WordPress
Article

Building a PhoneGap App with a WordPress Backend

By Narayan Prusty

In this tutorial, we will cover how to use WordPress as a backend for a PhoneGap mobile app. We’ll then look at how we can create REST APIs for WordPress so that the PhoneGap app can communicate with WordPress using those APIs. We’re also going to build a simple PhoneGap app which allows users to login and then display a list of WordPress blog posts.

PhoneGap using WordPress

Mobile application development solutions like AppPresser, Mobicloud and IdeaPress are limited to creating blog-style apps. Understanding how to integrate WordPress with PhoneGap will help you to build any kind of app utilizing WordPress as a backend.

Creating WordPress REST APIs

Let’s start with setting up WordPress REST APIs. WordPress provides you the necessary actions to create REST APIs which can be used by any HTTP client. REST APIs can be installed via a WordPress plugin or theme.

WordPress actions wp_ajax_ and wp_ajax_nopriv_ can be used to create GET or POST REST APIs.

A callback attached to wp_ajax_ is executed if the HTTP client making the request is logged in into WordPress. Similarly a callback attached to wp_ajax_nopriv_ is executed if the HTTP client making the request is not logged into WordPress.

Let’s create a REST API which allows a user to login into WordPress.

function already_logged_in()
{
	echo "User is already Logged In";
	die();
}

function login()
{
	$creds = array();
	$creds['user_login'] = $_GET["username"];
	$creds['user_password'] = $_GET["password"];

	$user = wp_signon($creds, false);
	if (is_wp_error($user))
	{
		echo "FALSE";
		die();
	}
	
	echo "TRUE";
	die();
}

add_action("wp_ajax_login", "already_logged_in");
add_action("wp_ajax_nopriv_login", "login");

Let’s see how the above code works:

  • If the user is already logged in the while making an AJAX request using PhoneGap, a user session cookie is automatically sent to the server. In this case already_logged_in function is executed.
  • If no user session cookie is sent to the server i.e., user is not logged in then login function is executed.
  • We need to make HTTP requests to http://[your_domain_name]//wp-admin/admin-ajax.php?action=login&username=your_name&password=your_password. Here the action is the REST API name i.e., the string name that comes after wp_ajax_ and wp_ajax_nopriv_.
  • You can either make a GET or POST request to this URL but it’s compulsory to provide the REST API name.
  • wp_signon is used to create a user session cookie i.e., used to login a user into WordPress.

Let’s create another REST API which returns the ten latest blog posts in JSON format.

function posts()
{
	header("Content-Type: application/json");

	$posts_array = array();

	$args = array("post_type" => "post", "orderby" => "date", "order" => "DESC", "post_status" => "publish", "posts_per_page" => "10");

	$posts = new WP_Query($args);
	
	if($posts->have_posts()):
		while($posts->have_posts()): 
			$posts->the_post();
            
            $post_array = array(get_the_title(), get_the_permalink(), get_the_date(), wp_get_attachment_url(get_post_thumbnail_id()));
            array_push($posts_array, $post_array);
			
		endwhile;
		else:
        	echo "{'posts' = []}";
        	die();
	endif;
	
	echo json_encode($posts_array);

	die();
}

function no_posts()
{
	echo "Please login";
	die();
}

add_action("wp_ajax_posts", "posts");
add_action("wp_ajax_nopriv_posts", "no_posts");

Let’s see how the above code works:

  • Here we registered a HTTP API with name ‘posts’.
  • If a user is not logged in then it returns a message to login. If the user is logged in, then it sends a JavaScripts array with ten latest posts.
  • Here we use WP_Query object to retrieve the blog posts.

Creating a PhoneGap App

Let’s now cover how to create a PhoneGap app by using WordPress as a backend.

There are a couple of points to note before proceeding with this tutorial:

  • There are two ways to build a PhoneGap app. You can use PhoneGap online builder or you can build it yourself using the PhoneGap desktop builder. In this tutorial, I will be assuming you use desktop builder.
  • PhoneGap app doesn’t obey AJAX and Cookie Same Origin Policy. Therefore you can make an AJAX request to any website using JavaScript running in the PhoneGap app. Also during HTTP requests, all cookies are sent to the server and any domain can store cookies in the app.

The PhoneGap app we will building in this tutorial will have the following directory structure and files.

