Drupal 8 Headless Hello World

I will be writing a series of article on Drupal-8 Headless. This article will focus on simple headless hello world. We will first learn how to create a Hello World Module in Drupal-8. Oh! but this hello world page will return JSON Data :-) Then we will be creating a NodeJS+Express project which consume the JSON data from Drupal and display it.

Node JS

It’s like Apache server for PHP. Just like Drupal Application needs Apache or Nginx. For running a Javascript Application on Server we require Node JS to be installed. Read more about installing and using Node JS.

Express JS

Express JS is a server side Javascript framework that provides features including server side routing, MVC, etc.

  1. Install a standard drupal-8 profile
  2. Create hello world module
    Create a helloworld folder in modules directory.
    Create a file name helloworld.info.yml with content
    Create a file name helloworld.routing.yml with content
     
    name: helloworld
    type: module
    description: Hello World JSON Return
    core: 8.x
    package: Other
        
    Create new directories src and src/Controller. Create file src/Controller/DefaultController.php with below code
    headers->set('Content-Type', 'application/json');
        return $response;
      }
    
    }
    
  3. Enable the Hello World Module in Drupal
  4. Create a new Node Project (say meand8)
    From your terminal type:
    $ mkdir meand8
    $ cd meand8
    $ npm init # initiate the node project. Choose all default options. 
    $ npm install express —save # add dependency on express js.
    
    
    It will create a file named package.json with content similar to:
    {
    "name": "meand8",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
    "test": "echo \"Error: no test specified\"&& exit 1"
      },
    "author": "",
    "license": "ISC",
    "dependencies": {
    "express": "^4.13.3",
      }
    }
    

    Create new file index.js with following content

    var express = require('express');
    var http = require('http');
    var app = express();
    var http = require('http');
    
    /* Assuming that you can access your drupal via http://localhost/d8 
    Make a http get request to drupal hello world page, that returns a JSON */
    
    http.get("http://localhost/d8/helloworld", function(res) {
      console.log("Got response: " + res.statusCode);
      res.on("data", function(chunk) {
        http_req = "" + chunk;
      });
    }).on('error', function(e) {
      console.log("Got error: " + e.message);
    });
    
    /*Create the landing page of Express JS App and return the Content from Drupal Hello World Page
    app.get('/', function(req, res) {
        res.send(http_req);
    });
    
    app.listen(3000);
    console.log('Listening on port 3000...');
    
    
  5. Start your node server
    In terminal type
    $ node index.js
    Listening on port 3000...
    Got response: 200
        
  6. Check in browser localhost:3000

Headless Drupal: Driving User-Experience on the Mobile Web

Drupal’s power lies in its flexibility, and the fact that developers can create complex content models.

An admin interface helps developers manipulate the backend content repository, to reflect changes in the front-end framework, and vice-versa. This tight coupling between the frontend and backend have been used to develop some of the best websites, e-commerce applications and web-apps. Over the years, Drupal has emerged as a very powerful framework.

However, this approach was more relevant a decade ago when mobile applications were still in their infancy, and when enterprise applications worked in silos without too much interaction between them. But a lot has changed since then. Today, the mobile web is changing the way business is done.

Simply replicating a part of the desktop application on a mobile app is not only costly, but also robs the app of its power. A more efficient and cost-effective approach is to have the backend content repository deliver content to a variety of powerful applications working on various devices. This means, a single backend Drupal CMS should be able to push content to a mobile app, and any other enterprise application at the same time. Using Drupal in this way is what we call “Headless Drupal”.

The necessity of such ‘cross-platform publishing’ is what is driving the popularity of Headless Drupal or decoupling of the backend CMS from the front-end framework. But this is not the only reason Headless Drupal is relevant but equally important is the fact that creating unique user-experience is differentiation strategy for business organizations.

A whole new set of front-end technologies have emerged using which we can create faster, responsive and interactive apps that offer a rich experience to the end-user. Front-end developers need not know the intricacies of backend drupal programming and still they can harness the power of Drupal’s powerful content-modeling capabilities, and its equally effective editing interface.

So how is Headless Drupal different from regular coupled CMS systems?

A traditional CMS has three components to it:

  1. The database which stores and maintains the content
  2. An admin interface that editors can be use to manage the content models in the database
  3. The templating layer: basically front-end that is use to implement unique look and feel for the website

In a Headless Drupal website or web-app, the content for the site/app is accessed using an API through formats such as JSON or REST. And front end specific application framework like Angular, Backbone, Ember or Knockout delivers the API output onto the front-end template layer. We do not use default Drupal templating layer to display the data or content.

So when should we go for Headless Drupal?

  • If you are building your website where content can be consumed by different applications and repurposed based on context. Headless Drupal will allows you to have different architecture for editorial system and the publishing system. You can event have one common editorial system for multiple publishing system.
     
  • You want to rely more on front-end architecture for scalability. And it makes more sense as having no heavy CMS in the delivery architecture means less of server processing. Static HTML files are easier to handle anyway from scaling perspective.
     
  • You are building an application where managing content is just one part. CMS is secondary function of the larger application.
     
  • Or sometimes you want to create two different application where one is used to create content like we do in staging environment. And after final approval, content is published to another publishing system. You do not require front-end for staging environment where content is created and reviewed only.

Headless Drupal is not without its share of adversaries or criticism. However in certain scenarios, its benefits far outweigh its drawbacks. In a world where user experience is critical for long-term success, decoupling CMS and front-end, which is what Headless Drupal achieves, is no longer an option, but a necessity.

Show data in Drupal from Web Services using Drupal WSData Module

With the evolution of Headless Drupal, Drupal is moving towards on being a preferable content storage to serve the data. But how is Drupal when being used as a Front end consuming remote data instead of proving it?

In one our recent project we have to achieve the same. Drupal is being used to display the remote data which is being provided by RESTful APIs. The catch was the data that was being consumed should not be saved in the Drupal database. So it was purely used just to display the data. Not only that we need to use the consumed data in views, and panels.

There are a few ways of doing this. One being using drupal_http_request function to consume the data and use it. But that would require a lot of customizations and in the long run would be very difficult to maintain.

In comes Web Service Data module

According to its documentation:
“Web Service Data is a collection of modules allowing you to interact with web services using entities and fields in Drupal.”

It was a perfect match for our requirement. The module will consume the data from Web Services and display it without saving any of it in the database. Plus it have fields, views and panels integration. So it was a win win situation all together.

So I am going to discuss how to use the Web Service Data module to consume Web Services and use them just as normal fields.

Enable the following modules:

  1. Web Service Data – Parent module to handle all the web services.
  2. Web Service Data Configuration – It enables to add the web service configuration from where we will fetch the data.
  3. Web Service Data Fields – Attach the power WSData module to fields.
  4. Web Service Data Fields Views Handlers – View handler for fields which are powered by WSData module.
  5. Web Service Fields Storage – Storage controller for fields to load the data.
  6. WS Data Demo – A demonstration on how to the module in action.

Once enabled if you go to “admin/structure/wsconfig/type” you will see a configuration type being added by the demo module.

In the Web Service Configuration section we define the endpoint of the service.

Next we go to “admin/structure/wsconfig”. The demo module has added a configuration for the type prescribed above. The configuration defines what CRUD operations for the service along with the method for it.

The demo module have also added a content type “Linked Data” with a title field and body field. The body field is provided by Web Service Data Fields module. In “admin/config/services/wsfields_storage” you can see the field being declared and configured to fetch data from the web service configuration.

So, we create a content for Linked Data. In the form we just need to enter the title. Lets say we enter “Drupal”. Once the content is saved you will be taken to the node page where the body of the content will be filled up by the Drupal wikipedia page.

Now let's use this module to fetch some remote data and publish it on our Drupal site. For this lets say we have an endpoint called http://examplesite.com/api/article/{article_id} which gives us details about an article.

  1. Go to “admin/structure/wsconfig_types” and add a Configuration type.
  2. Next we add a web service configuration for the type. We select the EventCampus Articles configuration as our endpoint.
  3. Add the required fields you want to fetch from the web services in “admin/config/services/wsfields_storage”. You can select what type of data you want to fetch and to which entity you want to attach the data. In the Web Service Remote Data Key you need to specify which field will hold the argument to the web service call. Like in our case title was the holder for the remote article_id argument.
  4. Now when we create a content of type article we can see the data pulled from the remote web service and being displayed in the node page.

This data can be used like default node fields in Views or Panels without any problem.

Currently once a few types of fields can be handled using the WsData module. But you can easily create handler for other fields which are not there like email, links, etc...

Conclusion, it’s a great module when we want to display data fetched from web services with saving in Drupal database. It comes packed with a good API system which we can extend to use it even in custom entities.

Free Drupal Training by Valuebound, Bangalore on Drupal Global Training Days

We are happy to announce that we are running Drupal training sessions on Saturday, 21st Nov as part of the Global Training Days. The initiative is run by the Drupal Association to introduce newcomers to Drupal.

Come and join us to learn about what Drupal does and how it can help you. We will learn about Drupal and build our first website live.

What is a Drupal Global Training Day?

Drupal Global Training Days is a worldwide initiative to increase the adoption of Drupal. All across the world, people are teaching and learning Drupal, and sharing that open source love.

What is it? 

It's a full day introduction to Drupal. Attendees will leave having successfully built a Drupal site. Part of the Drupal Global Training Day initiative by the Drupal Association.

What we are going to do -

  1. Install Drupal 8 using Acquia Cloud - https://www.acquia.com/drupal-8
  2. Familiarize ourseleves with the new User Interface and options
  3. Learn about how to create content
  4. Experiment with the inbuilt views as well as image handling
  5. Create new blocks and understand about regions
  6. Manage users
  7. QnA
  8. Celebrate D8 release

Whose it for? 

  • It's for those interested in taking up Drupal as a career path.
  • Web developers/designers willing to get started with Drupal.
  • Project managers managing or considering Drupal projects.
  • Decision makers evaluating Drupal. 

Cost? It's FREE. Venue provided by Valuebound.

WHY IS THIS SESSION FREE?

Introducing Drupal among students and amateur designers free of cost is one of the many ways by which we thank this open source community.

Valuebound Interactive is solely dedicated in helping organizations and individuals to adopt Drupal in their operations in the most effective manner. At Valuebound, we believe in giving result oriented training sessions which will help you to build impeccable websites.

Limited availability to ensure personal guidance throughout the day.

Independence/ Ethnic day celebration at Valuebound

Valuebound celebrated 69th Pre-Independence Day Celebration cum Ethnic day with lots of fun wearing traditional dresses,decorating office in the spirit of Independence Day with tri colour balloons & Indian flag, followed by some group activity & Pizza party.
 
It was real fun seeing the amount of participation & Enthusiasm in office.

Proud to be Indian!

Configuring & Debugging XDebug with PHPStorm For Drupal 7 on Mac os X yosemite

I am running my machine with nginx & php 5.6, First make sure that you have already installed Xdebug. We can check this with php version command

$ php -v

Xdebug check

If you see ‘Xdebug v’ that means XDebug installed. If you do not see then install XDebug using PECL

$ pecl install xdebug

If the extension is added to your php.ini file automatically, remove the following line:

zend_extension_ts="xdebug.so"

And replace it with:

zend_extension="/usr/local/php/lib/php/extensions/no-debug-zts-20131226/xdebug.so"

Restart your nginx and confirm XDebug is installed by checking php version OR you can also check with phpinfo in the browser.

check with phpinfo

Note =: to find php.ini or xdeboug.so use $ locate or check phpinfo for php.ini location.

How to configure XDebug for PhpStorm ?

Open PhpStorm -> File -> Default Settings -> In the search box search with ‘debug’

configure XDebug for PhpStorm

Change ‘Debug port’ to 9001, apply and ok.

Open File -> Default Settings -> Search for ‘IDE Key’

Search for IDE Key

Set IDE key as ‘PHPSTORM’, Apply & OK

Now we need to add following XDebug values in php.ini, restart nginx & php-fpm

xdebug.remote_port=9001
xdebug.remote_enable=1
xdebug.idekey=PHPSTORM

How to Configure Xdebug for Google Chrome ?

Enable google chrome extension Xdebug helper

Enable google chrome extension Xdebug helper

Once you have enabled extension then you need to add Debugger bookmarklets for chrome. Go to https://www.jetbrains.com/phpstorm/marklets/ page & Generate XDebugger bookmarks

Note : IDE key should be PHPSTORM, as we set in PhpStorm settings.

IDE key

Now Drag & drop - Start debugger & Stop debugger to chrome bookmarks Bar. You should see the screen like below

chrome bookmarks Bar

Test debugging with Breakpoints for drupal 7

Now it’s time to debug our drupal 7 site with phpstorm & chrome

Open PhpStorm with drupal 7 project & click ‘Start listen for PHP Debug connections’ (These option are at Top Right corner)

Start listen for PHP Debug connections

Now open google chrome browser & click on ‘Start debugger’ in the bookmark toolbar.

Start debugger

Now add breakpoint in index.php file in PhpStorm.

add breakpoint in index.php

Then again visit chrome and load any page of these project (localhost/drupal7). For the first time phpstorm will ask for confirmation dialogue box to accept connection from google chrome. Once you accept it, you will see debug information like below.

debug information

Now you can debug by putting multiple breakpoints on your code.

Drupal in a day at Brindavan College of Engineering

Valuebound conducted ‘Drupal in a Day’ workshop at Brindavan College of Engineering on August 11, 2015. 

The one day workshop comprised of one hour awareness sessions and four hours  of hands on learning about installing and configuring Drupal, an open source content management system. The response from students and faculties were encouraging throughout the session

Brindavan College of Engineering’s Management extended their full support to our one day workshop. The workshop witnessed an attendance of more than 160 pupils from B Tech and MCA Final Year. The session has reportedly impressed professors and students in Computer Science faculty, as they openly expressed their desire to take up Internship project on Drupal CMS. 

After the completion of workshops, many lecturers and students asked about a possible internship and project which can be given by on various Drupal companies.

Free Training by Valuebound, Bangalore on Drupal Global Training Days

Bangalore Drupal User Group in collaboration with Valuebound & TIME Inc India will be conducting a free Drupal training on Global Drupal Training Day, Sat, 29th Aug.

What is it?

It's a full day introduction to Drupal. Attendees will leave having successfully built a Drupal site. Part of the Drupal Global Training Day initiative by the Drupal Association.

Whose it for? 

It's for those interested in taking up Drupal as a career path. Hobbyist or entrepreneurs who wants to learn site building on your own.

Cost? It's FREE. Venue and lunch provided by TIME Inc India.

Venue

Time Inc.
RMZ ECOWORLD, PLOT C1, CAMPUS 8A, 5TH FLOOR OUTER RING ROAD BENGALURU, INDIA - 560103
Phone: +91 80 7105 7100

How do you use hook_menu_alter() in drupal 7

I have been working on Drupal 7 for almost two years now. During these two years I have worked on many hooks but hook_menu_alter() hook is the one of the mostly used one. Today i going to explain my experience with this hook.

Change theme of particular page/menu:

I have discussed this one of earlier post in detail. There we have used hook_custom_theme() hook to change theme on particular page. Instead of this we can also use hook_menu_alter() as another way to achieve same feature.

/*
 * Implements hook_menu_alter().
 */
