Grow your CSS skills. Land your dream job.

#81: AJAXing a WordPress Theme

Watch me bumble my way through adding AJAX functionality to a WordPress theme. The idea is that any internal link on the site will load into the main content area without requiring a page refresh, including search. Not always the most practical idea in the world, but it's kinda neat, and as I show in the video, I did find a nice real-world problem that it solved.

Links from Video:

The JavaScript is in the process of being updated to be better. See this code for where it is headed.

Comments

  1. Permalink to comment#

    Looks like another great tutorial!!!

    One of the main reasons why I love this blog more than others is simply coz… You come up with new stuff every now and then..

  2. Hoteldebotel
    Permalink to comment#

    Nice one! Keep it going!

  3. Permalink to comment#

    Any Idea on how to make the back button work too? That is the biggest hangup with using AJAX to load the pages for me.

    • Yep that’s an issue for sure. One way is the history plugin:

      http://plugins.jquery.com/project/history

      Which I’ve never had a ton of luck using. I’ve also heard of homegrown techniques for monitoring the URL every few seconds for hashtag changes and acting when it sees a change.

      Another issue, which I forgot if I mentioned in the podcast, is SEO. If you have a bunch of incoming links for something like http://www.yoursite.com/#/cupcakes – That page might load the cupcakes content just fine but Google bots will go to that page and see the homepage content not the cupcakes content (as far as I know).

    • Permalink to comment#

      Cool – Thanks for the tips – I will take a look at the History plugin.

    • Nowadays history and everything is much simpler with HTML5 pushState():
      You can let it change the current URL (only within your domain, for security reasons) and write into history. There are also methods for registering history navigation.

      So it’s easy to provide fallbacks for non-js-browser, IE, search engines and so on because they just use the normal URL and load the complete website forom the server instead of ajaxing…

      I used this on the new pre-alpha-version of my website (it’s in German but can still show the demonstrate things)…

  4. But will this work with different themes on different pages?

    • Yes. WordPress makes such an elegant way to separate style provider and content provider, thus you can have this working with most (if not all) themes as you can see in the podcast that most of the time he was using the output of the pages to see which elements to work with (sorry I was just glancing through, maybe it’s ALL the time).

  5. jQuery.load() is such a pleasure to use, as you most beautifully demonstrated.

    The only thing I’d say is that the selector you use isn’t that robust. Your better off using this one (found on CSS-Tricks):

    a:not([href^="http://www.mysite.com"]):not([href^="#"]):not([href^="/"])

  6. Permalink to comment#

    Overall very cool. but what concerns me, besides back button problems and SEO is that this technique (the hash tag) really does not support progressive enhancement. call me backwards, but i still believe that its good thinking to support clients without js. one way I can think off to solve that would be to include the # – tag on every page load, no matter if ajaxed or not.

    one other thing is the asthetics: I cant help, but find the # – tag incredibly ugly. The whole thing can very useful, but the looks not so nice ^-^ so even a rather progressive enhanced way does still look not sooo great to my eyes ^-^

    • Actually it is fairly “progressive enhancement” style. Early in the screencast I showed what happens when JavaScript is completely removed from it the theme, it just falls back to regular links and regular page refreshes.

      Although I agree the hash tag thing isn’t the most beautiful thing to look at.

    • Permalink to comment#

      sure thing, i know what you mean ^-^ what i am concert about is, if you send a link with hash tag to some one who can’t or does not want to use js, you end up on the front page, ergo deep linking does not work as intended. otherwise i fully agree: its progressive enhanced. ^-^
      the only possible solution i can think of, accept getting rid of the hashtag all together, would be to include it into the link structure. but that again might cause new problems… wish i would know more about js.
      but i very much like the concept. so thanx a lot for sharing!

    • sotiris
      Permalink to comment#

      i totally agree with you for the “look at #” part…!
      but how many users are there with javascript turned off? If you see any latest stats, about 99,5 of users, are “enabled”. So, why bother about this?

      By the way, great tut!

    • well, i am also thinking about mobile users. its not only iphones out there, and me living in japan, i see 80% use mobiles that don’t support js. so if one sends a link from, say, a mac to a mobile, which would at least allow the content to be readable, the receiver would not be able catch the link. thats kinda not really the way to go, and that keeps me from seeing this as progressive enhancment… i believe that 100% of possible users should be able to use a site! in all directions. ^-^

    • Permalink to comment#

      You live in japan.. way to go dude :P

  7. Great tutorial!

    Keep it up

    Cheers,

    Cory

  8. I have been looking everywhere for this, needed for a client awesome

    thanks

  9. Great stuff again chris

  10. Very nice article about ajax implemention.

  11. Great screencast, very useful info. A year back or so i smashed my brains out with a wordpress theme that needed ajax.

    And one more thing, i never got the chance to say this but you’ve got one of the best voices i’ve ever heard in screencasts or even podcasts.

    That hiccup was funny tho! :D

  12. John Doesky
    Permalink to comment#

    Dude Awesome, I have been waiting for this tutorial… You Rock! Maybe you will possible do a follow up adding custom animation with the easing? That would be super sick! Thanks again and great work…

  13. Permalink to comment#

    Great screencast Chris!
    Really enjoy your delivery.

    Keep up the good work man

  14. Jack Reichert
    Permalink to comment#

    Thanks for this great tutorial!

    It’s perfect timing, I was planning on using this weekend to research how to do just this. Totally awesome.

    About “reasons why” to do this, you didn’t mention what I think is the most important reason, which is,

    …it’s WICKED cool looking!

  15. Zach
    Permalink to comment#

    Great screencast! I learned a lot. One suggestion for the hash functionality on page load. All of the code within the if(hash) statement is a little redundant. Wouldn’t this work?

    if (hash) {
    $('a[href^=' + hash + ').click();
    }

    This way you keep all of your ajax scripting in the same place in case you ever wanna change it. Just a thought…

  16. burkhard
    Permalink to comment#

    how funny. the real life example reminded me of a podcast directory site i created some time ago. i did in fact use an iframe to display the content description where you could click a podcast to add it to the playlist of an instance of jw’s nice flash media player sitting on the framing page. as much as i hate frames, i really thought that an iframe was the most elegant solution then.

    i’m sure i’d do it with load() and the cookie plugin (for some playlist magic and hiding content already listened to) today. but back then, my skills and the technology were, umm, different.

    great podcast again, chris. thank you. and congratulations for the book being sold out. enjoy the feeling before you rush to sell the next edition! ;-)

    - burkhard

    (note to self: why not revive the site after all?…)

  17. burkhard
    Permalink to comment#

    …and note to chris:

    i wouldnt have to restart the screencast after writing my comment if there was an ajax comment form… ;-)

    - b.

    • Permalink to comment#

      I just had the same thing. An AJAX comments form wouldn’t be too hard, right?

  18. John
    Permalink to comment#

    Thanks for another great screencast Chris, I remember you saying the screencasts get the least attention/hits on the site overall? (I could be imagining reading that). Can’t understand why, I love them.

  19. Permalink to comment#

    It’s good for comments,pools or widgets.
    for an site I don’t know?!

    It’s become kind a like light box this days.

  20. Dhaval Jani
    Permalink to comment#

    Why do this?

    This is crazy good thing for band website where you could add a player in header and the song doesn’t refresh when you go to another page!

    I had been looking for something like this last year and found some wp ajax theme but din’t really work out… This looks really fit for that functionality!

    Chris, Thanks again.

    Dhaval

  21. Permalink to comment#

    I like the Lines and Boxes. Minimalism is sexy! Unless it starts to feel plain. But the ajax loader guarantees that it always feels cutting edge so it remains sexy :)

    Very nice.

    I can’t deal with the pound sign though. It just feels wrong and looks bad. I would love to see a solution that doesn’t involve changing the url like that. Plus the back button is a pretty big deal.

    One other thing though. No one has mentioned ads or other content designed to change at every page load. Since the page is no longer loading, each piece of content that needs to change (adsense blocks, etc) needs to be addressed individually in the js code. That does away with the whole plug and play idea. Unless I’m missing a workaround for that.

    Awesome concept though! I’ve never played with ajax before but I definately will start now. Thanks for the podcast.

  22. Liam
    Permalink to comment#

    I’m interested in how the “theme playground” works

  23. Eddy
    Permalink to comment#

    Hi Chris, the downloadable version is still really washed-out while the online version looks fine. There must be some setting for when you save the file or something.

  24. Dim
    Permalink to comment#

    That wasn’t one of your best performance, you should prepare better.

  25. I never have issues with my Drobo on my Windows 7 box ;) Thanks for another great videocast Chris!

  26. Very nice article. Thnx for sharing.

  27. Hey Chris since u put the CSS Screencast Podcast in iTunes I preffer see from there, and come here to comment some times. But this screencast in the iPhone Podcast Version is wrong, when I try play this the actualy that are played is the number 74, even I may never see this screencast once I had saw a couple times, may be good fix the link.

    Ah and when u think we can have the CSS off results?

  28. sotiris
    Permalink to comment#

    Great example for sure!
    i have one question though. What about multiple containers? Lets say you have some banners you want to load every time a user lands on the page. Will this work with different div and content?
    SEO is one main issue also.

    Sotiris

  29. okami
    Permalink to comment#

    I’ve been trying to impliment this script, and am running into problems with a blog installed in a sub-directory. While the actual loading works correctly when clicking a link, the resulting url has the subdirectory name twice (ie, if the blog is http://example.com/blog/, the modifed url ends up looking like http://example.com/blog/#/blog/page/)

    And while clicking links loads things properly, the modified urls don’t, so the deep linking isn’t an option.

    I tried just adding a substring to the this.pathname to cut off the sub-directory name, but while that makes the url look right, clicking the links no longer work.

    Finally, any easy ways to make the back button work with this? Or would that have to be a separate process altogether?

    Any help you offer would be greatly appreciated.
    Thanks

  30. Permalink to comment#

    Thank you Chris, I am going to try this for SURE.

    One thing though .. where or how can I get that cool music player ?

    Thanks, you are the BEST.

  31. Hey Chris, man this is amaizing, like i have been searching everywhere about a script like this when i suddenly come to your site and see it i was like Thank You God! But i have a problem thought with installing it. See i have my blog in here http://www.fantazoj.com/blog (im a design fan myself) and i created a new .js with that code that you posted in here, on the top. So i take the code and place it on my FTP themename/js/ajax.js and when i go to my site i mentioned earlier it doesn’t load like its suppose to, like you know, on the video or that mp3 site. I too want to put some music on the background without ever stopping it. Can you please help me dude, do i need to place the name ajax.js in some other template or something, because i’m not much of a coder.
    Appreciate it Chris.
    Thank you for the great tutorial.

  32. Bryan Warman
    Permalink to comment#

    Thanks Chris! Great tutorial.

    One thing I did notice is that Time Machine was backing up during the screencast and is probably causing a lot of your slow downs. Time Machine accesses your hard-drives and bogs them down. You might take a look at it next time things start slowing down for you.

  33. that’s a really cool screencast.
    I’m trying to do the same in a joomla template.
    does someone have any suggestion or link?

  34. hello,
    great tutorial, is it true that search engines have trouble with this script?

  35. ian
    Permalink to comment#

    Hi,
    I finaly managed to make it work. For some reason it didn’t like my permalinks structure.
    One question though. Is there any way to exclude an internal link so it doesn’t get the # tag. There doesn’t seem to be a neat way to log in because it’ll link to http://www.siteName.com/#/wp-admin/index.php.

  36. Rob
    Permalink to comment#

    Hi Chris

    Just a question – I am loading a page with a jquery image gallery. The links to load the previous and next images are using an href with the hash sign <a href=”#” rel=”nofollow”> so now the images wont load – is there a way to exclude certain links that use the hash sign?

    Thx

    Rob

  37. The all ajax theme would be amazing if:

    -1 Supported lightbox/nextgen overlays
    -Used wordpress custom menu (honestly a bit surprising that wasn’t in there)
    -Ajax everything (comments included!)
    -Better CSS layout for customization (such as full screen or full width pages, easier to manage css for backgrounds, color changes, fonts).
    -Built in support for custom page options

    Being that anyone who has the all ajax theme had to pay for it – or their a thief, its really not so much to ask to see these things included. There are several themes on themeforest.net that have blog posts in ajaxed pages with overlays, but usually lack functionality elsewhere in the theme. I would probably pay more than I already have if this could added.

  38. Thanks for yet another great tutorial Chris.

    I am a relative newbie to all this but I would like to take these principles here and use on a live job but the client wants a new full background image to load/change as well as the content. Is this possible and if so, some advice would be sooooo appreciated. I have nothing built yet but I was thinking of using tag background attribute for this.

    Just brought the print version of Digging into WordPress ….v. excited!

    thank you for any advice !

  39. oops. I just read posting tips.

    Last line of main paragraph in previous post should read

    “I have nothing built yet but I was thinking of using the < body < tag background attribute for this.

    :)

  40. the background image would be full screen but the content area would be in a smaller containing area as you have in this tutorial.

  41. Scott Rod
    Permalink to comment#

    Chris, I realize it’s been awhile since you created this podcast / theme. It would be neat if you revisited this concept. Perhaps something similar to this site: http://www.makr.com/, where clicking a thumbnail would load in the post’s contentt along with a larger thumbnail.
    Of course, I haven’t thoroughly thought it through. Considering, an average desktop display height and a lengthy article, it may not be practical. But, for some kind of gallery site with few details about each piece, it may be pretty useful.

  42. Any reason why upgrading to wordpress3.2.1 would kill the ajax theme? It works fine on an older version but as soon as i upgrade wordpress which also upgrades the database, no more ajax loading.

  43. Kalpesh Mistry
    Permalink to comment#

    It’s all just like I wanted. I need assist on this one and only query of mine. I cannot use many jQuery based scripts like tabs, lightbox, etc that are basically used inside the mainContent. allajas is getting conflicted with almost every other jQuery based scripts. I’m not a web developer, just a user with basic HTML/CSS knowledge, and so I badly need help on this.

  44. MadsRH
    Permalink to comment#

    I’m sorry for being a total newbie, but I’m missing some information about where this code is written. And if it’s an external .js file, how to include it.

  45. Permalink to comment#

    Hello,

    I’m interesting in trying this out, I manage to get jquery loaded. But I’m a noob and don’t know where to put the downloadable code.

    Please help.

  46. Permalink to comment#

    Hey guys, and chris thank you for making such a great tutorial.

    I was wondering if is it possible to include a title aswell, i tried

    $.address.change(function(event) {
    if (event.value) {
    $ajaxSpinner.fadeIn();
    $mainContent
    .empty()
    .load(base + event.value + ‘ #content’, function() {
    $ajaxSpinner.fadeOut();
    $mainContent.fadeIn();
    $.address.title($.address.title().split(‘ | ‘)[0] + ‘ | ‘ + current.text());
    });
    }
    which doesn’t seem to work since my jquery/ajax experience is totally n00bish /=
    i will appreciate any help and also I’m sure it will be big improvement to this tutorial adding title tag to each a.anchors

  47. Andrey
    Permalink to comment#

    I see one problem with updated all ajax theme. Main content is actually loading 2 times (2 GET requests) after loading main page. What is the way to avoid that? If we change ‘if (event.value)’ to if ‘(event.value!=”/”)’ condition in address change event then back button to the main page stopped working, AFAICS. How it can be avoided?

  48. Permalink to comment#

    I’m also kind of curious how to update the page title automatically.

    Is this easy to implement?

  49. Permalink to comment#

    Found one more issue that should be fixed:

    As I see in $(‘#searchform’).submit event $.address.value(query) should be changed to $.address.value(encodeURI(query)) to proper handle whitespaces and other special characters.

  50. Jeffrey
    Permalink to comment#

    Hello everyone,

    Does someone know how I could load the content from not only the #inside div, but from another div as well? This would mean that I could load content from two divs, instead of one.

    Hoping for help.

  51. Permalink to comment#

    Excellent!!!
    but some things are missing, for example when you click an (internal) link, the page does not return to the top. I think it will be useful scrollTop jQuery function:

    //return on top after click 
    $('#selector1, .selector2, .selector3').live('click', function(e) {
     $(window).scrollTop(0);
     e.preventDefault();
    });

    in my real case:

    //return on top after click 
    $('a[rel="bookmark"], a[target="_self"], a[rel="archives"], .category a, .continue a, .alignleft a, .alignright a, a.page-numbers').live('click', function(e) {
     $(window).scrollTop(0);
     e.preventDefault();
    });

    I hope it is useful, Ciao! :)

  52. Graham
    Permalink to comment#

    Great vid,
    I was trying to use this code on a site, but I was having problems with nextGen plugin where it would get stuck on the nextGen loader screen. Anybody encounter any similar problems?

    • Permalink to comment#

      I do not use this plugin, but give me the address of your site, think it should not be difficult.

  53. Jeffrey
    Permalink to comment#

    How can we add a 404 page for when a page doesn’t exists? Hoping for help!

  54. Permalink to comment#

    is true, the page 404 is ignored by loading with ajax O_O….. I think of a solution …..

    • Permalink to comment#

      This is a problem with permalinks, I have partially solved by removing the function empty() and adding a $mainContent.fadeOut(); before loading., so not returns a blank or empty page (sorry for my english :)

      $ajaxSpinner.fadeIn();
      $mainContent.empty().load(base + event.value + ' #inside', function() {
      $ajaxSpinner.fadeOut();
      $mainContent.fadeIn();
       

      $ajaxSpinner.fadeIn();
      $mainContent.fadeOut();
      $mainContent.load(base + event.value + ' #inside', function() {
      $ajaxSpinner.fadeOut();
      $mainContent.fadeIn();
       

  55. Jeffrey
    Permalink to comment#

    Something else is forgotten as well. When the user pushes the browser “back” button, the menu doesn’t get refreshed.

    Example:
    You’re on the Contact page, you click the “Back” button, Contact link in the menu keeps “active” class, while your on the homepage.

    Does anyone know how we could deal with that?

  56. Hello Chris. This work looks excellent but I just cant made ir work.

    I try to setup AJAX only in a portion of my client site. The objective is to load all articles (posts) in the same page they are listed… but only the articles (posts) and not the other pages of the site should load.

    I can’t figured out how to target only this articles/post links to load inside my #inside” div.

  57. wow….. what a great tutorials. I am a big fan of WordPress and it helps me to learn more about creating nice template.

  58. Jaffe
    Permalink to comment#

    I am randomly getting $el as undefined. it was working and now isn’t working. I am a little confused as to why in the variable section we define say URL = “” but we define $el as just $el. Is there a reason it is not $el = “” ? thanks for the response to help me better understand $el and it’s error of not being defined.

  59. Tara

    Hey anyone got an idea of how to get this working within a single post using the prev / next post links?

    I have it working but the new posts url adds onto the previous url like so: http://mysite.com/post-1/#/hello-world/

  60. Is it possible to do this without # in the url?. I am curious to implement this in my blog, if it can be done.

  61. Permalink to comment#

    First time poster long time voyeur.. You have a most excellent site!!!

    I was just wondering about the SEO side of things… I was just having a look at google on ajax-crawling
    and it says it will crawl AJAX content that is set up like this: #!key=value
    Do you reckon it would solve the problem if the jQuery was set up as follows?

    var current = location.protocol + ‘//’ + location.hostname + location.pathname;
    if (base + ‘/’ != current) {
    var diff = current.replace(base, ”);
    location = base + ‘/#!’ + diff;
    }

    Cheers

    G

  62. Awesome. I came across your screencast because I was looking for a solution to a problem identical to the Boulder Acoustic Society’s. Now I’ll be using this technique to make sure that my client can have a consistent music player as the user browses their site. Thanks!

  63. Permalink to comment#

    Great Stuff Bro

  64. Permalink to comment#

    Thanks for the great Stuff. But i think too, that to much of Ajax on a page is not good. When a user is on the Page A and click on Link B… and then he want back to page A with the Browser back function, so the Sidebar is also standing still on Page B. When you now have a bigger Menue Tree, your User get a problem ;).
    Also is my question: What is with Seo and Ajax?
    So i think take Ajax for cool great little things(like Slider or the next 5 Post in Sidebar for load on click) and not for all the Page.

  65. Permalink to comment#

    Could it be that “Boulder Acoustic Society” doesn’t use this method anymore?
    furthermore I don’t seem to get this one working. (at least not on the basic HTML5 blank theme (i guess from smashing magazine?)
    I checked out “http://www.deluxeblogtips.com/2010/05/how-to-ajaxify-wordpress-theme.html” for this as well, but I get the same result there. I can see ajax trying to fetch something, but it loads a blank page (while having the url + hashtag linking to the post in the browser menu). As usual it’s probably something easy I am forgetting to check here…

    • Permalink to comment#

      Minor update, I have installed the plugin “Advanced Ajax Page Loader 2.6.4″ and this seems to be working fine with my current setup (besides some tweaking still). If I find the courage to dive into some of that code, I might find a solution on the “why” this didn’t work. Either way, thanks for this nice tutorial, did explain a whole lot of the ins and outs of ajax, specifically for this.

    • Permalink to comment#

      Final update, I tried something else, loosely based on something I found here: “http://wptheming.com/2011/12/ajax-themes/” . Even though I do not fully understand everything I have implemented here (very new at ajax ;) ), this was the solution I was looking for (…worked for me). The plugin I was previously talking about was making it hard for me at certain stages in the developing process so I left that for what it was and started coding/interpreting/copying from this new link I found.

      I must admit, after some hours of struggling, it feels great getting this to work, now I can re-organize some divs/sections/navs n start the actual design implementation.
      When the project is finished I’ll try to remember posting a link to the result here.

  66. I bet none of the above choice satisfies the need of SEO, especailly when it comes to page rank, analytics, every other thing that directly bind with the urlcontent. But all the method won’t interfere with the search indexing process. I worry about analytics factor, page rank factor and most importantly social share buttons won’t work well in this method.
    You have to wait for better solution, if your site/blog relies mostly on search engine and social network sharing for bandwidth…

  67. HockeyGuy
    Permalink to comment#

    your code is very broke with the version of Jquery that ships with wp 3.5
    actually even earlier versions of jquery….
    /wp-includes/js/jquery/jquery.js?ver=1.8.3

    is this project just abandoned for now?

    There are a handful of other howtos similar to this but all of them are well out of date and without rewriting a lot of the code something that seems simple just won’t work well..

    If anyone knows some good code that works with wp 3.5 please leave a msg.

    • JakeLisby
      Permalink to comment#

      I had the same issue with the shipped version of jquery and ended up needing to dereg that version and add my own version that is included with the theme I created. You should include in your functions.php file, but here’s the statement to remove it from the front-end of your site. (The admin side requires the shipped version of jquery to correctly function.)

      if ( !is_admin() ) wp_deregister_script('jquery');

  68. peyman
    Permalink to comment#

    Hello
    how can i download this Theme???

  69. jase
    Permalink to comment#

    Is there any chance you could post an update on this that QUICKLY and SUCCINCTLY explains how to use AJAX to load post content in WP3.6? This is a great resource, but the code is out of date and even the updated code is out of date (live was deprecated a long while back).

    With sites that have heavy graphics that take a while to load, AJAX is the only way to go for content loading. My site is setup where all of the “sections” have to preload so they can be scrolled serially. Without Ajax, it wouldn’t work at all.

    Thanks for your help.
    jase

  70. Permalink to comment#

    Hy!
    I have a little problem….
    So the page loader not working for me, becouse I use the default permalinks strukture,becouse must…
    The new post loading in ajax (you know serverInternal) and this required the defaut permalinks strukture…
    If I not use default strukture,de function come back with 404…

  71. nao
    Permalink to comment#

    Hey Chris,

    Little snag – video download is downloading as TXT.

    For example, #81- AJAXing a WordPress Theme.txt

    Content is fine, however. Just renamed it with an .m4v extension and the all’s good.

    Peace

  72. Robert
    Permalink to comment#

    Hi everyone, I’m still a n00b talking about Ajax so I would ask if there is a possibility to have the final code of this because it’s hard to follow it for me. If I had the code I can read it slowly :)

  73. Josh

    I realize that this article is quite a bit older, but it still comes up pretty high in search results so I thought I would ask:

    When using jQuery’s load function, doesn’t this make a request to the entire WordPress page, including all sidebar widgets and everything else, just to pull a chunk of content from a div? Is it considered best practice to do it this way? Are there any concerns with performance?

    Thanks!

  74. Brandon

    Dude I love this video I’m laughing my ass off the whole time but I’m able to pay attention. It’s like you are speaking to my A.D.D. lol

Leave a Comment

Current day month ye@r *

*May or may not contain any actual "CSS" or "Tricks".