--www
    --cordova.js
	--js
	    --index.js
	    --index.html

www directory will be present in your newly created project.

Here cordova.js file needs to be the same as provided by default.

Remove all content present in index.js and index.html file.

Put this code in your index.html files.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height" />
        <title>Sitepoint - PhoneGap App using WordPress</title>
        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.4/jquery.mobile-1.4.4.min.css">
    </head>
    <body>
        <div data-role="page">
            <div data-role="header" data-position="fixed">
                <h1>Login</h1>
            </div>

            <div data-role="main" class="ui-content">
                <input id="username" type="text" placeholder="Enter Username">
                <input id="password" type="password" placeholder="Enter Password">
                <button onclick="login();">Login</button>
                <a href="#pagetwo" id="page_two_link"></a>
            </div>

            <div data-role="footer" data-position="fixed">
                <h1>Made by @narayanprusty</h1>
            </div>
        </div> 

        <div data-role="page" id="pagetwo">
            <div data-role="header" data-position="fixed">
                <h1>Posts</h1>
            </div>

            <div data-role="main" class="ui-content">
                <ul data-role="listview" id="posts">                 
                </ul>
            </div>

            <div data-role="footer" data-position="fixed">
                <h1>Made by @narayanprusty</h1>
            </div>
        </div> 

        <script type="text/javascript" src="cordova.js"></script>
        <script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
        <script src="http://code.jquery.com/mobile/1.4.4/jquery.mobile-1.4.4.min.js"></script>
        <script type="text/javascript" src="js/index.js"></script>
    </body>
</html>

Let’s see how the above code works:

  • Here we are using jQuery mobile to create the UI of the app. jQuery mobile is loaded from CDN.
  • We have two pages. The first one is a login page and if the credentials are correct then user is moved to second page where a list of posts is displayed.
  • When the login button is clicked a JavaScript login function is called.

Now we are done with the UI of the app, let’s code the frontend functionality. Put this code in index.js file.

function fetch_and_display_posts()
{
    var xhr = new XMLHttpRequest();
    xhr.open("GET", "http://localhost/wp-admin/admin-ajax.php?action=posts");
    xhr.onload = function(){
        var posts_array = JSON.parse(xhr.responseText);

        var html = "";

        for(var count = 0; count < posts_array.length; count++)
        {
            var title = posts_array[count][0];
            var link = posts_array[count][1];
            var date = posts_array[count][2];
            var image = posts_array[count][3];

            html = html + "<li>" + "<a href='javascript:open_browser(\"" + link + "\")'>" + "<img height='128' width='128' src='" + image + "'>" + "<h2>" + title + "</h2>" + "<p>" + date + "</p></a></li>";
        }

        document.getElementById("posts").innerHTML = html;
        $("#posts").listview("refresh");
    }
    xhr.send();
}

function login()
{
    var username = document.getElementById("username").value;
    var password = document.getElementById("password").value;

    if(username == "")
    {
        navigator.notification.alert("Please enter username", null, "Username Missing", "OK");
        return;
    }

    if(password == "")
    {
        navigator.notification.alert("Please enter password", null, "Password Missing", "OK");  
        return;
    }

    var xhr = new XMLHttpRequest();
    xhr.open("GET", "http://localhost/wp-admin/admin-ajax.php?action=login&username=" + encodeURIComponent(username) + "&password=" + encodeURIComponent(password));
    xhr.onload = function(){
        if(xhr.responseText == "FALSE")
        {
            navigator.notification.alert("Wrong Username and Password", null, "Wrong Creds", "Try Again");
        }
        else if(xhr.responseText == "TRUE")
        {
            fetch_and_display_posts();
            $("#page_two_link").click();
        }
    }   
    xhr.send();
}

function open_browser(link)
{
    window.open(link, '_blank', 'location=yes');
}

Let’s see how the above code works:

  • Here we have three functions. login function retrieves the username and password from the form and sends it to WordPress. If the credentials are correct then WordPress sends back a session cookie indicating a user is logged in. Then we call the fetch_and_display_posts function which actually retrieves the latest ten posts and displays it in the second page. When someone clicks on a post we call the open_browser function which displays the complete article in a new browser window i.e. using PhoneGap InAppBrowser.
  • Here during AJAX request I have used domain name as localhost. Make sure you replace that with your own domain name.

