Web Components, PhoneGap Build and WordPress – A Hybrid App for your Blog

Tweet about this on TwitterShare on LinkedIn3Share on Google+0Share on Reddit0Buffer this pageFlattr the authorEmail this to someonePrint this page

Web Components, PhoneGap Build and WordPress

What started of as a “small experiment” ended up with me sleepless for 2 days straight.

It all started with this video

Pretty pumped up, I started off exploring the New Polymer. I used Polymer a couple of months ago and wrote a tutorial on Web Components and Polymer . Now, a lot has changed. So, super excited about the new way of developing Web Components, I quickly whipped out 3 new components (<upper-case><lower-case> and <capital-case>). Pretty basic, but gave me a decent hands on.

Then I started digging into their tutorial (a must read) and loved the way how components go hand in hand in building an actual application, yet the smaller pieces remain reusable. This got me thinking to make a Hybrid app for my blog using Web Components, PhoneGap and WordPress and this post is the on-going journey.

As of today I was not able to get the Hybrid app working on most of the devices. I was able to get it working only on an iOS emulator (did not test on iPhone/iPad device) and Android 4.4.2 (Android emulator).  but I have raised this issue with the Polymer folks.

The final app will look like

Screen Shot 2014-06-28 at 1.55.17 pm

You can take a digg at the demo here.

You can find the complete code here, the Installer source repo here and the PhoneGap installer here.

Note : I will be updating this post from time to time as things progress.

Contents

Prerequisites

To get started off, make sure you have completed the following

Setup WordPress JSON API

First, we will update the existing WordPress to spit out a JSON when we hit certain end points. For that we are going to use JSON API a WordPress plugin, that will expose our blog feeds as REST API.

Navigate to your Wordpress Admin Dashboard, Plugin > Add New. Search for JSON API and install it. Once installed, navigate to Settings > JSON API and make sure the core module is activated.

Screen Shot 2014-06-28 at 9.23.40 am

Activate other module only if you know what you are doing. 

Now, open  http://blogurl/api/get_recent_posts/ for my blog it would be  http:/api/get_recent_posts/ and you should see a JSON response like

Screen Shot 2014-06-28 at 9.26.50 amIf you do not see the response, refer to the troubleshooting section.  You can explore more API methods and options from JSON API notes.

Setup the project

Create a new folder named myBlogsHybridApp. Create 2 new folders named dev and dist inside it. This is more of a preference and totally optional. Now inside the dev folder, create another folder named app. This is where we will be building the Web Component app. Once the development is done, we will move the required folders to the dist folder.

Develop the app

Now, we are going to develop the actual app using Web Components. I have followed the Web Components tutorial very closely and built the app, so I will be reusing the structure as well as most components as they are and then fine tune it for our needs.

The logic is pretty simple. There are 2 types of tags, one which have a visual presence like the div tag or span tag and the other which are more functionality oriented like the script tag or style tag.

In our app, we will build/use a post-service tag that will fetch the JSON. This response will be consumed by a post-list tag and then will generate each blog post using the blog-post tag. Finally we will be using a couple of core components to get the look and feel.

Open terminal/prompt inside the app folder and run

bower init

You can fill it up as

Screen Shot 2014-06-28 at 9.52.36 amWe will be using bower to install a bunch of dependencies. Next create a new file at the root of the app folder and name it .bowerrc and fill it up like

Next, Run

bower i --save polymer platform polymer/core-ajax polymer/core-header-panel polymer/core-toolbar

 You may be asked with this question while installing

Screen Shot 2014-06-28 at 9.58.09 am

This will dump all the required dependencies inside the components folder. Create a new file named index.html at the root of app folder and open it in your favorite editor.

This will be our blog’s home page or the startup screen on the device. We will import core-header-panel, core-toolbar and post-list components as dependencies. You can fill it up like

The post-list tag is responsible for fetching the JSON from the server and building each blog post.

To test the page, you can host this on a *AMP server. Or if you have Python installed, you can run

python -m SimpleHTTPServer

