You can detect whether the current page was loaded from ajax by checking the value of $config->ajax from your template file:
<?php
if($config->ajax) {
// page was requested from ajax
}
Following that, you will likely want to render the page differently to accommodate whatever you are doing from the javascript side. For instance, you might want do one of these:
1. Deliver alternate or reduced markup when loaded from ajax
2. Deliver a JSON or XML string for parsing from javascript
Below are examples of each of these scenarios.
1. Deliver alternate or reduced markup when loaded from ajax
You might find checking for ajax helpful when you want portions of pages to load in your site without re-rendering the entire page for each request. As a simple example, we'll use the default ProcessWire site and make it repopulate it's #bodycopy area when you click a page in the top navigation. (To use this example, you'll need the default ProcessWire site templates, though you can easily adapt the example to another situation.)
To accomplish this, we'll update our main page template to only include the header and footer markup if the page is NOT being loaded from ajax:
/site/templates/page.php
<?php
if(!$config->ajax) include("./head.inc");
echo $page->body;
if(!$config->ajax) include("./foot.inc");
Next we'll update the top navigation to do ajax loads of the pages when the client has javascript (and leave as-is when they don't). Paste this javascript snippet before the closing </head> tag in the header markup file:
/site/templates/head.inc:
<script type="text/javascript">
$(document).ready(function() {
$("#topnav a").click(function() {
$("#topnav a.on").removeClass('on'); // unhighlight selected nav item...
$(this).addClass('on'); // ...and highlight new nav item
$("#bodycopy").html("<p>Loading...</p>");
$.get($(this).attr('href'), function(data) {
$("#bodycopy").html(data);
});
return false;
});
});
</script>
Now when you click on any page in the top navigation, it pops into the bodycopy area without a page load visible from your browser. And all pages remain accessible from their URL as well. Note that this is just a test scenario, and I probably wouldn't use this approach for the entire bodycopy area on a production site (it would make bookmarking difficult). But this approach can be very useful in the right places.
2. Deliver a JSON or XML string for parsing from javascript
Lets say that you want pages in your site to return a JSON string with the page's id, title, and number of children when it is requested from ajax. When not requested from ajax, they will return their content as normal.
To handle the ajax requests, you'd want to add something like this at the top of your template file before any other output.
<?php
if($config->ajax) {
// this is an ajax request, return basic page information in a JSON string
$json = array(
'id' => $page->id,
'title' => $page->title,
'numChildren' => $page->numChildren
);
echo json_encode($json);
return;
}
// not ajax, continue with regular page output
And here is some markup and inline javascript you might use to test the ajax call on some other page (or the same one if you prefer). You would paste this snippet right in your site's markup where you want that info to appear.
<ul id='info'></ul>
<script type='text/javascript'>
var url = '/'; // this is homepage, so replace '/' with page URL you want to load JSON from
$(document).ready(function() {
$.getJSON(url, function(data) {
$.each(data, function(key, value) {
$("#info").append("<li>" + key + ": " + value + "</li>");
});
});
});
</script>
The above snippet would output something like this:
• id: 1
• title: Home
• numChildren: 5
To take this example further, you could build an ajax-driven sitemap or any number of web services.
Conclusion
Hope this helps you to see how simple it is to use ProcessWire to deliver output for ajax. These are just contrived examples, but hopefully examples that might lead to more ideas. In addition, much of what you see in these examples is also applicable to building web services in ProcessWire.