Tuesday, July 12, 2016

Single Page Apps Using AngularJS and the WordPress REST API

Automattic and the WordPress community are working on integrating the WordPress REST API plugin into the WP core, which means that the API will be available without the actual plugin, and we could see more of WordPress integration with front-end JavaScript frameworks.

This would allow a faster time to market for applications, since some basic functionality that is often implemented from scratch in JavaScript apps is already implemented; we could use WordPress' user management, WooCommerce for product handling, static pages, and the list goes on! It is also possible to add custom endpoints to the API.

One way to use this API would be to include a front-end JS framework as part of a WordPress theme. This can be inconvenient, though, as it enforces a non-standard directory structure and is generally not a best-practice use of either the framework or the WordPress theme.

A better solution is to use a REST API to expose WP data and make two apps that are completely structurally separated, but connected with a "session sharing" technique, in order to use the best from both.

In this tutorial, I will show you how to do this "session sharing", where WordPress is used for user management and login, and on the client-side, an Angular app that allows easy, SPA-like (Single Page Application) post editing for authorized users.

You can find the code for the WordPress child theme and the Angular client app on GitHub:

Requirements

Before starting this tutorial, it is recommended that you already have some experience with the following:

Additionally, we will be using:

  • Vagrant (two virtual machines, one for WP and the other for running the Angular app on a grunt server)
  • Yeoman (to scaffold our Angular app)
  • Grunt

as development tools, but you should be also fine if you use some other way to run your local WP site and other or no scaffolding tool.

A WordPress REST API

In order to achieve our goal architecture, we have to install the WordPress REST API plugin, which is currently in it's beta phase and there are things to consider, see here.

The official recommendation is not to use version 2 in production, as the latest stable version is version 1. Also, the rumor is that the plugin will never get a stable version, but instead when the plugin is ready to move out of beta, it will be released as part of the WordPress core. In this tutorial we will use the version 2 plugin nonetheless.

Authentication

There are several authentication methods that can be used to secure the REST API (see here for details), but let's take a brief look at the pros and cons of each:

Basic Authentication

This is the most basic authentication type, where we would send the username and password in the header with every request. It requires SSL, as otherwise we would open the username and password to attack. Also, we are giving the Client ID and secret to the client.

Cookie Authentication

The standard, built-in wordpress login system also works. The trouble with this approach is that in order to avoid CSRF issues, we have to use it on the inside of WP. Since we need to access the API from outside, from another app, this approach is not for us.

OAuth Authentication

We are going to be using a non-standard way of implementing OAuth here. We will not let the user authorize an application explicitly, but instead we will seamlessly hook into the WordPress login function, authorize our Angular app for the user and retrieve an access token, which we forward to the JS app in order to authorize the API requests.

It's very important to mention that, even with this approach, we need SSL. Since this is an educational tutorial we will not be introducing the complexity of SSL even though, regarding the code itself, there would be no difference with or without SSL.

This approach should be preferred over basic auth, since we do not have to store the username and password of the user in the browser or give the Client ID and Secret to the user. The OAuth approach is only possible with a plugin, and for this reason we are going to use WP OAuth Server.

Sharing the Token

After we generate the token upon logging in to WP, we need to somehow share it with our JS app. There are multiple ways to do this, depending on your needs and personal preferences. In this tutorial we will describe two of these approaches. It's worth mentioning that both of these approaches might be constrained by browser version.

Setting Wildcard Domain Cookie

The first option, which is possible only if both apps are on same subdomain, is to set a wildcard cookie and then use that cookie on Angular side. If using this approach, it's important to take care of your local hosts file, in order to have the same subdomain.

I personally use Vagrant and Vagrant host manager, and then set the hostname of the WordPress VM to sitepoint.local and the other Vagrant VM's hostname to app.sitepoint.local. This will automatically edit your hosts file like this:

192.168.33.16  app.sitepoint.local  # VAGRANT: 297067a67f66f631aa1962e3b49ab73c (default) / cc52bb5a-3972-4b55-8e0c-0c805b9c6f1c
192.168.33.15  sitepoint.local  # VAGRANT: 6a5b8c757547fe9f0a32a0c747a91a79 (default) / b08c3e7d-cba8-4130-a11b-b26494574280

This is the approach we will use in this tutorial, but if you feel that this is an additional complication for you, consider the iframe option.

