WordPress Hybrid Client: v1.3.0 released

WordPress Hybrid Client (WPHC) is an Open Source project available on GitHub.

You can refer to the online documentation to properly build your applications. A Computer science background is required but the explanations should be clear enough.

v1.3.0 ChangeLog

milestone

iOS / Android push notifications 100% free and self hosted for WordPress using Cordova and Ionic

Push notification is always a pain when it comes to find the perfect free service, there are several possibilities like pushwoosh, pushapps, pushover etc.

If you are hosting your WordPress website there is no need to subscribe any of those services. With your server you have already what it takes to send push notifications to your subscriber.

No third party service involved, just your WordPress server and your application.

It all start with installing Push Notifications for WordPress (Lite) plugin to your WordPress.

Send push notifications to iOS, Android, and Fire OS devices when you publish a new post. Straight from your WordPress site, in real-time.

Installation

  1. Search and install “Push Notifications for WordPress (Lite)” from the Plugins WordPress page
  2. Activate “Push Notifications for WordPress (Lite)” through the ‘Plugins’ menu in WordPress
  3. Configure the plugin by going to the Push Notifications menu that appears in your admin menu

Android

If you have not already done so, you’ll need to set up a Google API project, to generate your senderID. Follow these steps to do so.

Get the SenderID

Signing into https://developers.google.com/mobile/add and follow the steps to get Cloud messaging senderID and apiKey.

Tip: The senderID is a 12 digit number

Configure the WordPress plugin

Go to Push Notifications > Settings and check the following checkboxes:

  • Basic Options > Send push notifications when a new post is published
  • Basic Options > Android devices
  • Send Push Notifications for > Posts
  • Misc > In the Android notification payload add the message field

Then go to “Android Push Notifications (via GMC)” section and enter you Google Api key.

Do not forget to save.


iOS

Configure the WordPress plugin

Go to Push Notifications > Settings and check the following checkboxes:

  • Basic Options > Send push notifications when a new post is published
  • Basic Options > iOS devices
  • Send Push Notifications for > Posts

Do not forget to save.

Certificates and Provisioning profiles

This part is really painful (Generally when you have to use Apple’s service it is…). It is all well explained there: http://strangemilk.com/ionic-push-notifications-with-ios/

Create .pem

Get .perm files

Once you have got your .pem files upload them in the iOS Push Notifications section

Setup Ionic / Cordova

I recommend using NgCordova and the NgCordova pushNotifications plugin

Installation

cordova plugin add https://github.com/phonegap-build/PushPlugin.git

# Or if you are using Ionic CLI
ionic plugin add https://github.com/phonegap-build/PushPlugin.git

Register to “Push Notifications for WordPress (Lite)”

“Push Notifications for WordPress (Lite)” exposes a Web service API that you can access over HTTP.

It only takes the OS (iOS | Android) and the device token.

function register(os, token) {
        var baseUrl;
        baseUrl = 'http://yourDomainName.com/pnfw';
        if (!baseUrl) {
            return $q.reject();
        }
        return $http({
            method: 'POST',
            url: baseUrl + '/register',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            transformRequest: function(obj) {
                var p, str;
                str = [];
                for (p in obj) {
                    str.push(encodeURIComponent(p) + '=' + encodeURIComponent(obj[p]));
                }
                return str.join('&');
            },
            data: {
                os: os,
                token: token
            }
        });
    };

iOS

$cordovaPush.register(iosConfig).then(function(deviceToken) {
    register('iOS', deviceToken).success(function() {
        return $log.info('Push notif Token stored');
    });
    $log.debug('iOS push notification registration success', deviceToken);
}, function(err) {
    $log.error('iOS push notification registration error', err);
});

$rootScope.$on('$cordovaPush:notificationReceived', function(event, notification) {
    $log.debug('Push notif message', notification);
    if (notification.alert) {
        if (notification.foreground) { // If your user is using the app
            // Do something like opening the Post within the app
            // You have access to
            // notification.id which is the new Post ID
            // notification.alert which is the new Post Title
        } else { // If your user has clicked on the notification
            // Do something like opening the Post within the app
            // You have access to
            // notification.id which is the new Post ID
            // notification.alert which is the new Post Title
        }
    }
    if (notification.badge) {
        return $cordovaPush.setBadgeNumber(notification.badge).then(function(result) {
            $log.debug('Push notif badge ok', result);
        }, function(err) {
            $log.debug('Push notif badge error', err);
        });
    }
});