And when you navigate to http://localhost:8000/  you should see

Screen Shot 2014-06-28 at 10.09.43 am

With a 404 on post-list.html.

Next, we will create a blog-post tag. This tag is responsible for rendering each blog post. post-list tag will use the blog-post tag to render each blog post. Kind of like a Collection and a Model, where the blog-post tag is the model.

Create a new file named blog-post.html at the root of the app folder. Open it up in your favorite editor and fill it up like

Here we style the component and reorder the markup to make the post more presentable.

Now, we will be building the post-list tag. Create a new file named post-list.html at the root of app folder. Open it up and fill it like

On line 33, we will be calling the post-service. And with that response, we will build the blog-post tag.

And finally our post-service tag. Create a new file named post-service.html at the root of app folder and fill it like

This component is a wrapper for core-ajax, which is responsible for firing an AJAX call to the URL specified on line 11. Once the response is in, we will pluck out only the required fields, escape/format the data and set it inside the posts variable, which will be used by post-list tag.

Save all the files and re-run the server and you should see the latest blog posts

Screen Shot 2014-06-28 at 10.38.19 am

Simple, easy and awesome!

If you see a CORS error for your blog, refer Troubleshooting section.

Setup PhoneGap

Now, we will create a PhoneGap project and integrate the app we built into it. CD  back to the dev folder and run

phonegap create theJackalofJavascriptApp

theJackalofJavascriptApp is the name of the app. This will scaffold a PhoneGap Build template. If you are facing any issues, refer the prerequisites section.

Open www/config.xml and update it with project specific details like

Do notice line 91. This is responsible for allowing the app to interact with the outside world. You can also use settings on line 94 or 95 or 96 to restrict the access of the app.

Next, delete the below folders/files present inside the www folder

  • css folder
  • img folder
  • js folder
  • spec
  • spec.html file
  • index.html file
  • icon.png file

Now, copy the contents of dev/app/ folder to www folder.  Once that is done, we will test the app. Back to terminal/prompt and cd  into the theJackalofJavascriptApp folder and run

cordova platforms add ios or  cordova platforms add android

This will add the respective platform support to your app. Next, we will build the respective platform. Run

cordova build ios or  cordova build android

Next, we will emulate the app. For ios run

cordova emulate ios

This will launch the iPhone simulator and will render the app. Something like Screen Shot 2014-06-28 at 11.30.50 am

And for Android, sometimes  cordova emulate android might not work. in that case, after the build you can open the project in ADT. Refer prerequisites.

When you run the project from ADT, on Android 4.2.2, you will see

Screen Shot 2014-06-28 at 11.39.20 am

And in the LogCat you can see

Screen Shot 2014-06-28 at 11.42.12 am

Uncaught ReferenceError: Window is not defined at file:///android_asset/www/components/platform/platform.js:13

I have raised this issue with the Polymer team here. I will update this post as they respond.

I have created another Android target with version 4.4.2 and the app seems to work fine

Screen Shot 2014-06-28 at 11.56.27 amYay!!

PhoneGap Build

Assuming that everything is fine, we will issue a PhoneGap build to generate a Native installer. We need a GitHub repo to dump code to. Then we will submit this repo to PhoneGap Build service to generate an Installer for us. Create a new repo and name it as per your blog name. I will be using theJackalofJavascriptApp as the name.

Now, copy the contents of myBlogsHybridApp/dev/theJackalofJavascriptApp/www to dist folder and cd  into it. From inside the dist folder run

git init

git add -A

git commit -am "initial commit"

git remote add origin https://github.com/arvindr21/theJackalofJavascriptApp.git

and finally

git push origin master

to push the code to the repo.

Next, we navigate to PhoneGap Build and submit the app repo.

Screen Shot 2014-06-28 at 11.59.27 amIt will take a couple of minutes for PhoneGap build to fetch the repo. Once it is done, you will see a “Ready to Build” button. That should trigger the service and your native installers should be ready in a giff.

Screen Shot 2014-06-28 at 12.11.40 pm

