Route For HTML/OS
Two Simple Illustrations
Consider these two URL's
- http://example.com/blog
- http://example.com/cgi-bin/htmlos.cgi/001149.3.317303135718820096/blog
Consider this telephone conversation between Tom and Bill.
Tom: Hey Bob do you remember that cool blaster watergun we were looking at the other day on the internet?
Bill: Yes, I do. It was pretty cool. Wait! I have it here. I am so glad I remembered to bookmark it.
Tom: Cool, can you give it to me?
Bill: http://waterblasters.com/cgi-bin/htmlos.cgi/001149.3.317303135718820096?id=543
Tom: Was that slash cgi slash oh oh one one or was it zero zero one one?
Introducing Route
These two albeit contrived examples illustrate that it is desirable to have URL's that are easy to remember and easy to bookmark, oh and also search engine friendly.
Route provides HTML/OS powered websites a framework to keep URL's simple. This is oftentimes reffered to as a Model View Contoller or MVC.
This article will cover the following topics
- Introduction to Route
- Installing Route
- Understanding routes
- Programming routes
- Additional Considerations
- Under the hood
- Hash Tag Navigation
Note: Throughout this article we may use a capital R and other times a lowercase r when using the word route. Route with a capital R means the framework Route. And route with a lowercase r means a particular URL (or route) that the framework Route handles. So just remember Route handles routes.
Installation
Route is available as an Aestiva .bb file and can be downloaded here...
System Requirements
Route utilizes the .htaccess file (for Apache) or web.config file (for IIS).
To use Route your server must read .htaccess (Apache) or web.config (IIS) files. The Route setup program will attempt to determine if .htaccess files are being parsed by your server. If they are not you will not be able to use Route.
Note: Route for IIS (Windows) requires the URL Rewrite Module. Information Found here.
Installing route.bb
To install route use the Aestiva application installer.
- From the Aestiva Desktop go to the Control Panel.
- Click the Install Product Icon.
- Type the path to the route.bb file in number 3, Transfer from Web Location
http://clearimageonline.com/home/route.bb
Route setup
Once it is installed you can run the Route setup by clicking the Route icon on the Main Menu.
The Route setup will modify the .htaccess (Apache) and (web.config) file found at the public root level of your HTML/OS installation. The setup program will make a backup automatically before overwriting it. Look for the backup in /apps/route/setup/back. The backup file will have a date/time stamp in its name.
Note: If you have trouble with your Route installation, you should be able to remove the .htaccess and/or web.config file from the root of your public folder. For detailed information about exactly what Route setup does, inspect /apps/route/setup/routesetup.log
Understanding routes
Flowchart
3 kinds of URL's
There are 3 kinds of URL's that we can have when using Route.
- File path URL's
<img src="/apps/myapp/images/logo.jpg">
These URL's are never handled by HTML/OS or Route they are handled by the web server (i.e. Apache, IIS) - cgi-bin Application URL's such as...
- Start links. Start links create a new session.
http://example.com/cgi-bin/start.cgi/index.html
- getlink() and HTML/OS generated
http://example.com/cgi-bin/htmlos.cgi/001063.3.2061320743573834126
- Start links. Start links create a new session.
- And new with Route we have routes like...
http://example.com/blog/view/25
Note: Having Route installed will not affect (unless the site relies on .htaccess or web.config files) an existing HTML/OS site. Existing HTML/OS sites will use cgi-bin style URL's and Route never sees these. This means you can install it with the confidence that everything will continue to work as normal. Then you can slowly add routes.
Programming routes
Handling routes
/apps/route/index.html
With Route installed you can edit /apps/route/index.html to program how your route URL's will be handled.
This program decides where each route should go. Use a goto to decide what program will handle any particular route. The following example uses a nested if then statement but you can use any control structures. For example a case statement would be suited very well for this.
if tag_[1]='blog' then
if tag\_[2]='' then
goto '/apps/blog/index.html'
else
if tag\_[2]='list'
blogcategory=tag\_[3] # <== Notice we use tag\_[3] to set a variable called blogcategory /#
goto '/apps/blog/list.html'
elif tag\_[2]='view' then
blogpage=tag\_[3]
goto '/apps/blog/view.html'
elif tag\_[2]='play' then
blogpage=tag\_[3]
goto '/apps/blog/play.html'
else
goto error(404)
/if
/if
The following variables can be used to determine where each route will go.
http://example.com/blog/view/521?var=y&var2=listmode
sysservicetype http
domainname example.com
tag /blog/view/521?var=y&var2=listmode
tag_path /blog/view/521
tag_vars var=y&var2=listmode
tag_[1] blog
tag_[2] view
tag_[3] 521
Coding routes into your pages
Coding a route is similar to the way getlink works. Add something like this to your HTML files.
<a href="<<route('/blog/view/day1')>>">My first Day of School</a>
--or--
<<
display <a href="^+route('/blog/view/day1')+^">My first Day of School</a> /display
>>
--or--
<a exithref="/blog/view/day1">My first Day of School</a>
The exithref approach does not consider if the end user isn't using cookies. the function route() takes this into account and will return a route that works even without cookies.
Coding routes into an overlay
Instead of goto page add something like this.
goto route('/blog/view/'+blogpage)
Additional Considerations
Search Engines
Search engines should be able to crawl a route site very quickly. Because Search engines do not accept cookies each visit to your site by a robot / search engine will generate a new session.
robots.txt
Here is a suggested robots.txt file. It will tell search engines not to crawl any URL that starts with /cgi-bin. This has the benefit that all your route URL's will be crawled but not the normal HTML/OS links.
User-agent: *
Disallow: /cgi-bin
409 Error
Route will return a 409 ERROR if both a file path and a route are attempted. Generally this means you have added a folder or file at the root of your public folder that was not there when you did your initial Route setup. Reinstalling Route will recreate your web.config and .htaccess file and the error will go away, but it may make more sense to remove the conflicting file or folder. Optionally you may want to manually modify your .htaccess file.
Session Restarts
Route handles expired sessions automatically. There may be times when you need to force a session to restart. To do this you can manually type the following URL to create a new session.
http://example.com/restart
Using controllers
Many use /apps/route/index.html for all their routes and are happy to keep them all there. However, at some point managing all of the routes necessary for a web site may become difficult to manage with a single file. This is where controllers may help save time.
Suppose you have an app defined at http://example.com/blog/.../... You can forward all requests where tag_[1]='blog' to another page that would then decide how to handle all the other tag_'s
blog would be called a controller and you would go to it at the end of /apps/route/index.html like this...
goto controller(tag_[1])
Then create a file at /apps/route/controllers/blog.overlay
In this file you can add specific code for the app /blog
Route comes with 3 controllers pre-installed home.overlay, http_error.overlay, and restart.overlay
Here is what they contain...
home.overlay
<<overlay restart
# You can break your controllers out to .overlay files like this one /#
goto '/apps/route/setup/working.html'
>>
http_error.overlay
<<overlay error
goto error(tag_[2])
>>
restart.overlay
<<overlay restart
temp=split(getlink('/apps/route/index.html'),'/')
temp=temp[1,rows(temp)]
ci\_cookiewrite('route\_controller',temp,adddays(now,-365))
goto '/apps/route/restart.html'
>>
Route Under The Hood
Apache .htaccess File
To use Route your server must read .htaccess files. The Route setup program will attempt to determine if .htaccess files are being parsed.
This is a sample of what the .htaccess file might look like. Not intended for actual usage. The Route installer will build a site specific .htaccess file for the HTML/OS installation.
#routehead ######################### # .htaccess is a part of the Clear Image Media Routing Package for HTML/OS # contact riegel@clearimageonline.com with any questions # # copyright (c) July 2011 # Update January 2016 # Contributors: Johan van Langevelde # # This .htaccess is autogenerated by /apps/route/setup/setup.html # use it to make modifications RewriteEngine on ######################### #/routehead #routebody ######################### # Custom Errors # ErrorDocument 404 /apps/route/errors/404_error.html ErrorDocument 403 /apps/route/errors/403_error.html ######################### # Test Rewrite Rules # RewriteRule ^apps/route/setup/test.txt$ /apps/route/setup/testROUTE.txt [L] RewriteCond /http/cache//00 -d RewriteRule ^apps/route/setup/exist.txt$ /apps/route/setup/pass.txt [L] ######################### # Hidden CGI-BIN # RewriteRule ^([0-9]+\.[0-9]+\.[0-9]+)(.*)$ /cgi-bin/htmlos/$1$2 [L] ######################### # Cookie found rewrite rule # RewriteCond %{REQUEST_URI} !^/cgi-bin [NC] RewriteCond %{REQUEST_URI} !^/IMG [NC] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # Instantaneous restarts not supported, possibly move HTML/OS cache folder outside of DOCUMENT_ROOT # RewriteCond %{HTTP_HOST}:%{HTTP_COOKIE} ^(.*?):.*\broute_\1=00([1-9]+) [NC] # RewriteCond /http/cache//00/%2.a -f RewriteCond %{HTTP_HOST} ^(.*)$ [NC] RewriteCond %1:%{HTTP_COOKIE} ^(.*?):.*\broute_\1=([^;]+) [NC] RewriteRule ^(.*)$ /cgi-bin/htmlos/%2 [L] ######################### # Cookie NOT found rewrite rule # RewriteCond %{REQUEST_URI} !^/cgi-bin [NC] RewriteCond %{REQUEST_URI} !^/IMG [NC] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ /cgi-bin/htmlos/apps/route/startlink.html [L] ######################### # Cookie Found Special Case for DirectoryIndex # RewriteCond %{REQUEST_FILENAME} -d # Instantaneous restarts not supported, possibly move HTML/OS cache folder outside of DOCUMENT_ROOT # RewriteCond %{HTTP_HOST}:%{HTTP_COOKIE} ^(.*?):.*\broute_\1=00([1-9]+) [NC] # RewriteCond /http/cache//00/%2.a -f RewriteCond %{HTTP_HOST} ^(.*)$ [NC] RewriteCond %1:%{HTTP_COOKIE} ^(.*?):.*\broute_\1=([^;]+) [NC] RewriteRule ^(.*)$ /cgi-bin/htmlos/%2 [L] ######################### # Cookie NOT Found Special Case for DirectoryIndex # RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^(.*)$ /cgi-bin/htmlos/apps/route/startlink.html [L] ######################### #/routebody #routeimages ########################### # START: IMG ########################### ######################### # BEGIN: # # Does the original Image Exist? # If yes does the Thumb Exist? # If NO then invoke script # RewriteCond %{REQUEST_URI} ^/IMG/(.*)/XPATH/(.*)$ RewriteCond /http/production_server/public/%2 -f RewriteCond %{REQUEST_URI} ^/IMG/(.*)/XPATH/(.*)/(.*) RewriteCond /http/production_server/public/%2/.TEMP/%1_XDELIMIT_%3 !-f RewriteRule ^(.*)$ /cgi-bin/htmlos/NOSESSION/apps/route/startlink.html [L] # # Does the original Image Exist? # If yes does the Thumb Exist? # If YES then deliver it # RewriteCond %{REQUEST_URI} ^/IMG/(.*)/XPATH/(.*)$ RewriteCond /http/production_server/public/%2 -f RewriteCond %{REQUEST_URI} ^/IMG/(.*)/XPATH/(.*)/(.*) RewriteCond /http/production_server/public/%2/.TEMP/%1_XDELIMIT_%3 -f RewriteRule ^IMG/(.*)/XPATH/(.*)/(.*)$ /$2/.TEMP/$1_XDELIMIT_$3 [L] # # END: ######################### ########################### # END: IMG ########################### #/routeimages
IIS web.config File
Route for IIS requires the URL Rewrite Module. Information Found here. To use Route your server must read and parse web.config files. The Route setup program will attempt to determine if web.config files are being parsed.
This is a sample of what the web.config file might look like. Not intended for actual usage. The Route installer will build a site specific web.config for the HTML/OS installation.
?xml version="1.0" encoding="UTF-8"?>
<!--
Route Comments
web.config is a part of the Clear Image Media Routing Package for HTML/OS
contact riegel@clearimageonline.com with any questions
copyright (c) July 2011
Update March 2012
This .htaccess is autogenerated by /apps/route/setup/setup.html
use it to make modifications
/Route Comments
-->
<configuration>
<system.webServer>
<httpErrors>
<remove statusCode="403" subStatusCode="-1" />
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="403" path="/apps/route/errors/403_error.html" responseMode="ExecuteURL" />
<error statusCode="404" path="/apps/route/errors/404_error.html" responseMode="ExecuteURL" />
</httpErrors>
<rewrite>
<rules>
<rule name="Test Rewrite Rules" stopProcessing="true">
<match url="^apps/route/setup/test.txt$" ignoreCase="false" />
<action type="Rewrite" url="/apps/route/setup/testROUTE.txt" />
</rule>
<rule name="Hidden CGI-BIN" stopProcessing="true">
<match url="^([0-9]+\.[0-9]+\.[0-9]+)(.*)$" ignoreCase="false" />
<action type="Rewrite" url="cgi-bin/htmlos.exe/{R:1}{R:2}" />
</rule>
<rule name="Cookie found rewrite rule">
<match url="^(.*)$" ignoreCase="false" />
<conditions logicalGrouping="MatchAll">
<add input="{URL}" pattern="^/cgi-bin" negate="true" />
<add input="{URL}" pattern="^/trash" negate="true" />
<add input="{URL}" pattern="^/apps" negate="true" />
<add input="{URL}" pattern="^/upload" negate="true" />
<add input="{URL}" pattern="^/system" negate="true" />
<add input="{HTTP_COOKIE}" pattern="route_controller=([^;]+)" />
</conditions>
<action type="Rewrite" url="/cgi-bin/htmlos.exe/{C:1}/_/{R:1}" />
</rule>
<rule name="Cookie NOT found rewrite rule">
<match url="^(.*)$" ignoreCase="false" />
<conditions logicalGrouping="MatchAll">
<add input="{URL}" pattern="^/cgi-bin" negate="true" />
<add input="{URL}" pattern="^/trash" negate="true" />
<add input="{URL}" pattern="^/apps" negate="true" />
<add input="{URL}" pattern="^/upload" negate="true" />
<add input="{URL}" pattern="^/system" negate="true" />
<add input="{HTTP_COOKIE}" pattern="^.*route_controller.*$" negate="true" />
</conditions>
<action type="Rewrite" url="/cgi-bin/htmlos.exe/apps/route/startlink.html?_/{R:1}" appendQueryString="true" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Route and AJAX Hash Tag Navigation
Looks like there is a better way Using Push State.
Google has specified a way for AJAX applications to make their pages available to search engines. A popular technique for AJAX based aplications if to use the hash tag for navigation. This has the benefit of allowing javascript to handle all navigation and the state of the application can be stored in the URL for bookmarking.
The previous example has been modified for hash tag navigation
<a href="<<route('/blog')>>#!/view/day1">My first Day of School</a>
or
<<
display <a href="^+route('/blog')+^#!/view/day1">My first Day of School</a> /display
>>
or
<a exithref="/blog#!/view/day1">My first Day of School</a>
So the resulting URL would look like this...
http://example.com/blog#!/view/day1
The problem arises in the way hash tags are sent to the server or more acurately not sent to the server. The hash and everything following it is never sent to the server. So a search engine can pick up the URL by crawling a page but they can't "crawl" that url.
To get around this google has proposed to rewrite any hash tag navigation that begins with #! and replace it with ?escapedfragment_=
So a link like...
http://example.com/blog#!/view/day1
would be crawled as...
http://example.com/blog?_escaped_fragment_=/view/day1
This is how route handles a request from a search engine that has hash tag navigation.
Actual URL http://example.com/blog#!/view/521?var=y&var2=listmode
Request sent http://example.com/blog?_escaped_fragment_=/view/521?var=y&var2=listmode
How Route populates the variables...
sysservicetype http
domainname example.com
tag /blog#!/view/521?var=y&var2=listmode
tag_path /blog#!/view/521
tag_vars var=y&var2=listmode
tag_[1] blog#!
tag_[2] view
tag_[3] 521
To learn more about how google and other handle hash tag navigation see their documentation.