Android

$cordovaPush.register(androidConfig).then(function(result) {
    $log.debug('android push notification registration success', result);
}, function(err) {
    $log.error('android push notification registration error', err);
});
return $rootScope.$on('$cordovaPush:notificationReceived', function(event, notification) {
    switch (notification.event) {
        case 'registered':
            if (!notification.regid.length) {
                return;
            }
            $log.debug('registration ID', notification.regid);
            register('Android', notification.regid).success(function() {
                return $log.info('Push notif Token stored');
            });
            break;
        case 'message':
            $log.debug('Push notif message', notification);
            if (notification.foreground) { // If your user is using the app
                // Do something like opening the Post within the app
                // You have access to
                // notification.payload.id which is the new Post ID
                // notification.payload.message which is the new Post Title
            } else { // If your user has clicked on the notification
                // Do something like opening the Post within the app
                // You have access to
                // notification.payload.id which is the new Post ID
                // notification.payload.message which is the new Post Title
            }
            break;
        case 'error':
            $log.debug('Push notif error', notification);
            break;
    }
});

All in one

angular.module('yourModuleName').run(function($log, $cordovaPush, $rootScope, $http, $ionicPlatform) {
    var androidConfig, iosConfig, register;

    androidConfig = {
        "senderID": ""
    };
    iosConfig = {
        "badge": true,
        "sound": true,
        "alert": true
    };

    register = function(os, token) {
        var baseUrl;
        baseUrl = 'http://yourDomainName.com/pnfw';
        if (!baseUrl) {
            return $q.reject();
        }
        return $http({
            method: 'POST',
            url: baseUrl + '/register',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            transformRequest: function(obj) {
                var p, str;
                str = [];
                for (p in obj) {
                    str.push(encodeURIComponent(p) + '=' + encodeURIComponent(obj[p]));
                }
                return str.join('&');
            },
            data: {
                os: os,
                token: token
            }
        });
    };
    return $ionicPlatform.ready(function() {
        if (ionic.Platform.isAndroid()) {
            $cordovaPush.register(androidConfig).then(function(result) {
                $log.debug('android push notification registration success', result);
            }, function(err) {
                $log.error('android push notification registration error', err);
            });
            return $rootScope.$on('$cordovaPush:notificationReceived', function(event, notification) {
                switch (notification.event) {
                    case 'registered':
                        if (!notification.regid.length) {
                            return;
                        }
                        $log.debug('registration ID', notification.regid);
                        register('Android', notification.regid).success(function() {
                            return $log.info('Push notif Token stored');
                        });
                        break;
                    case 'message':
                        $log.debug('Push notif message', notification);
                        if (notification.foreground) { // If your user is using the app
                            // Do something like opening the Post within the app
                            // You have access to
                            // notification.payload.id which is the new Post ID
                            // notification.payload.message which is the new Post Title
                        } else { // If your user has clicked on the notification
                            // Do something like opening the Post within the app
                            // You have access to
                            // notification.payload.id which is the new Post ID
                            // notification.payload.message which is the new Post Title
                        }
                        break;
                    case 'error':
                        $log.debug('Push notif error', notification);
                        break;
                }
            });
        } else if (ionic.Platform.isIOS()) {
            $cordovaPush.register(iosConfig).then(function(deviceToken) {
                register('iOS', deviceToken).success(function() {
                    return $log.info('Push notif Token stored');
                });
                $log.debug('iOS push notification registration success', deviceToken);
            }, function(err) {
                $log.error('iOS push notification registration error', err);
            });
            return $rootScope.$on('$cordovaPush:notificationReceived', function(event, notification) {
                $log.debug('Push notif message', notification);
                if (notification.alert) {
                    if (notification.foreground) { // If your user is using the app
                        // Do something like opening the Post within the app
                        // You have access to
                        // notification.id which is the new Post ID
                        // notification.alert which is the new Post Title
                    } else { // If your user has clicked on the notification
                        // Do something like opening the Post within the app
                        // You have access to
                        // notification.id which is the new Post ID
                        // notification.alert which is the new Post Title
                    }
                }
                if (notification.badge) {
                    return $cordovaPush.setBadgeNumber(notification.badge).then(function(result) {
                        $log.debug('Push notif badge ok', result);
                    }, function(err) {
                        $log.debug('Push notif badge error', err);
                    });
                }
            });
        }
    }, false);
});

