Bring Your WordPress to Your Android App Using the WordPress REST API and WebViews

Audric Steibel
9 min readJul 8, 2020

--

I recently had to work with the WordPress API, in order to bring our blog into our Android app. This article describes some of the work I’ve done, how I’ve used both the WordPress API and WebViews to provide our users with an optimal experience. It’s meant to help other developers having to work with the WordPress API to integrate a blog into a mobile app, in a way that feels the most native possible.

Some context

The company I’m working at has a website and an app for both Android and iOS. Both platforms (web and mobile) have a very similar set of features, with a few exceptions. One of those exceptions is what we call the “Advice Section”, which consists of a series of articles with different contents (texts, images, and videos). Due to the complexity of the data and the lack of API at the time, we decided to not have it in our app.

Recently though, we switched this section of our website to a WordPress, in order to give more flexibility and autonomy to our Content Team. WordPress comes with a REST API, so we decided to have a look and see if it was possible to easily add this section to our apps as well.

Here’s what this section looks like in our website:

The Hosco website and its Advice Section

You can see we have a list of articles split between 4 categories, and a search feature. Clicking on an article will open it, and the user can read the content. We decided to have something similar in the app: articles, search, and categories. Other WordPress features such as comments were not included in our scope for the mobile apps.

So let’s dive into the WordPress API and let’s get coding!

Let’s get coding!

The WordPress API

The WordPress REST API is documented here: https://developer.wordpress.org/rest-api/reference/. I recommend reading it first, before deciding whether or not to implement it in your app.

All the data we needed for what was in our scope was data accessible publicly in the API, so there’s no need for authentication. You can directly check some of your data with the following:

Here’s the request using the WordPress demo project:

curl “https://demo.wp-api.org/wp-json/wp/v2/posts"

Calling this endpoint will give you the list of articles published on your WordPress. The list is paginated, so use the page query parameter to implement an infinite loading in your RecyclerView. You can choose the number of articles per page with the per_page query parameter. By default, the API sends 10 articles per query.

Data

You can see in the result that you get several useful information to display in your list:

  • the title of the article
  • the publication date
  • the excerpt
  • the content of the article…
A first look at our data

2 important things are missing though: the cover picture of your article and the name of the author.

Getting the cover picture is quite simple: you simply need to add the query parameter _embed. With this set, you will receive the _embedded data, including the featured_media (in which you’ll get the URL of your cover image), but also information on the terms in your taxonomy. For example, if you have category as a taxonomy, you can get the name of the category of your article from the _embedded data and display it in the app.

Regarding the author, it’s another story. You’ll see there’s an author block in the _embedded data, but there’s an error:

Trying to get information about the author is not possible

This appears to be due to a security layer in the API, blocking the User endpoint from public access. In my case, we decided not to display the name of the author. But in case you want to have it in your app, there are several solutions. This article can shed some light on the matter: https://wordpress.stackexchange.com/questions/261319/wp-api-v2-returning-invalid-user-id

One solution, if you have the resources to do so, is to simply extend the WordPress API, to have it return just the name of the author. More information on this topic can be found here: https://tech.hosco.com/wordpress-really/

Search

Going back to the posts endpoint, you can perform different types of searches. For example, if you want to search for a keyword, you can use the parameter keyword, in which you put the string with which to perform the search.

curl “https://demo.wp-api.org/wp-json/wp/v2/posts?search=test"

Categories

You can also search for articles matching one of your categories. You can use the parameter categories, in which you put the ID of the category. To know the ID of your categories, you’ll first need to retrieve the list of categories from the WordPress API.

You can use the endpoint /categories for this.

curl “https://demo.wp-api.org/wp-json/wp/v2/categories"

Here’s the result in the demo project of WordPress:

The demo project has 3 categories

Using what we just acquired, we can now filter for a category. For example, to get all the articles in the category Aut architecto nihil, you’ll need the following request:

curl “https://demo.wp-api.org/wp-json/wp/v2/posts?_embed&categories=2"

Single article

Finally, you can load the data of a single article by using the query parameter slug in the posts endpoint.

curl “https://demo.wp-api.org/wp-json/wp/v2/posts?_embed&slug=odio-labore-qui-ipsam-omnis"

I recommend also using the _embed parameter to be sure you have access to the data you need.

With this in place, you can now easily load all your articles, perform searches with a keyword, and look at specific categories.

This article being focused on WordPress and its API, and loading content in a WebView, I’m not going to explain how to make HTTP calls in an app or show content in a recycler view, I’m assuming you know this if you’re reading this article. If not, there are plenty of good articles about those topics out there.

Here’s what that first part looks like for me:

Details of an article: WebView

