Use AngularJS Custom Directives In A WordPress Theme

This is the 3rd post of a series about building WordPress themes with AngularJS and WP REST API (WP API).

In previous posts, you’ve learned some new HTML tags and attributes like <ng-view> and ng-repeat, which we call “built-in directives” in AngularJS. In fact, anything you’ll learn starts with "ng" means it comes from AngularJs, and in general we shouldn’t prefix our custom directives (or functions) with the same “ng” pattern.

Long story short, “directives” are a way AngularJS manipulates parts of the DOM. They look like HTML tags or attributes and are used like HTML tags or attributes. The hard part is to define their “behaviors” so we can get the expected results.

As a developer comes from WordPress world, the first impression to me on AngularJS “directives”, is that they work like “template tags” in themes.

By its definition, Template tags are used within your blog’s Templates to display information dynamically or otherwise customize your blog, providing the tools to make it as individual and interesting as you are.

That said, we use template tag to save time. For example, we call get_header(), get_footer(), get_sidebar() every time we need the same pieces on a single page.

In this tutorial, I’ll show you how to create a custom directive with AngularJS called <search-form>, to make it work like the WordPress template tag get_search_form(). And with WP API, we can get the search results in our demo single page application. Check the screencast below:

Use custom directive to create a search form , the ng-change version

0. Getting Started

You need to download the project files from the GitHub repo if you want to start right away. The project file is a zipped WordPress theme, so you need to activate it in your WordPress install to see the demo work.

1. Create the <search-form> custom directive

For the best practice you should prefix your own custom directive, make it like “<my-search-form>”. I skip prefix to make the code cleaner and more readable.

We can register our custom directive with the following code:

First thing you’ll notice is, the directive name "searchForm" is camelcased. When AngularJS meets <search-form> in the DOM, it does the magic by transforming <search-form> to searchForm, and find the matching custom directive function to execute, such process is called “normalization”. (You can search for “normalization” in this documentation.)

1.1. Tag or attribute?

By default, the custom directive can be used as HTML tag element or attribute. If you’d also like to use it as a class name, you can change the restrict property to "EAC", by adding a “C” to “EA” (which E is for element, and A is for attribute).

1.2. A much simpler search form

In general, the HTML of a default WordPress search form (generating by get_search_form()) should look like this:

But in the template property of the searchForm directive, I remove the form and submit button, leave only the text input element, to make the HTML much cleaner.

1.3. Data binding with ng-model

The value of ng-model may look a bit odd to some of you. Please note I use filter.s on purpose, it means “the s property of the filter object”. We’ll add the filter object to the $scope in the controller later, so AngularJS can monitor the change of its value for us.

2. Add the controller property to the custom directive

2.1. Add a filter property to the $scope

In the controller, before we create the search function, I add a new property called filter to the $scope, and the filter property is an object with a s property, which is set to an empty string by default.

2.2. Use $http service to get the search results

In the search function, we still use the $http service to communicate with the JSON REST API (WP API, be sure you’ve install and activate the plugin). We need to pass an extra parameter to the query URL, which is filter. The filter parameter controls the parameters used to query for posts, just like the query variables we use in WP_Query. After we add the query string, the query URL become 'wp-json/posts/?filter[s]=' + $scope.filter.s.

3. Search when the user changes the input


3.1. The built-in ng-change directive

So how do we trigger the search function? You must be wondering: Can I use something like onchange in JavaScript? This answer is YES! Let’s add a "ng-change" directive (attribute) to the input element, and set its value to search(). Now whenever the value in the search input changes, AngularJS will call the WP API to get the search results.

We can reduce the API calls by checking the length of "filter.s" string, i.e. the length of the characters should be equal or more than 5 to trigger the search.

3.2. Insert the tag to your template

The last step we should do, is to insert the custom directive to the template. I just place the <search-form></search-form> on top of the main.html. You can try different flavors like <div search-form></div> or <div data-search-form></div>.

4. HTML search form and ng-submit

The search function should work now. I’d like to show you another way to create a “real” search form, other than just one simple text input in previous example. Personally I prefer the 1 text input method, but it’s good to learn more about directives in AngularJS by the following example. Let’s create a new file called search-form.html to the partials folder:In the custom directive function, remove the template property, and add templateUrl to set the path of the search form.