Posting to localStorage via iframe

This approach is better for someone who wants to avoid handling cookies and/or does not have the WP app and Angular app on same sub-domains. We expose an iframe from the SPA to WP and then we post a message to the iframe, inside which there is a listener waiting for incoming messages to take the access token and store it in the JS app's localStorage, for later use. I will explain the modifications needed in a separate section at the end of the article. See here for browser compatibility.

The Server

First we are going to create a template for the login screen containing the code to generate the access token. Then, we will hook into some login/logout functions in order to handle the cookie (or iframe, if you go with that option).

Create the server VM

Time to grease some elbows! I like starting out a WordPress project by cloning the Scotchbox Vagrantfile .

Open your favorite terminal application and navigate to the folder where you wish to keep the project. In my case this is /boxes. Then, clone the Scotchbox repo and navigate inside.

cd /boxes
git clone http://ift.tt/1uFOPMK sitepoint-wp-rest-api
cd sitepoint-wp-rest-api

# remove .git folder in order not to get confused if you later initialise your own repository
rm -rf .git

# Initialise a vagrant machine
vagrant up

At this point, you may want to open the sitepoint-wp-rest-api folder in your favorite IDE or text editor, since we need to edit the Vagrantfile.

This is how the Vagrantfile looks by default when cloned:

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|

    config.vm.box = "scotch/box"
    config.vm.network "private_network", ip: "192.168.33.10"
    config.vm.hostname = "scotchbox"
    config.vm.synced_folder ".", "/var/www", :mount_options => ["dmode=777", "fmode=666"]

    # Optional NFS. Make sure to remove other synced_folder line too
    #config.vm.synced_folder ".", "/var/www", :nfs => { :mount_options => ["dmode=777","fmode=666"] }

end

There are two thing to take care of here:

  1. Change the IP
  2. Change the hostname

In case you already have a network device or another VM running on 192.168.33.10, make sure to change that. You can choose any IP address as long as it's in the private address space.

If you want to use the approach with sub-domain cookie, it is also important to change the hostname to a FQDN.

Optional: You can also increase the RAM/CPU of the VM. This can be especially handy later for the second VM ,when we will need to run bash npm install - it will take less time if we increase the performance of the VM. Check the commented-out part at the end of the code snippet for how to achieve this. Although it's sometimes good to see how the system runs on 512MB RAM and 1 CPU (Vagrant's default), for development purposes we want it to be fast. Later when testing/optimizing speed of the WP site, you can tune this down again.

The final Vagrantfile looks like this

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|

    config.vm.box = "scotch/box"
    config.vm.network "private_network", ip: "172.31.255.254"
    config.vm.hostname = "sitepoint-wp-rest-api.test"
    config.vm.synced_folder ".", "/var/www", :mount_options => ["dmode=777", "fmode=666"]

    # Optional NFS. Make sure to remove other synced_folder line too
    #config.vm.synced_folder ".", "/var/www", :nfs => { :mount_options => ["dmode=777","fmode=666"] }

    # Optional performance tweaking
    #config.vm.provider "virtualbox" do |v|
    #   v.memory = 2048
    #   v.cpus = 2
    #end
end

One last step before we turn on the VM: the vagrant-hostupdater plugin install. What this plugin does is, when you run vagrant up, it updates your local hosts file with the IP and hostname given in the Vagrantfile, you will see what that means in a few moments.

# Install Vagrant host udpater plugin
vagrant plugin install vagrant-hostsupdater

Now it's time to boot up the machine:

vagrant up

You may get asked for the sudo password since vagrant-hostupdater will be editing the /etc/hosts file, which requires admin permissions.

This will take a minute (or a few minutes!) depending on whether you already have the scotch/box image locally - it has to be downloaded first if you do not.

Now, visit http://172.31.255.254/ and you should see the Scotchbox information page (what you actually see is the index.php located in the public folder of the cloned Scotchbox repository).

The result of what the hostupdater plugin did can be seen if you visit http://ift.tt/28YusYP - it's still the same page. Sitepoint-wp-rest-api.test resolves to 172.31.255.254 via your local hosts file. From now on we will use this FQDN to access our REST API.

Install WordPress

Now that we have a server running, it's time to install WordPress. Go into your local user's folder and download WordPress. Unpack it, create a configuration file and then copy raw files to the public folder inside of sitepoint-wp-rest-api.