WordPress Hybrid Client

If you want your WordPress website available on iOS and Android there is a simple free and Open Sourced solution: WordPress Hybrid Client

With WPHC (WordPress Hybrid Client), your WordPress website application (iOS and Android) is just a build away.

Here is the features already available and a lot more is coming:

  1. Push Notifications
  2. Social buttons
  3. About Page
  4. Params Page
  5. Language switch [French|English|Chinese]
  6. Accessibility (Post font size)
  7. App rate
  8. Docker support for easier installation
  9. Syntax highlighter for tech blogs

MISC: Test Push Notifications on Android

If you want to test that GMC is correctly setup and that your device receive notifications you can follow this tutorial: Sending push notifications to Android via Gulp

WordPress Hybrid Client: v1.2.0 released

WordPress Hybrid Client (WPHC) is an Open Source project available on GitHub.

With WPHC you will be able to generate iOS and Android applications in a blink of an eye. Before anything you will need to install WP-API plugin which basically will turn your Website into a REST API.

Then you can refer to the documentation to properly build your applications. A Computer science background is required but the explanations should be clear enough.

v1.2.0 ChangeLog

milestone

WordPress Hybrid Client: v1.1.0 released

WordPress Hybrid Client (WPHC) is an Open Source project available on GitHub.

With WPHC you will be able to generate iOS and Android applications in a blink of an eye. Before anything you will need to install WP-API plugin which basically will turn your Website into a REST API.

Then you can refer to the documentation to properly build your applications. A Computer science background is required but the explanations should be clear enough.

v1.1.0 ChangeLog

milestone

WordPress Hybrid Client: Create free iOS/Android mobile applications for WordPress

After more than 100 commits, I am happy to announce the release of my latest Open Source project WordPress Hybrid Client available on GitHub.

With WPHC you will be able to generate iOS and Android applications in a blink of an eye. Before anything you will need to install WP-API plugin which basically will turn your Website into a REST API.

Then you can refer to the documentation to properly build your applications. A Computer science background is required but the explanations should be clear enough.

I first created this project for my blog app that is now available on Android and iOS (approval still pending). Go check it out, it speaks for itself!

As it is an Open Source project, any help is welcome, I have created issues and milestones to help people get a clear understanding on where the project is heading.

If you have any questions please ask on the comments.

Creating an hybrid app in minutes with Ionic Framework

Creating hybrid apps with Ionic is really fast and powerful. I have gather a year of information to create an ultimate presentation of Ionic in a airpair blog post: A year using Ionic to build hybrid applications

If you only want a summary of what’s inside this post you can check out the below presentation. It contains all you need to know to create, build and package an hybrid app with Ionic!

[iframely]http://www.slideshare.net/julienrenaux/hybrid-apps-withionic[/iframely]

Some quick tips:

  • Develop in the browser with live reload: ionic serve
  • Add a platform (ios or Android): ionic platform add ios [android] Note: iOS development requires OS X currently
  • Build your app: ionic build
  • Simulate your app: ionic emulate
  • Run your app on a device: ionic run
  • Package an app using Ionic package service: ionic package

AngularJs 1.x Open Source projects to follow in 2015

Ionic Framework

ionic

Ionic needs no introduction, it is a HTML5 Mobile Framework for building, cross-platform hybrid native apps with HTML, JavaScript, and CSS.

In 2014 Ionic became one of the top 50 most popular open source projects in the world, with over 12,000 stars on GitHub and over 50,000 new apps were created using Ionic Framework.

2015 will be an important year for Ionic as they will slowly move from a simple HTML5 hybrid framework to a whole galaxy of tools to create hybrid apps. The npm ionic package is already available with features such as building cordova apps or creating splashscreens and icons for IOS and Android.

Developers to follow:


Angular Material Design

Material Design is a Google specification for a unified system of visual, motion, and interaction design that adapts across different devices.