Here are the screenshots of the working PhoneGap App using WordPress.

PhoneGap using WordPress 1

PhoneGap using WordPress 2

PhoneGap using WordPress 3

Further Information

So now you know how to create a simple PhoneGap app using WordPress as a backend. If you’re looking for more information, here are a list of some other useful resources that are great for new PhoneGap developers:

Free Guide:

7 Habits of Successful CTOs

"What makes a great CTO?" Engineering skills? Business savvy? An innate tendency to channel a mythical creature (ahem, unicorn)? All of the above? Discover the top traits of the most successful CTOs in this free guide.

  • http://nyasro.com/ Nyasro

    Very nice and helpful article. Thanks for this.

  • http://zhbhijrah.my Rahman Ramesh

    Great intro to phoneGap via WordPress! Thanks for the tip.

  • UncatCrea

    A very good article. Thank you. We need more of those.

  • begs

    where do you put the first code
    function already_logged_in()
    function login()
    ….
    is this a plugin which one should create?

    • Daniel

      You can probably put it in pretty much any file you know will run. I would suggest that you put it in your functions.php.

      The trick is that he’s using the WordPress add_action function to add the login & already_logged_in functions. So when you send an ajax req to admin-ajax.php with an action that matches the login or already_logged_in function, WordPress will runt that function.
      add_action(“wp_ajax_login”, “already_logged_in”);
      add_action(“wp_ajax_nopriv_login”, “login”);

      • begs

        Thanks for the detailed information

      • http://customizedclouds.com Adam Dartez

        Yea I dropped the code into my functions file and worked perfectly…

        • Nerdy

          dropped what ?

          all below ?

          function already_logged_in()

          {

          echo “User is already Logged In”;

          die();

          }

          function login()

          {

          $creds = array();

          $creds[‘user_login’] = $_GET[“username”];

          $creds[‘user_password’] = $_GET[“password”];

          $user = wp_signon($creds, false);

          if (is_wp_error($user))

          {

          echo “FALSE”;

          die();

          }

          echo “TRUE”;

          die();

          }

          add_action(“wp_ajax_login”, “already_logged_in”);

          add_action(“wp_ajax_nopriv_login”, “login”);

          in the functions.php ?? i did that but the site stoped .. the last 2 statements seem to cause some error,

          if i remove

          add_action(“wp_ajax_login”, “already_logged_in”);

          add_action(“wp_ajax_nopriv_login”, “login”);

          the site will work again but the actions will not be added

  • jjkktr

    Nice Article, can you/anybody share a article Building a PhoneGap App with a drupal Backend

  • clinkme

    Is it possible to do it with ajax? I’m trying to do it using ajax but not working :(

  • http://customizedclouds.com Adam Dartez

    Oh man thank you so much for this tutorial, what was I thinking about to spend $300 to buy an appresser theme, this is way more flexible…PS the tutorial worked perfectly! Thanks again bro!

  • http://customizedclouds.com Adam Dartez

    Hey bro sorry for the double comment but I wrapped the PHP code from your tutorial inside a WP plugin and have been easily able to add additional post types to it by basically following the schema you gave. I’m creating a phonegap app to access a site I’m running WooCommerce on and was easily able to add the products custom post type, and really any post type that’s on the website easily. But now I want to access pages with the plugin but am having trouble figuring out how to edit the array to do that. For instance WooCommerce has a reports page located at /wp-admin/admin.php?page=wc-reports and if I could figure out how to set up the array I could access any page but am really having trouble understanding the codex. I know the answer lies in editing this part of the code from your tutorial

    $posts_array = array();

    $args = array(“post_type” => “post”, “orderby” => “date”, “order” => “DESC”, “post_status” => “publish”, “posts_per_page” => “10”);

    $posts = new WP_Query($args);

    if($posts->have_posts()):

    while($posts->have_posts()):

    $posts->the_post();

    $post_array = array(get_the_title(), get_the_permalink(), get_the_date(), wp_get_attachment_url(get_post_thumbnail_id()));

    array_push($posts_array, $post_array);

    endwhile;

    else:

    echo “{‘posts’ = []}”;

    die();

    endif;

    echo json_encode($posts_array);

    but I’m such a noob I can’t figure it out. As far as I can tell instead of using

    “post_type” => “post”

    you need to call get_page in your arguments array, but even then I can’t figure out to set up the loop to loop over pages instead of posts like you showed here

    if($posts->have_posts()):

    while($posts->have_posts()):

    $posts->the_post();

    Is there anyway you could give an example of accessing a page over rest like you did with posts? Or maybe point me in the direction of a tutorial that explains this. Again sorry about the double comment but if I could figure this part out then I’d be able to access any wp content type in my phonegap app. If not I still want to thank you SO much for this tutorial, I’ve studied your code for the last five days and it’s really helped me understand rest a lot better so again thanks alot!

  • sovanda

    i’m trying but is not working…

  • Bheemagani Madhu Goud

    Good article it is very useful brother..and i am going to start to build the phone gap app using REST API

    http://www.webtutorialspoint.com/phone-gap/using-phonegap-how-to-create-sample-app-for-ios/

  • Rob Chan

    How would one go about setting this up without the log in? So just showing the most recent posts.

    • http://qnimate.com/ Narayan Prusty

      Just use WP_Query to retrieve posts.

  • Nesh

    I did all the steps mentioned above but while running in the browser after clicking the login button, nothing happens .

  • Theo

    Hi Narayan,

    Thanks a lot for your tutorial!

    One question though, you state: “PhoneGap app doesn’t obey AJAX and Cookie Same Origin Policy”

    But when I test my PhoneGap app with the The PhoneGap Developer App i run into security issues.
    The ajax call can not be made if i don’t set the header to (“Access-Control-Allow-Origin: *”) in admin-ajax.php.
    But when I set the header then the sessions are not working correctly; already_logged_in () is never fired…

    Any suggestions? Has it something to do with the The PhoneGap Developer App?

    Best regards,

    Theo

  • Theo
  • Bruno Giubilei

    Hi Theo i have the same problem, i fixed this using this codes for PHP in the files on my server side implementation.

    header(‘Access-Control-Max-Age: 1728000’);

    header(‘Access-Control-Allow-Origin: *’);

    header(‘Access-Control-Allow-Methods: *’);

    header(‘Access-Control-Allow-Headers: Content-MD5, X-Alt-Referer’);

    header(‘Access-Control-Allow-Credentials: true’);

    regards!

  • kim

    Hi, good article but I have problems…

    When I test the app in PhonegappAPP I can’t see any posts… appears “Please login”.

    I suppose it’s due the problem described in https://github.com/phonegap/phonegap-app-developer/issues/253….

    There’s a way tot test the app correctly?

  • brandecho

    Hello all. In the first two code blocks in this article, is it safe to assume that the code goes into the WordPress Theme function.php file?

  • Tierra de Frikis

    Excelente! Me encanto!

  • Dan

    Great tutorial, cant get it to work properly though, getting a few errors:

    Uncaught ReferenceError: require is not defined
    (index):19 Uncaught ReferenceError: login is not defined

    Can you possible add a download option of you package?

    Thanks,
    Dan

  • Evan Omondi

    is it possible to have a view on the app that gets data from wordpress without the user necessarily having to login? just having the wordpress as a backend for uploading articles

  • http://shivaramaniyer.ind.in/ Shivaraman Iyer

    Thanks for this article. It has been very helpful for me to start with a phonegap app. The thing is I am logging the user out using an action ‘logout’, but whenever I try to log back in, the older user’s session is still being maintained. any idea on how to log the user out?

    I am using ionic framework for the app, which uses angular for running the app.

  • bobin56

    Login does not work on my end , when i inspect it seems like the ajax call is not working , responseText is empty and readyState ends up at 1…please help

  • http://www.wiziwiz.com/ wiziwiz

    hmmm does this need rewrting? – I placed the the the code in functions.php and site crashed

  • Alejandro Tiria

    Excelente explicación me funciona perfecto, ahora como hago para cerrar la sesión logout?

  • Alejandro Tiria

    logout WordPress API REST?

  • jonpaulharvey

    Not very secure at all though passing unencrypted user creds in that manner???

Recommended
Sponsors
Because We Like You
Free Ebooks!

Grab SitePoint's top 10 web dev and design ebooks, completely free!

Get the latest in WordPress, once a week, for free.