You can share the apk or publish it on App stores.

Yeoman Generator

To make lives easy for all of us, I have written a Yeoman Generator that will scaffold the above template. You can start modifying the template with your own components and look and feel.

To install the generator run

npm install -g yo generator-wchybridapp

and then run

yo wchybridapp

Once the app is scaffolded, you can follow the above steps.

Next Steps

This is just a getting started post on how to integrate Web Components with PhoneGap build and use a JSON service to build an awesome Hybrid app. The potential for JSON API is humongous. You can build awesome interfaces with Web Components and use JSON API to handle your blog data. You can also create Blog post, moderate comments etc from within your Hybrid app.

Welcome to the Future! 

Troubleshooting

  • If your blog redirects to the home page when you try to fetch the JSON using any of the endpoints, check your .htaccess file once again. If you are using Yoast WordPress SEO, make sure the below option is unchecked in the permalinks settings
    Screen Shot 2014-06-28 at 9.33.09 am
  • If you are facing a CORS issue while fetching the JSON data, you can edit the plugin and add  header("Access-Control-Allow-Origin: *"); to json-api/json-api.php. Not recommended but could not find another solution.

Thanks for reading! Do comment.
@arvindr21

Tweet about this on TwitterShare on LinkedIn3Share on Google+0Share on Reddit0Buffer this pageFlattr the authorEmail this to someonePrint this page
  • frank

    Hello is there a simple way to transform a wordpress website into a hybrid App?

  • http://www.mobilepundits.com/ Krishnayan Swami

    Your article provided me some useful tips that I’m excited to follow. but i had a doubt I have created a hybrid application in jQeury mobile with phonegap … the question is Can I publish it in Google playstore /Apple appstore like other native apps?

    • / Arvind Ravulavaru

      Hello Krishnayan, Sure you can. You can package your app and build it using https://build.phonegap.com. Then you can sign and distribute the app installers to app stores.

  • Siddhant Minocha

    There’s a problem. I’m trying to Emulate on Android version 4.4.2 but its not working. It gets stuck at the loading page.

    What could the problem be?

    • / Arvind Ravulavaru

      Is it working fine inside a browser?

      • Siddhant Minocha

        No! I tried to run it using SimpleHTTPServer (python). Its stuck at the “loading” page in the browser too!

        • / Arvind Ravulavaru
          • Siddhant Minocha

            I have checked. My website is sending correct JSON data. http://worldcup15.in/api/get_recent_posts

            ^ You can have a look. :)

          • / Arvind Ravulavaru

            Cool. Then can you open the dev tools and see if there is any script error in the console?

          • Siddhant Minocha

            This clue is going to help:

            127.0.0.1 – – [21/Dec/2014 22:34:33] code 404, message File not found
            127.0.0.1 – – [21/Dec/2014 22:34:33] “GET /WorldCup2015/dev/app/WorldCup15/www/components/platform/platform.js

          • / Arvind Ravulavaru

            Can you check the path for platform.js? This is used by polymer.

          • Siddhant Minocha

            How do I check that?

          • Siddhant Minocha

            Hi! I did everything again from the scratch.
            I uninstalled npm, nodejs, cordova and phonegap. Installed them again.
            and Its still not working even inside a browser.
            But the console shows no error now. Only the page is stuck at “Loading”

          • / Arvind Ravulavaru

            Can you clone this repo : https://github.com/arvindr21/myBlogsHybridApp and try.

          • Siddhant Minocha

            For some unknown reasons, its still not working on my browser.
            But now its working perfectly on an emulator. 😀 😀

          • / Arvind Ravulavaru

            Can you share a copy of your code? I can take a look.

          • Siddhant Minocha

            Which file’s code do you want?

  • Jordi

    The demo, don’t function!

    • / Arvind Ravulavaru

      Hi Jordi, please check my response to Lira. The issue is same. Thanks

  • Lira

    Hey first thanks for this nice tutorial! but i need help, i did exactly all of the steps but: Save all the files and re-run the server and you should see the latest blog posts. When i re-run and call index.html so i see only LOADING…. and not the posts. I used your URLS not my own Urls for test. Can u help?

    • / Arvind Ravulavaru

      Hello Lira, Thanks!

      And thanks for bringing this to my notice. Apparently there is something wrong with “something”. Instead of dispatching the JSON response, the plugin is dispatching a HTML.

      If you navigate to : /api/get_recent_posts You will see a HTM returned instead of a JSON. And this causes the parsing logic to break in Javascript, crashing the entire application.

      I have raised an issue here : https://wordpress.org/support/topic/urls-dispatch-html-instead-of-json?replies=1#post-6108542 Depending on the resolution, I will update this post/comment.

      Thanks.

      • JG

        Hi Arvind,

        Thanks for a great article,

        I thought id drop a comment to say how i got around the JSON plugin showing html,

        it seems the developer of the plugin is not going to provide a fix anytime soon,

        The way i got around it was by installing the wordpress jetpack plugin and using the wordpress public api it works great.

        Example API url:
        http://public-api.wordpress.com/rest/v1/sites/YOURSITEHERE/posts/?number=1&pretty=true

        Hope this can be of help,

        Jake.

        • / Arvind Ravulavaru

          Thanks JG!. Really appreciate the solution. I will try that out!

          • JG

            No problem if you have any issues drop me a comment :)

          • / Arvind Ravulavaru

            Too soon to ask (:D) but, I quickly tried : http://public-api.wordpress.com/rest/v1/sites/thejackalofjavascript.com/posts/?number=1&pretty=true and I get

            I have jetpack already installed. Any other plugin I need to Install or set permissions?

          • Jake Gladden

            Ah yes that happened to me disable and reconnect jetpack and you should be good to go,

            Jake.

          • / Arvind Ravulavaru

            Cool! Will check it out! Thanks again.

          • JG

            No problem my friend :),

            How can i contact you outside of here i have a couple of small questions,

            Jake.

          • / Arvind Ravulavaru

            You can hit me from the request link on top of this page.

  • C.k

    @arvindravulavaru:disqus
    why has not ios app of this demo?

  • Chris White

    Hey, thanks for the great tutorial but i have a quick question. I’ve set a custom field that has an iframe of a video player in wordpress and i’ve it set up to where its getting the html but when it renders the page, all you see is the html? Is there a way to databind html and display it where it gets rendered?

    • / Arvind Ravulavaru

      Hello @disqus_b9zXEG0nlE:disqus I have been looking for the same too. If you notice, I am doing this

      in post-service.html to remove unwanted characters.

      Pls. do let me know if you find the solution.

      Thanks.

  • jgcoroleu

    Hi, how i can to add a featured image to my posts?

  • Bruno Seixas

    Hey =)
    Again I am not sure where I could ask this so here it goes ;p

    I was looking for a way to make a phonegap mobile app run in background, as a service, so the users can receive live notifications. It seems that Phonegap does not support and the advice is to make a plugin for it.

    After some research I found this https://github.com/phpsa/cbsp
    Have you ever done something like this?

    • / Arvind Ravulavaru

      IMO, when the requirement gets out of PhoneGap’s hands, I would suggest scaffolding the app using PhoneGap/Cordova and then add an Android or iOS platform and distribute those installers after adding the background service to the app in the native language.

      Do let me know, if you see any issues with this approach.

      • Bruno Seixas

        As I consider myself a newbie in this particular area of dev I cant really judge if your approach has issues but it seems correct. I was able to dig a little bit more and there are some cool plugins (available in phonegap plugins page) but usually they are platform specific. It seems a hot topic and with a lot of “hows and dos”. One thing they have in particular, the plugin I mentioned.
        Let´s see how things move on =)

        Once again thanks for the help =)

        Ps: A working example. https://gist.github.com/teusinkorg/10649655

        • / Arvind Ravulavaru

          Cool. Thanks!

  • Bruno Seixas

    I have been looking from a distance to Web Components but it seems their popularity and community embrace is growing rapidly.