angular/material is a lean, lightweight set of AngularJS-native UI elements that implement the material design specification for use in Angular single-page applications (SPAs). This is the official AngularJs Material Design library.

No doubt that 2015 will be the year of Material Design, it is already everywhere from Android to Polymer. I have a lot of expectations for this library that I already use in my current company. Unfortunately a lot of features are missing (menu, dropdown menu, select, multi-select etc.) and the development pace is not high enough to reach the planning explained at the end of this video:

Go Google go!

Developers to follow:


lumX Material Design

lumx

Material Design is a Google specification for a unified system of visual, motion, and interaction design that adapts across different devices.

LumX will help you to design beautiful applications, faster and easier, respecting Material Design specification in a pixel perfect way.

In a lot of aspects this set of directives is more advanced than the official Angular Material Design repository. I really hope this project will have the attention it deserves. A downside of it though is that it depends on jQuery..

Developers to follow:


Foundation for Apps

foundation_apps

Foundation for Apps is an Angular-powered framework for building powerful responsive web apps. With this project the Zurb foundation is clearly trying to compete with Ionic Framework. There is still a lot of work to do but it sounds really promissing!

Developers to follow:


Angular Hint – Runtime hinting for AngularJS

Whether you start a new project or want to have feedbacks on an existing Angular app, this project is for you. It basically tells you if you follow AngularJs’s standards or not.

If you do not want to add this project to your development dependencies you can use a Chrome plugin that includes it.

If you also wants to follow AngularJs’s best practice I suggest you to read John Papa’s angularjs-styleguide. There are a lot of great advices in there and I personally always go through it before starting a new project. Some are explained in this video:

Developers to follow:


Angular-google-maps

angular-google-map

Angular-google-maps is a set of directives for the Google Maps JavaScript API. It is part of the great Angular UI organization. This repository changed a lot in Q4 2014 and released 2.x versions that is really popular lately.

Developers to follow:


Ng-Annotate

If you are familiar with AngularJs and it’s concept of Dependency Injection (DI), you know that it can be really annoying to use when minifying your code:

Minification KO

angular.module('ngAppStrictDemo', [])
// BadController will fail to instantiate, due to relying on automatic function annotation,
// rather than an explicit annotation
.controller('BadController', function($scope) {
  $scope.a = 1;
  $scope.b = 2;
})

Minification OK

angular.module('ngAppStrictDemo', [])
// Unlike BadController, GoodController will not fail to be instantiated,
// due to using explicit annotations using the array style.
.controller('GoodController', ['$scope', function($scope) {
  $scope.a = 1;
  $scope.b = 2;
}])

angular.module('ngAppStrictDemo', [])
// Unlike BadController, GoodController2 will not fail to be instantiated,
// due to using the $inject property.
.controller('GoodController2', GoodController2);
function GoodController2($scope) {
  $scope.name = "World";
}
GoodController2.$inject = ['$scope'];

Before AngularJs 1.3 it was difficult to know if you code was production ready (minifiable) or not. To tackle this very problematic AngularJs 1.3 introduced the ngStrictDi directive which tells you if your code is production ready or not.