You now have a list of articles, but you need to display the article itself. As mentioned before, the content of the article is in content > rendered. It gives you the HTML content of the article, which you can inject into a WebView. It seems easy in theory, but I’ve run into a series of issues, which you may experience as well.

Plugins

Our WordPress uses the plugin ElegantTheme. This causes the HTML to have elements which are used by this plugin:

[et_pb_section fb_built=”1″ _builder_version=”4.4.8″ link_option_url_new_window=”on”][et_pb_row _builder_version=”4.4.8″ background_size=”initial” background_position=”top_left” background_repeat=”repeat” link_option_url_new_window=”on”]…

Because they are in the HTML, they’re inside the WebView. In my case, it completely broke it. So I’ve had to remove manually those elements from the HTML before displaying it in the WebView.

All of those elements start with [et_pb_ or [\et_pb_, so you can use a regular expression to find all those elements and remove them.

I’ve run into another problem with this plugin though: some images of the articles are added via the plugin and are inside those elements. For example:

[et_pb_image src="url_of_the_image" alt="alt" title_text="title" _builder_version="4.4.8"][/et_pb_image]

Images are added in HTML via <img /> elements, so we need to update the regex to do the following:

  • find all images in the plugin
  • find the src inside the image
  • replace it with an img, with the src attribute.

In the end, my regex ended up looking like this:

My Utils.getStringFromHtml function is a function that returns text based on the HTML, it’s relying on Html.fromHtml().

Images

Another issue I encountered had to do with images. Some images didn’t have set sizes, and the default size was not adapted for mobile screens, resulting in huge images going out of the screen. To fix this, I’ve had to manually modify the img elements in the HMTL and specify their width to be 100%, so they would take the width of the screen of the device.

This needs to be done only if the width is not already set though, as some images do have a set size. I’ve done the same work for videos as well, on iframe elements.

In order to easily parse the HTML and manipulate its elements, I’ve used the Jsoup library.

In your gradle file:

implementation 'org.jsoup:jsoup:1.11.1'

You can now do the following:

Fullscreen videos

If you have videos inside your HTML, they should appear inside your WebView and play without problems. They can be shown in full screen, if the iframe element has been properly set (with allowfullscreen). However, to make the functionality work, you’ll have to do some work.

You need to give a custom WebChromeClient to your WebView, one that overrides the methods onShowCustomView and onHideCustomView, which are called when the fullscreen mode is shown and hidden.

In onShowCustomView, hide the content of your screen, and add the supplied view (corresponding to your video) to the parent element in your XML. In onHideCustomView, remove the view of the video from the parent and show the content again.

Your XML will look like something like this:

The custom WebChromeClient is :

This can be built upon to provide more features to your videos. For example, you may want to force the screen to rotate to landscape when the video is in fullscreen. You can play around with those 2 functions to achieve this result.

CSS

Once the HTML is loaded into the WebView, you might want to apply some styling to it, to provide your users with a better experience. To do so, I’ve found this useful piece of code on StackOverflow

In order to inject some CSS in your WebView, you can first create a CSS file, and save it in your assets folder. Then, when your page has finished loading, which you’ll know by overriding the onPageFinished method in your WebViewClient, you can modify the page to add the CSS to it:

You might experience a bit of a jump in the page, so you could improve it by showing the WebView only once the CSS has been injected.

Links

If you have links in your articles, they should automatically load if you click on them. By default, everything will load in your WebView. This might be something you want, but you may want another option.

In my case, I had 2 different scenarios:

  • links pointing to other parts of our platform (other articles, or something from another non-advice-related feature)
  • external links

We chose to redirect the first type of links to the appropriate page in the app, and the second to a web browser, in order to make it more understandable to the user that they left our app.

To do so, you can simply override the shouldOverrideUrlLoading method in your WebViewClient, and put the redirection logic there:

Putting everything together

We now have all the elements we need to display our article into a WebView, and handle most of the things we need to handle. The complete code for the loading of the content in the WebView is:

putting everything together

Here’s the final look of the page of an article. As you can see, it looks like it could be a part of the app, and not something loaded in a WebView.

Conclusion

At the end of all of this, we managed to add our WordPress into our app, using the WordPress REST API, and a simple WebView. As you saw, the experience for the user is pretty good, as it looks like we’re still in the app and that there’s no WebView. I’m quite happy with the end results!

Also, even though I encountered a bit of struggle at times (particularly with the videos, and with the HTML parsing), I think the end result is fairly “simple”. It was definitely worth the effort to try to implement the WordPress API and add our Advice Section to the app.

I hope this article was useful for you, and that it helped you in your journey to bring your WordPress to your app!

Thanks for reading!

--

--

Audric Steibel

Product Manager, previously Mobile Developer. Interested in building great products and providing users with a fantastic user experience.