views:

20

answers:

1

Question... I want to build a one page web app that has deep linking (the url changes on click to where the user is loading) so the user can share links, bookmark, etc...

The issue with the jQuery BBQ plugin is that it requires the href to have a hash in it like href="#/photos/1"

That means I need to make sure every URL in my app starts with a hash. Also, it means non-JS browsers won't work since the URLs are all hashed.

Is there an elegant way to accomplish a one page web app with deep linking that works seamlessly for JS & Non-JS browsers, and requires less code changes?

thanks

+1  A: 

If you want to use a single URL structure that could work for both JS and non-JS capable/enabled browsers, you can check if the browser supports JS and change the navigation links accordingly. If the browser does support/has enabled JS, add a hash and retrieving the page using window.location.hash. Example URL:

site.com/#photos/1

If it doesn't support JS your URL would look like:

site.com/photos/1

This way you only need to add a # to the URL. That's easily to do, either in the script itself, or change the links on the page using jQuery after the page has been loaded. You can use (assuming Apache/PHP) Apache's ModRewrite to rewrite the URL to something like:

site.com/index.php?p=photos&show=1

Say the site loads for the first time and the browser does not support JS, load whatever should be loaded the normal way, depending on (in this case) the "page" and "show" variables. If it does support JS, you could store the variables like this:

<div style="display:none;" id="page">photos</div>
<div style="display:none;" id="show">1</div>
<div id="content"></div>

and after the page is loaded you fire up jQuery and extract the navigation data:

var page = $('#page').html();
var show = $('#show').html();

and do whatever needs to be done to show the correct page.

When you click new links you can use the various jQuery plugins for the hash navigation, or the page will simply load in the normal way when there's no JS and thus no hash in the links.

To prevent code duplication you need to setup your pages in such a way that they can be easily displayed the normal way and via jQuery. Say you have this photos page, you could include a "photos.php" when browsing without JS and use the same file using jQuery:

$.get(page + '.php', {
  show: show
}, function(data) {
  $('#content').html(data);
});

Since the "photos.php" will see the exact same $_GET variables, the output will be the same.

You will get some overlap though. If you want to display/post a form e.g. you'll probably handle that differently the normal way opposed to when you handle this via jQuery. The normal way you'd process the form data, and display an updated page. So in the case of "photos.php" you'll want to full output. But when using jQuery you only want a result that e.g. says "done" and change the page without reloading it entirely. This can be solved by adding a few more variables to the $.get (or $.post) functions.

You might want to look into (PHP) MVC frameworks. When using an MVC setup you can separate all the site's logic (navigation/database queries/etc) from the view (i.e. what is displayed on the site). It makes it really easy to use the same logic, but separate views for, in this case, a site with normal and one with jQuery-based navigation.

In the end you must ask yourself if it's worth going through all this trouble though. Whom's the site for? Do these people really use browsers without JavaScript? Is it really necessary to have a site available that doesn't rely on JS? Nowadays mostly everyone is using a browser that can handle JS just fine, and the time that people would disable it for 'security reasons' is long gone. Maintaining both versions of a site might take up a lot of time and resources (depending on the size of course), so it might just not be worth it. In that case it's easier to simply display a message or a stripped down and simplified site stating that the user should step into the 21st century to use the fully functional site.

Alec