cd ~
curl -OL http://ift.tt/zUVk1t
tar xzvf latest.tar.gz
cd ~/wordpress
cp wp-config-sample.php wp-config.php

# Do not forget to change /boxes to the actual folder onb *your* system
sudo rsync -avP ~/wordpress/ /boxes/sitepoint-wp-rest-api/public

Now, head back to your IDE and open wp-config.php. Fill in the DB credentials as found here. Additionally, it is a good practice to add WP_HOME and WP_SITEURL variables in the configuration files. They will override the values from the database, making it easier for versioning and changing between environments/hosts.

// wp-config.php

/** The name of the database for WordPress */
define('DB_NAME', 'scotchbox');

/** MySQL database username */
define('DB_USER', 'root');

/** MySQL database password */
define('DB_PASSWORD', 'root');

/** This is new, WP SiteURL and Home globals override */
define('WP_SITEURL', 'http://ift.tt/28YusYP');
define('WP_HOME', WP_SITEURL);

Change these values, and save the file.

Visit http://ift.tt/28YusYP again, and this time you should see a WordPress install wizard.

WordPress install - step 2

Click next a few times and finally you should see a default WP site with the twentysixteen theme running.

Install the REST API plugin

Head to the WordPress REST API plugin page and download the plugin. Unzip the downloaded file and copy it to wp-content/plugins/. Go to http://ift.tt/28YuEXW, click Plugins on the left menu, find WordPress REST API and activate it. No additional configuration or setup is needed for the API - it just works!

Now, if you visit http://ift.tt/28ZaXeK you should get a JSON array containing all the posts:

Continue reading %Single Page Apps Using AngularJS and the WordPress REST API%


by Almir Bijedic via SitePoint

Simple Background Parallax Scrolling in JavaScript

A tutorial about creating simple background parallax scrolling in JavaScript.


by via jQuery-Plugins.net RSS Feed

Getting Started with React, GraphQL and Relay (Part 2 of 2)

This article is part of a web development series from Microsoft. Thank you for supporting the partners who make SitePoint possible.

Introduction

The previous article explored the overall development process of working with Relay as well as the conversion of a GraphQL server. With the backend prepared, the second half of a React/GraphQL/Relay application is to consume it with the React-Relay web browser application. Consuming GraphQL services with React via Relay is tricky to setup. The technology is quite new, and therefore the number of examples, the clarity of the documentation, as well as a number of technical challenges (not bugs) have to be smoothed over. The example reviewed here will be a full blown CRUD (Create, Read, Update, and Delete) application. In addition to querying data, there will be an example of three kinds of mutations which will be helpful to new Relay developers because online examples of mutations are, at the time of this writing, few and far between.

Widget Tool Application

This simple application allows the user to manage a table of widgets. Widgets can be added, removed, and updated. The application does not use any kind of view routing which results in the Widget table being replaced with another view. Instead, it’s a simplistic version of an editable grid. For each widget the following information is collected:

  1. Name
  2. Description
  3. Color
  4. Size
  5. Quantity
  6. Owner

The drop-down list for the owner is populated from a distinct list of all owners who currently own widgets.

React and Relay

Relay applications are nothing more than React components wrapped in Relay Containers. The Relay Containers describe the data needed by the components, and Relay Root Containers connect with the GraphQL-Relay server to query and mutate data. The description of the data needs is accomplished via GraphQL fragments, while the root schema type for the connection is specified through a Relay Route. Conceptually, it’s a relatively simple setup. The challenge is in the details of the setup, and understanding exactly what Relay needs to know in order to perform the various operations.

React, graphicQL and Relay

Source: React – Facebook Code

The above image from this blog post depicts the way in which Relay works with React. Components trigger actions through Relay’s Store API, and the Relay Store handles the responses from the GraphQL server. Interestingly, Relay supports the concept of optimistic updates, which allow the mutation to be recorded in the store pending final confirmation from the server. Optimistic updates allow the UI to signal the user that the update has occurred, even though it has not. Should the update fail, the user will have to be notified, and the UI updated.

Querying Data

Querying data from a Relay-enabled GraphQL server is relatively simple, especially when compared to mutations. Once the component that will consume the data has been created, a Relay container describing the data needed by the component is created. To set up the container, the component being wrapped by it needs to be specified along with a query fragment which defines the data being queried.