function custom_module_menu_alter(&$items){
  // Change 'node/add/page' page to admin theme (Assume by default node/add page uses default theme)
  $items ['node/add/page']['theme callback'] = variable_get('admin_theme');
}

Change title of page/menu:

Menu provides page titles. If we are in ‘node/add/page’ then we see page title as ‘Create Basic page’ but what if we need custom title like ‘Add page’. We can achive this using below custom module.

/*
 * Implements hook_menu_alter().
 */
function custom_module_menu_alter(&$items){
  // Change 'node/add/page' title to 'Add page'
  $items ['node/add/page']['title'] = 'Add Page';
}

Customize accessing a page/menu:

For many pages/menus we restrict access to different users or on conditions. Let’s say we want restrict ‘user/register’ page in particular times.. I mean no registration will be done in 12AM - 06AM.

/*
 * Implements hook_menu_alter().
 */
function custom_module_menu_alter(&$items){
  // Restrict 'user/register' page in 12AM-05AM
  $items ['user/register']['access callback'] = '_MY_MODULE_time_access';
}

/*
 * Access callback function to restrict user registration in particular timings
 */
function custom_module_time_access(){
  // Get current time hour like 0,1,2,3....23
  $current_time_hour = date('G');
  
  // if current time is between 0 & 5 then return false
  if($current_time_hour >= 0 && $current_time_hour <= 5 ){
    return false;
  }
  return TRUE;
}