Ng-Annotate basically makes the “Minification KO” example a production ready code! You do not have to worry about the $inject property or the array style anymore. This project literally changed my life, with it I was able to remove all the duplicate service injection ['$scope', function($scope) and the $inject property GoodController2.$inject that I used before.

Developers to follow:

Ionic Framework features you may have missed

Ionic Framework is one of the best framework for developing hybrid mobile apps with HTML5. Based on AngularJS the set of available features is tremendous. This post presents, with examples, some of the best hidden features provided.

Scroll

Scroll documentation

Infinite Scroll

The ionInfiniteScroll directive allows you to call a function whenever the user gets to the bottom of the page or near the bottom of the page.

[codepen_embed height=”268″ theme_id=”5820″ slug_hash=”jukJh” default_tab=”result” user=”shprink”]See the Pen Infinite Scroll: 1.0.0-beta.14 by Julien Renaux (@shprink) on CodePen.[/codepen_embed]

List

List documentation

Collection repeat

The collection-repeat directive is a directive that allows you to render lists with thousands of items in them, and experience little to no performance penalty.

[codepen_embed height=”268″ theme_id=”5820″ slug_hash=”HoIDJ” default_tab=”result” user=”shprink”]See the Pen collection-repeat: 1.0.0-beta.14 by Julien Renaux (@shprink) on CodePen.[/codepen_embed]

Gesture

$ionicGesture documentation

Events

The gesture service has only two methods, on adds an event listener for an DOM element and off removes it. While AngularJS ngTouch provides only three touch events (ngClick, ngSwipeLeft and ngSwipeRight) $ionicGesture provides dozens (hold, tap, doubletap, drag, dragstart etc.).

[codepen_embed height=”268″ theme_id=”5820″ slug_hash=”txliu” default_tab=”result” user=”shprink”]See the Pen Ionic $ionicGesture example: 1.0.0-beta.14 by Julien Renaux (@shprink) on CodePen.[/codepen_embed]

Dom manipulation

DomUtil documentation

If you are accustomed to AngularJS I am sure that you experienced some difficulties when manipulating the DOM. JQlite helps but is itself very limited. Ionic provides some methods to help you deal with it.

ionic.DomUtil.ready

Call a function when the DOM is ready, or if it is already ready call the function immediately.

[codepen_embed height=”268″ theme_id=”5820″ slug_hash=”BxufK” default_tab=”result” user=”shprink”]See the Pen ionic.DomUtil.ready Example by Julien Renaux (@shprink) on CodePen.[/codepen_embed]

ionic.DomUtil.getParentWithClass

Returns the closest parent of element matching the className, or null.

[codepen_embed height=”268″ theme_id=”5820″ slug_hash=”lDrpb” default_tab=”result” user=”shprink”]See the Pen ionic.DomUtil.getParentWithClass Example: 1.0.0-beta.14 by Julien Renaux (@shprink) on CodePen.[/codepen_embed]

Utilities

ionic.throttle

Only call a function once in the given interval. In this example the function should be called half as many as we tried.

[codepen_embed height=”268″ theme_id=”5820″ slug_hash=”iefAE” default_tab=”result” user=”shprink”]See the Pen Ionic Throttle example: 1.0.0-beta.14 by Julien Renaux (@shprink) on CodePen.[/codepen_embed]

ionic.debounce

Only call a function once in the given interval, the timer is reset on every call. In this example the function should never be called.

[codepen_embed height=”268″ theme_id=”5820″ slug_hash=”yzrsD” default_tab=”result” user=”shprink”]See the Pen Ionic Debounce example: 1.0.0-beta.14 by Julien Renaux (@shprink) on CodePen.[/codepen_embed]

ionic.Utils.arrayMove

Really useful function that manipulates array items position.

[codepen_embed height=”268″ theme_id=”5820″ slug_hash=”HghBw” default_tab=”result” user=”shprink”]See the Pen Ionic arrayMove example: 1.0.0-beta.14 by Julien Renaux (@shprink) on CodePen.[/codepen_embed]

Tabs

Starting from ionic beta.14 we can select the position of the tabs through configuration.

Tabs top

.config(function($ionicConfigProvider){
    $ionicConfigProvider.tabs.position('top');
})

[codepen_embed height=”268″ theme_id=”5820″ slug_hash=”qlECF” default_tab=”result” user=”shprink”]See the Pen Tabs Top: 1.0.0-beta.14 by Julien Renaux (@shprink) on CodePen.[/codepen_embed]

Tabs bottom

.config(function($ionicConfigProvider){
    $ionicConfigProvider.tabs.position('bottom');
})

[codepen_embed height=”268″ theme_id=”5820″ slug_hash=”emXyjV” default_tab=”result” user=”shprink”]See the Pen Tabs bottom: 1.0.0-beta.14 by Julien Renaux (@shprink) on CodePen.[/codepen_embed]

Delegation

Delegation allow you to have several instances of the same component within the same view. You have this capability on ion-side-menus, ion-tabs,ion-scroll ion-content, ion-list and ion-slide-box using the delegate-handle directive attribute.

[codepen_embed height=”268″ theme_id=”5820″ slug_hash=”CsBhf” default_tab=”result” user=”shprink”]See the Pen Ionic Side Menu delegation: 1.0.0-beta.14 by Julien Renaux (@shprink) on CodePen.[/codepen_embed]