import Relay from 'react-relay'; 
import WidgetToolComponent from '../components/widget-tool'; 
 
export default Relay.createContainer(WidgetToolComponent, { 
  fragments: { 
    colors: () => Relay.QL'fragment on __Type { enumValues { name description } }', 
    sizes: () => Relay.QL'fragment on __Type { enumValues { name description } }', 
    viewer: () => Relay.QL' 
      fragment on Viewer { 
        id 
        users(first: 1000) { 
          edges { 
            node { 
              id 
              firstName 
              lastName 
            } 
          } 
        } 
        widgets(first: 1000) { 
          edges { 
            node { 
              id 
              name 
              description 
              color 
              size 
              quantity 
              owner { 
                id 
                firstName 
                lastName 
              } 
            } 
          } 
        } 
      } 
    ' 
  } 
}); 

For this application, three fragments are needed. Two of the fragments are used for introspection queries, in order to load the possible values for two enums which are defined: colors and sizes. The third fragment is for querying application data for the specific viewer. In this application, there is only one unauthenticated viewer. In an application where authentication and authorization are implemented, the viewer would represent the authenticated user, and the data queried under the viewer would typically be limited to data accessible to the user. This limitation would need to be implemented in the GraphQL server.

The parameters passed into users and widgets are the GraphQL-Relay connection pagination arguments: first, after, last, before. first indicates how many edges to return from the beginning, or after the cursor if after is specified. last indicates how many edges to return up to the number of edges before the specified cursor. The cursor is used by Relay to determine the starting location.

Once the fragments are defined, the Relay route is used to specify the queries and fields to execute queries (including the fragments) against.


import Relay from 'react-relay'; 
 
export default class extends Relay.Route { 
  static queries = { 
    colors: () => Relay.QL'query { __type(name:"Color") }', 
    sizes: () => Relay.QL'query { __type(name:"Size") }', 
    viewer: () => Relay.QL'query { viewer }' 
  }; 
  static routeName = 'ViewerRoute'; 
} 

Once the Relay container and route, as well as the React component, are coded, they need to be configured with a Relay root container. The root container will query the GraphQL server for the data needed to fulfill the requirements of the Relay container. The query is formed using the Relay route and the Relay container fragments. Once the data is received, the root container will pass the data to the container, which will set the properties of the React component and render it.


import React from 'react'; 
import Relay from 'react-relay'; 
import ReactDOM from 'react-dom'; 
import WidgetToolContainer from './containers/widget-tool-container'; 
import ViewerRoute from './routes/viewer-route'; 
 
ReactDOM.render( 
  <Relay.RootContainer Component={WidgetToolContainer} route={new ViewerRoute()} />, 
  document.querySelector('main') 
); 

In this application, the root container will fill the WidgetToolContainer using data specified by the ViewerRoute and fragments defined within the WidgetToolContainer.

First Mutation: Insert

Setting up mutations requires creating a new class which inherits from Relay.Mutation, provided by the react-relay module.


import Relay from 'react-relay'; 
 
export default class extends Relay.Mutation { 
 
  static fragments = { 
    viewer: () => Relay.QL'fragment on Viewer { id }' 
  } 
 
  getMutation() { 
    return Relay.QL'mutation { insertWidget }'; 
  } 
 
  // more code here... 
 
} 

A static property named fragments needs to be configured in this new class. The fragments property lists the mutation’s data dependencies. In this case, the mutation of the widget is dependent upon the viewer ID. The mutation is dependent upon the viewer ID because all data retrieved in the application is retrieved through the context of the current viewer. Therefore, when the mutation is performed, Relay will ensure the viewer ID is always available.

With the fragments configured, the getMutation function needs to be configured for the mutation. The getMutation function specifies the name of the GraphQL mutation to be executed, and should match the name of the mutation on the GraphQL server.

The getVariables function transforms data passed into the constructor of the mutation into the structure needed by the GraphQL server to perform the mutation. The data passed into the constructor are made available on the props of the Relay mutation object. In this case, the widget fields on the props are used to construct a new widget object as a property of the input data object sent to the mutation on the GraphQL server. This widget object must conform to the InputInsertWidget type as defined by the GraphQL server.


  getVariables() { 
    return { 
      widget: { 
        name: this.props.name, 
        description: this.props.description, 
        color: this.props.color, 
        size: this.props.size, 
        quantity: this.props.quantity, 
        ownerId: this.props.ownerId 
      } 
    }; 
  } 