Create duplicate page/menu:

We can also use hook_menu_alter() hook if we want to create a duplicate page, a page with same functionality but with different url. Let’s say we want a url ‘add/page’ which acts same as of ‘node/add/page’.

/*
 * Implements hook_menu_alter().
 */
function custom_module_menu_alter(&$items){
  // Copy ‘node/add/page’ page to ‘add/page’
  $items ['add/page'] = $items ['node/add/page'];
}

Custom Account cancellation methods in Drupal 7

In drupal 7 whenever admin selects to cancel user/s account, it provides multiple cancellation options like

  • Disable the account and keep its content.
  • Disable the account and unpublish its content.
  • Delete the account and make its content belong to the Anonymous user.
  • Delete the account and its content.

In this post I am going to explain how to create a create custom method like ‘Disable the account and make its content belong to the admin user.

There are two user API hooks available to achieve this - hook_user_cancel_methods_alter() & hook_user_cancel(). Before we start implementing lets discuss about these hooks.

hook_user_cancel_methods_alter()

This hook is used to modify account cancellation methods and can be used to add, customize, or remove account cancellation methods. After we invoke this hook all defined methods are converted as radio button form elements by user_cancel_methods() We can define following 3 properties -

  • title: The title of method (radio button's title).
  • description: (optional) A description to display on the confirmation form if the user is not allowed to select the account cancellation method. The description is NOT used for the radio button, but instead should provide additional explanation to the user seeking to cancel their account.
  • access: (optional) A boolean value indicating whether the user can access a method. If #access is defined, the method cannot be configured as default method.

In our case we are defining new method called ‘my_module_assign_to_admin

hook_user_cancel()

These hook will be called on user account cancellations. Depending on the account cancellation method, the module should either do nothing, unpublish content, or anonymize content. In this case also following 3 properties can be defined -

  • $edit: The array of form values submitted by the user.
  • $account: The user object on which the operation is being performed.
  • $method: The account cancellation method.

In our case we are defining functionality for our method ‘my_module_assign_to_admin

Let’s create module called my_module, using following code

/*
 * Implements hook_user_cancel_methods_alter().
 */
function my_module_user_cancel_methods_alter(&$methods) {
  // Add a custom method.
  $methods['my_module_assign_to_admin'] = array(
    'title' => t('Disable the account and make its content belong to the admin user.'),
    'description' => t('All contents will be assigned to admin user.'),
    // access should be used for administrative methods only.
    'access' => user_access('Administer permissions'),
  );
}

/*
 * Implements hook_user_cancel().
 */
function my_module_user_cancel($edit, $account, $method) {
  switch ($method) {
    case 'my_module_assign_to_admin':
      // Assign nodes to admin user.
      module_load_include('inc', 'node', 'node.admin');
      $nodes = db_select('node', 'n')
        ->fields('n', array('nid'))
        ->condition('uid', $account->uid)
        ->execute()
        ->fetchCol();
      node_mass_update($nodes, array('uid' => 1));
      break;
  }
}

Just enable this module on your module list page, you should see additional option for user cancellation -

  • Disable the account and make its content belong to the admin user

Referrence
https://api.drupal.org/api/drupal/modules!user!user.api.php/function/hook_user_cancel/7
https://api.drupal.org/api/drupal/modules!user!user.api.php/function/hook_user_cancel_methods_alter/7

Download the Drupal Guide
Enter your email address to receive the guide.
get in touch