Now you’ll need to submit the form by clicking the submit button, or pressing the enter button to get the search results.

Use custom directive to create a search form , the ng-submit version

You can get the finished files from the GitHub repo for this project (ng-change version / ng-submit version). This article only provides you with very basic introduction about custom directives in AngularJS, so I have some further reading for you:

If you have any question when following the steps in this tutorial, please feel free to contact me.

Happy Holidays!

21 responses

  1. […] previous posts (1st, 2nd, 3rd) I’ve covered several topics in AngularJS with a very simple WordPress theme, […]

  2. Hi there Yoren,

    I have been interested in angularJS for quite a while and am excited to see it catching on. Your series on WP theme and aJS integration was very helpful in gaining direction as some of the directives and server-side integrations were a bit confusing. I hope to see more posts in the future about this topic from you. Keep up the good work, and please do contact me if you have any tips you’d like to share. Have a great day!


    1. Yoren Chang Avatar
      Yoren Chang

      hey Jeff, thanks for the nice words. I’m happy to know my tutorials really helped. The idea I started my AngularJS+WP series is exactly to introduce AngularJS to WP devs with some simple examples. I’ll write at least 1-2 tutorials in this series every month. So see you soon! 🙂

  3. […] So far we’ve built one with category archives and pagination, and also a functional search form in it. You can just download it and focus on this tutorial right away, though I do encourage you […]

  4. Im trying out this tutorial and it works great!
    I still have one question tho, i’ll start with example:

    content- “Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!”

    searching term – “hi”

    i still get the results to be true.

    im guessing that its searching for each letter and giving me true because it found ‘h’ and ‘i’ in this content even tho its not ‘hi’.
    how can i make it so that its searching for ‘hi’?

    1. btw, how can i highlight the search result?

      if this is whole another tutorial, i’ll just search on google to find a way but asking just in case there is a super easy solution.

      1. Yoren Chang Avatar
        Yoren Chang

        About search terms highlighting, there’s no quick and dirty way in WordPress or AngularJS. Good Luck on googling!

    2. Yoren Chang Avatar
      Yoren Chang

      Hello, Ben, Due to the design of the search in WordPress, it won’t exactly match the “word” you’re searching for. I believe some search plugins might solve this, and even the ElasticPress ( should provide a better user experience.

  5. Arunraj Avatar

    Hi YOREN,

    Your tutorial so so useful for me, i have doubt in how to make wordpress comment form in angular js theme. . . .


    1. Yoren Chang Avatar
      Yoren Chang

      hi, Arunraj, please check this comment (and its reply) out:

  6. Hi, please check the code below:

    var app = angular.module(‘myreddit’, [‘ionic’, ‘ngSanitize’, ‘angularMoment’])

    app.controller(‘RedditConlr’, function($http, $scope, $sce){

    $scope.stories = [];

    angular.forEach(response, function(child){

    I can successfully retrieve my posts but post title showing escaped characters instead of special characters like this:
    (If you are a WordPress lover – you’ll like these!)

    Please help , I am very new to angular js.

    1. Yoren Chang Avatar
      Yoren Chang

      Hi, Rituparna, You can use ng-bind-html to display the title. For example, ‹h1 ng-bind-html="post.title"›‹/h1›. It should display the special characters as usual.

  7. […] a custom directive in AngularJS is very easy, you can go back to check out my previous tutorial about it again. The gist below shows […]

  8. I dont like this wp theme

    1. Haris, your comment is pretty irrelevant.

  9. Abhay Avatar


    how to implement contact form with angular.

  10. Dragan Milunovic Avatar
    Dragan Milunovic

    Just to say ……thank you very much for wonderful tutorials :))

    1. Yoren Chang Avatar
      Yoren Chang

      Hey Dragan, Thanks for your kind words. I’m flattered!

  11. Hi,
    Can we use the “ng-change” directive on the .html form version ?

    1. Yoren Chang Avatar
      Yoren Chang

      Not sure what you meant but ng-change is a built-in directive so definitely yes.

  12. Hi Everyone!
    To get the search functionality to work correctly with WP API V2 you will need to update this:

    to this:

Leave a Reply

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