The props values are passed via the constructor for the mutation as shown here. The viewer must be set to the original viewer retrieved using Relay. The widget property must be set to null since this will be a new widget rather than an existing widget. Finally, using Object.assign, the properties from the widget object (which contains the data to be inserted) are copied on to the object being passed into the constructor.


Relay.Store.commitUpdate(new InsertWidgetMutation( 
  Object.assign({ viewer: this.props.viewer, widget: null }, widget) 
)); 

When commitUpdate is called, a new InsertWidgetMutation object is created and passed in. The function commitUpdate will use getConfigs and getFatQuery to determine which data needs to be updated to accomplish the mutation. While not shown here, it’s possible to configure optimistic updates and handle collisions between multiple mutations. These features really show the true power of Relay to handle data mutations intelligently.

For the insert widget mutation, the configuration type is RANGE_ADD, where a new widget is being added to the range of widget edges. The connection name identifies to which range of edges the widget is being added, and identifies the name of the GraphQL field which will contain the data for the new widget edge. The range behavior identifies how the widget will be added to the range–single or multiple range behaviors can be configured. For the widget connection, the default and only behavior is the append behavior. Other range operations are prepend, ignore, refetch, and remove.


getConfigs() { 
  return [{ 
    type: 'RANGE_ADD', 
    parentName: 'viewer', 
    parentID: this.props.viewer.id, 
    connectionName: 'widgets', 
    edgeName: 'widgetEdge', 
    rangeBehaviors: { 
      '': 'append' 
    } 
  }]; 
} 

getFatQuery is used to retrieve all of the data needed to update the application once the mutation has been completed. The name InsertWidgetPayload is simply 'Payload' appended to end of a camel case version of the mutation name. All GraphQL fields impacted by the mutation should be included in the fragment.


getFatQuery() { 
  return Relay.QL' 
    fragment on InsertWidgetPayload @relay(pattern: true) { 
      viewer { 
        widgets { 
          edges { 
            node { 
              id 
              name 
              description 
              color 
              size 
              quantity 
              owner { 
                id 
                firstName 
                lastName 
              } 
            } 
          } 
        } 
      } 
      widgetEdge 
    } 
  '; 
} 

Once the mutation is complete, Relay will update the Store, triggering React to render the component attached to the container. View the full source code of the insert widget mutation file on GitHub.

Continue reading %Getting Started with React, GraphQL and Relay (Part 2 of 2)%


by Eric Greene via SitePoint

Design By Roka

Portfolio of Shawn Park, Lead Designer at Instant eSports & previously Product Designer at Box.
 I strive to make an impact on everyone’s lives by creating a bridge between human & technology.


by csreladm via CSSREEL | CSS Website Awards | World best websites | website design awards | CSS Gallery

Tjapukai

Tjapukai is where Australia begins. It is Australia’s most accessible venue to experience authentic Aboriginal and Torres Strait Islander culture dating back over 40,000 years.


by csreladm via CSSREEL | CSS Website Awards | World best websites | website design awards | CSS Gallery

RICH ART GALLERY

NLMD Service Web design / Database Construction / Branding Design / Visual Communication Design / Motion Graphics / Filming & Post-Production


by csreladm via CSSREEL | CSS Website Awards | World best websites | website design awards | CSS Gallery

An in-App Browser with ThemeableBrowser PhoneGap Plugin

PhoneGap is a framework that allows developers to build mobile applications using HTML, CSS and JavaScript. With it, you can build applications for a variety of mobile operating systems such as Android, iOS and Windows Mobile. Plenty of core plugins and API hooks are available and there is a thriving community ecosystem.

For example, using cordova-plugin-geolocation you can get a user's locations and with cordova-plugin-vibration you can make the user's device vibrate. In this tutorial I am going to focus on one specific plugin that is not part of the core suite, 'ThemeableBrowser'. It's a fork of the core InAppBrowser plugin that allows you to open external websites within an app, style the browser and add custom actions.

By the end of this tutorial, you will have created a simple mobile app which displays SitePoint's website alongside some bonus features.

Continue reading %An in-App Browser with ThemeableBrowser PhoneGap Plugin%


by Ivan Dimov via SitePoint