Using Slug To Get Single Post In AngularJS WordPress Theme

In the first post of my AngularJS WordPress theme series, I set the post title to link to {{post.ID}} so I can get a single post with the default route in WP API: /posts/<id>.

Couple days ago Ryan asked me can we use slug instead of ID, and reminded me that in the original demo video (Eric Wolfe: Building a WordPress Theme Using AngularJS), Eric did use the slug rather than ID. At first I replied to him it’s because Eric used the JSON API not WP API (JSON REST API), by default the WP API can only get post by ID.

The answer was not so persuasive I thought it’s better to double checked. Luckily I found the right answer in Josh‘s article on Torquewe can get posts by slug with filter parameter.

So here are the snippets you’ll need to update, if you prefer to use slug in our project files (from my previous tutorials):

1. js/scripts.js

  • line 6: Change /:ID to /:slug
  • line 16: Change 'wp-json/posts/' + $routeParams.ID to 'wp-json/posts/?filter[name]=' + $routeParams.slug
  • line 17: With this approach, we’ll get an array of posts, so we set $scope.post = res[0].

2. partials/main.html

  • line 5: Change {{post.ID}} to {{post.slug}}

You can get the full code from a branch of the project repo. I hope short posts like this can also help readers understand better about AngularJS and WordPress, especially how to accomplish a specific task. See you soon.

