It is often the case a website's pages are made up of standard content, such as a site logo, navigation, breadcrumb, footer, etc, and then the content that is specific to the page itself. I shall refer to these as "template" and "content" from now on. These are concepts only, they have no concrete representation below.
The content makes up the meat of the resource and will be unique for each page.
The template, in contrast, will change a little from page to page. For example, the highlighted item in the navigation menu will change, as will the contents of the breadcrumb, but most parts of the template will remain static.
The following proposal explores the possible ways of using XML-HTTP-Requests natively to allow users to navigate between site resources without having to download the entire page every time.
The term native implies that the browser would be able to navigate the site in this way without the aid of Javascript.
Here is a simple example:
<head>
<routes>
<!-- Any element implementing this route will update
its contents with the resource at dst if the user
navigates to src through an href -->
<route src="/articles/:id" dst="/_partials/articles/:id" />
</routes>
</head>
<body>
<!-- User navigates to a URL through an anchor -->
<a href="/articles/foo">Foo</a>
<a href="/articles/bar">Bar</a>
<!-- Any elements resolving that url get updated with
the contents of a mapped partial if it exists. -->
<div class="content" route="/articles/:id"></div>
</body>
Notice that the styling of the navigation is unaffected by the routing. Implementing something like this would be a bad idea:
<a class="active" href="/articles/foo">Foo</a>
<a href="/articles/bar">Bar</a>
The menu item for "Foo" would remain highlighted regardless of what page we were actually on.
To get around this we could progressively enhance with Javascript, but the default user experience would still be poor.
To work without Javascript, we could implement a pseudo-selector for anchor tags to match any tag whose href matches the current URL.
a:current-location {
color: darkblue;
}
An alternative approach is to have a separate resource for navigation that also matches the route. This might be useful if the CSS alone isn't enough. For this we need to add the ability to have one route mapping to many resources, which we achieve with named routes.
<routes>
<!-- This example uses a named route so that one src
can resolve to multiple destinations. The bound element
decides which to use. -->
<route name="route1" src="/articles/:id" dst="/_partials/articles/:id" />
<route name="route2" src="/articles/:id" dst="/_partials/articles/:id/nav" />
</routes>
Now we can assign a route to an element by its name, rather than its source.
This time the entire contents of <nav>
will be replaced.
<nav route="route2">
<a class="active" href="/articles/foo">Foo</a>
<a href="/articles/bar">Bar</a>
</nav>
<div class="content" route="route1"></div>
If we carried on and added more routes, we might find that we want to refactor
the route definition a little bit. Some data could be refactored to the
<routes>
tag.
<routes>
<route name="article.body" src="/articles/:id" dst="/_partials/articles/:id/content" />
<route name="article.summary" src="/articles/:id" dst="/_partials/articles/:id/summary" />
<route name="article.title" src="/articles/:id" dst="/_partials/articles/:id/title" />
</routes>
<!-- with simple concatenation rules, could become -->
<routes name="article." src="/articles/:id" dst="/_partials/articles/:id/">
<route name="body" dst="content" />
<route name="summary" dst="summary" />
<route name="title" dst="title" />
</routes>
At this point we have the beginings of a templating engine. Indeed, with more partials we can template more and more of the page. Taken to its logical extreme you could replace large parts of an MVC framework with this, although this isn't something I'm advocating at this point.