46 responses

  1. Hi, really liked your tutorial. It was a very good starting point for me to build themes using Angular for WP. It would be great if you can guide me on using OAuth1 for getting list of users, get articles for some users. I have been checking on net for quite some time but not getting any answers. Great if you can point me at the right direction.

    1. Yoren Chang Avatar
      Yoren Chang

      hey, Abhijit, thanks for your kind words. I’ve done the search about oauth with WP API and get the same results with you. I haven’t tested it by myself (https://github.com/WP-API/client-cli) but it looked a easy start. I hope I can write some tutorials about it soon, thought it may be an much advanced topic than mosts posts I’ve written.

      I’ll send an email to notify you if I do write about the oauth topic. Talk you soon!

  2. Hi Yoren, thanks for the quick reply. I’ll definitely check the link you posted! Will surely stay in touch! 🙂

  3. Thanks Yoren. I appreciate your mention in the article. I’d love to work with you to build a full-scale WordPress Application using Angular.

    I need to understand how to use the WP-API much better and then I think I can make WordPress very powerful.

    Other concerns of course are SEO, building SPAs can have a negative effect on search, though I know there are some ways around it.

    Please keep me updated on what you learn.

    Thanks

    1. Yoren Chang Avatar
      Yoren Chang

      Hey Ryan, about the SEO issue, I’ve read some articles about Google is now able to execute JS when indexing webpages: http://googlewebmastercentral.blogspot.com.es/2014/05/understanding-web-pages-better.html

      Another tip I found recently is that the permalink structure in WordPress and the link structure in our AngularJS app must be identical. Because it looks that search engines will still index the WordPress URLs for our app.

      Thanks for stopping by and sharing my posts!

  4. Incredible post indeed.

  5. […] And we need to change the markup in main.html to display the loop. See the elegant ng-repeat below, I really like this one. (If you prefer to user slug, please check out the following post: Using Slug To Get Single Post In AngularJS WordPress Theme) […]

  6. Nicolas Avatar

    Hi Yoren, thank you for all your tutorials !!

    For get page, it’s simple, we add : type[]=page to the request. But how to do this with route ?

    Thank you !

    1. Yoren Chang Avatar
      Yoren Chang

      Hey Nicolas, just tweet you back. Have you tried /wp-json/pages?filter[name]=some-page ?

  7. Just a thought: to make things a bit more accessible in the content.html file and avoid continually pointing at item 0 in an array, you can just change the Content controller to use “$scope.post = res[0];” which will keep content.html code as it was.

    1. Yoren Chang Avatar
      Yoren Chang

      Hi Daniel, Thanks for your feedback. Just tidied up the code accordingly.

      1. Maybe will be better “$scope.post = res.pop();” ?

        1. Yoren Chang Avatar
          Yoren Chang

          Hey Goomba, it’s obvious you speak fluent JS than us!

  8. gaggo Avatar

    @YOREN,

    So nice, your work! But I just can’t get something out of my head: How can we give the crawlers something to eat when they come?

    As it is now, they would just find a sad empty page. (Testable if reloading any of the sub-pages with javascript turned off). Do you have any idea already on how to solve these problems? Otherwise we will all go back to the stone-age of flash seo-wise 😉

    1. Yoren Chang Avatar
      Yoren Chang

      Hey Gaggo, you can check out my answer/thoughts on this question: https://1fix.io/blog/2015/02/08/set-page-title-angularjs-wordpress-theme/#comment-6788

    2. Yoren Chang Avatar
      Yoren Chang

      And I’d also like to note that Google have announced they can interpret JavaScript now (last year as I recall). So it could be an accessibility issue more than SEO issue I guess. 😉

      1. Gaggo Avatar

        Damn, I missed that you answered… A “subscribe to comments” plugin would be great. I am from Germany and over here everybody is super-conscious about accessibility, so I would have to re-write all the pages server-side.

        Another approach could be to let Angular build the html and then save it to a transient named after the current url once a day. Then, the post could render this transient, if javascript is turned off.

        Any thoughts?

        1. Yoren Chang Avatar
          Yoren Chang

          I’ll say for now for better accessibility, we should still render the page with server-side scripts like PHP and only load (change) content with JavaScript when the user interacts with the page (a click with mouse or enter with keyboard).

          Somehow I even think things might be easier (for developers) if we build a separate site for disabled users. But I know it’s not recommended.

          I’d love to install subscribe to comments plugin which:
          1. doesn’t rely on 3rd-party service
          2. doesn’t create extra tables in database
          Any suggestion? 😉

  9. Gaggo Avatar

    Ah ok, I see, this actually creates separate tables… Then I don’t have any idea 😉

    1. Yoren Chang Avatar
      Yoren Chang

      Ha, I might be asking for too much!

  10. This is a great tutorial, already using this tutorial on my local (wordpress). so im curious to implement this tutorial on mobile apps using ionic, i get “?filter[name]=undefined” object in console on $routeParams.slug or ID. still can’t figure it out, did i missed something on this tutorial or is there a different method if we want to use it on mobile apps using ionic or phonegap.

    1. Yoren Chang Avatar
      Yoren Chang

      Hey there, I haven’t used ionic yet but I doubt if my scripts can fully compatible with it.

      For example, ionic relies on ui-router heavily so you should be using state instead of route to set the routes in your app. In that case, the $routeParams will become $stateParams either.

      I’m just guessing based on ionic tutorials I’ve read. Let me know how exactly you solve this. Good luck!

      1. Geezzz… i didn’t see that coming…! works perfectly using $stateParams rather than $routeParams, thank you very much, you really saved my day.

        1. Yoren Chang Avatar
          Yoren Chang

          Great! Glad I can help.

  11. damien Avatar

    Nice tutorial,
    However, I think this method doesn’t with the v2 api rest.
    $scope.post = res[0]; returns the last post.
    Also do you have any idea to display the next post and the previous post, relative to the post inside a single post ?

    1. Yoren Chang Avatar
      Yoren Chang

      Hi, Damien, I’ve written about upgrading to WP API V2 here: https://1fix.io/blog/2015/09/29/wp-api-v2-angularjs-theme/. As to the post navigation, I think you’ll need to write a custom directive for it, and maybe also a custom endpoint for WP API to get those posts.

  12. Dragan Milunovic Avatar
    Dragan Milunovic

    Thank you very much for these tutorials…..
    Really helpful….I have just started to connect angular and wordpress….
    So far I have made a few wordpress sites from scratch….though dont have much experience in angular….just basics….hope dont have to make angular sites only by themselves…..I mean dont know can make wordpress theme by angular without too much knowledge of angular….
    BEST REGARDS…..and wish all the best in your work :))

    1. Yoren Chang Avatar
      Yoren Chang

      Hi Dragan, thanks for your kind words. I believe this series of tuts can help you with an easy start about WP and AngularJS. If you feel good about such stack and would like to go further, just check this project out: https://getmoxied.net/lean/.

      1. Dragan Milunovic Avatar
        Dragan Milunovic

        Hello again :)),

        thank you very much for the answer and just one more question.
        Which plugins should I use during making wp rest api themes…
        Are there some established plugins or should create some by myself like custom post types because future employers can appreciate more if I make some custom post type by myself…..
        Any words is highly appreciated…..thanks in advance……Best regards :))

        1. Yoren Chang Avatar
          Yoren Chang

          Hi Dragan, I think it’s a quite broad question that might indicate you’re new to WP / REST API development. I highly recommend Josh Pollock’s articles and a course to you: http://joshpress.net/learn-modern-wordpress-with-me/.

          Josh is very passionate about WordPress and he’s also a REST API advocator. I believe his course can help you on building a career as a professional WP developer.

          Wish you best luck and feel free to let me know your thoughts.

          1. Dragan Milunovic Avatar
            Dragan Milunovic

            Thanks, I will check his courses…..

  13. Hi Yoren,

    Brilliant tutorial you have here, loved them all. I have one question regarding SEO. As we all know, Yoast is the most popular WP plugin for SEO. How do we make it work in Angular-WP like a regular WP theme? Mainly I’m referring to the meta tags it can add into every individual pages. Secondly, the way it can manipulate breadcrumbs.

    Thank you very much.

    1. Yoren Chang Avatar
      Yoren Chang

      Hi Shaiful, the best way I can think of is to extend WP API with custom endpoints so you can expose breadcrumbs and meta tags to your Angular theme (template). It will require a specific amount of work especially when dealing with breadcrumbs, but it should work that way.

  14. Yaroslav Grushchak Avatar
    Yaroslav Grushchak

    Hi Yoren!
    Can you suggest, how can I get post by slug in WP REST API V2?

    1. Yoren Chang Avatar
      Yoren Chang

      Hey Yaroslav, sorry I missed your comment. It’s been a while I haven’t kept up with WP API v2, but the same approach should technically still work. Have you tried and failed at this?

      1. Yaroslav Grushchak Avatar
        Yaroslav Grushchak

        I have got it with /wp-json/wp/v2/posts?slug=

  15. Hi Yoren,

    Thanks for the good work.

    I have some problems with ng-route. Although I could make it work while on index (home) to /:slug navigation, it gets error -page not found- when I hit /:slug directly or refresh the page in slug view.

    I did use the and did the whole routing just like yours, but no idea about this situation. Any ideas?

    Thanks,

    1. Yoren Chang Avatar
      Yoren Chang

      Hey Gokhan, Have you set the permalink in WordPress as the same as the Angular route? That should fix this issue.

  16. Hi Yoren
    Am working on wordpress theme with Angular2, and am using this:

    getPost(slug): Observable {

    return this.http
    .get(this._wpBase + `posts?slug=${slug}`)
    .map((res: Response) => res.json());
    }
    to get the posts, but it doesn’t work upon build and deploy. When I tried using fields in place of slug, I get the last post instead the list of post titles.

    1. Yoren Chang Avatar
      Yoren Chang

      hey, Can you get the post list when you call WP API directly without Angular?

  17. Hi Yoren,
    it’s always me… 🙂

    I would like to use as permalinks settings a custum structure which is: /%category%/%postname%/

    Basically with 2 category: 1) articles 2) tracks
    I would like to have something like /articles/:slug and /tracks/:slug

    And gives to each category a different template based on different controller/partial. Can you give me any tips about this? What would be the best approach to make this work?
    Thanks in advance!

    Luca

    1. At the moment I’m using a dumb solution which is something like:

      .when(‘/tracks/:slug’, {
      templateUrl: myLocalized.partials + ‘content.html’,
      controller: ‘Content’
      })
      .when(‘/articles/:slug’, {
      templateUrl: myLocalized.partials + ‘articles.html’,
      controller: ‘Articles’
      })

      And I build the a links manually based on the section (i.e. tracks/{{post.slug}} or articles/{{article.slug}} )
      But I guess there is a smart solution…

      1. Yoren Chang Avatar
        Yoren Chang

        Hey Luca, honestly I used the dumb solution as yours when I was in need. I’m not as avid on AngularJS as the time I wrote the series of tutorials, so I never had the chance to dig a better solution. Feel free to come back and share with us when you find one!

        1. Yes this is working, but it encounters in many errors, for instance you can access to the same page with multiple layout. If I have a slug like ” track-example ” you can see it as ” /tracks/track-example ” and ” /articles/track-example “. You have to pay attention to all the internal href you do

          1. Yoren Chang Avatar
            Yoren Chang

            Yes exactly. That’s why it’s a dumb solution. Haha.

Leave a Reply

Your email address will not be published. Required fields are marked *