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

How to create custom tokens in Drupal 7

One of the great feature in drupal is tokens system. Tokens are reusable text that can be placed into documents via simple placeholders, like %site-name or [user]. In Drupal there are many default tokens are made available thru’ token module e.g. nodes, users, taxonomy as well as other site related tokens. For example to display site name we have [site:name] token, to display node author we have [node:author]. All these tokens are properties of entities. And if we add new field in node then these field will be available as token. For example [node:body] is the token where it will display body field.

But quite a few times we come across situation when default tokens available in Drupal is not enough for project. Today we are going to discuss about how to create custom tokens using our custom module. In our example we will create a token Trimmed body field. This will display 20 characters of body field in a node wherever we will use this token.

To achieve these we will be using hook_token_info() and hook_tokens() hooks Create a new module MY_MODULE and implement these two hooks. But before start implementing this let’s discuss about hook_token_info() and hook_tokens() hooks.

hook_token_info()

These hook provides information about available placeholder tokens and token types. Tokens are placeholders that can be put into text by using the syntax [type:token], where type is the machine-readable name of a token type, and token is the machine-readable name of a token within this group.

Return value properties:

These function will return associative array of available tokens and token types.

types

  • name: Name of the token type.
  • description: Description of the token type.
  • needs-data: The type of data that must be provided to token_replace() in the $data argument (i.e., the key name in $data) in order for tokens of this type to be used in the $text being processed.

tokens

  • name: Name of the token.
  • description: Description of the token.
  • type (optional): A 'needs-data' data type supplied by this token, which should match a 'needs-data' value from another token type. For example, the node author token provides a user object, which can then be used for token replacement data in token_replace() without having to supply a separate user object.

hook_tokens()

These hook provides replacement values for placeholder tokens. This hook is invoked when someone calls token_replace(). That function first scans the text for [type:token] patterns, and splits the needed tokens into groups by type.

Return value properties :

$type: The machine-readable name of the type (group) of token being replaced, such as 'node', 'user', or another type defined by a hook_token_info() implementation.

$tokens: An array of tokens to be replaced. The keys are the machine-readable token names, and the values are the raw [type:token] strings that appeared in the original text.

$data: (optional) An associative array of data objects to be used when generating replacement values, as supplied in the $data parameter to token_replace().

$options: (optional) An associative array of options for token replacement; see token_replace() for possible values.

Create MY_MODULE module & create file MY_MODULE.tokens.inc and implement following code.

/**
 * Implements hook_token_info().
 */
  function custom_title_token_info() {

    // Define token value, body_trim is the token will be used as [node:body_trim]
    $node_trim['body_trim'] =  array(
      'name' => t("Trimmed body field"),
      'description' => t("Trim body field to 20 characters "),
    );

    // Return associative array of tokens & token types
    return array(
      'tokens' => array(
        'node' => $node_trim,
      ),
    );
}

/**
 * Implements hook_tokens().
 */
function custom_title_tokens($type, $tokens, array $data = array(), array $options = array()) {
  $replacements = array();

  // Check if token type is node
  if($type == 'node'){
    foreach ($tokens as $name => $original) {
      switch ($name) {
        // Check token is body_trim
        case 'body_trim':
          $body = $data['node']->body[LANGUAGE_NONE][0]['value'];
          // Trim 20 characters and return
          $replacements[$original] = substr($body,0,20) . ' ...';
          break;
      }
    }
  }
  return $replacements;
}

Note : We have not defined any custom token type as we needed node related token.

Reference:
function hook_token_info
function hook_tokens

Implementing themes based on specific conditions in Drupal 7

In drupal 7 we have options to set default theme & admin theme. There are limitations, Admin theme will be available for roles which has access permission for admin theme. But in case if we have conditions to set specific theme for specific page based on user roles or specifying theme for particular node types, drupal core will not provide options to do these. We do have module available for this purpose - ThemeKey. But we can achieve by using drupal hooks also.

In this post I am going to explain how we can change particular theme for different pages based on various conditions. Let’s take following scenarios.

  1. Set admin theme for node edit pages for manager role users
  2. Set default theme for node/add/article pages for manager role users

Note : By default manager role is not set admin theme.

Drupal 7 provides hook_custom_theme() hook to do these functionality. Let’s create module called dynamic_theme. Check implementation of hook_custom_theme() for above scenarios.

Scenario 1 : Set admin theme for node edit pages for manager role users

/**
 * Implements hook_custom_theme().
 */
function dynamic_theme_custom_theme() {

  // Load current user
  global $user;

  // Check current page is 'node/%nid%/nid'
  if(current_path() == 'node/%node/edit'){
    // Check current user role is 'manager'
    $roles = $user->roles;
    if(in_array('manager',$roles)){
      // return admin theme for these page
      return variable_get('admin_theme');
    }
  }
  
}

Scenario 2 : Set default theme for node/add/article pages for manager role users

/**
 * Implements hook_custom_theme().
 */
function dynamic_theme_custom_theme() {

  // Load current user
  global $user;

  // Check current page is 'node/%nid%/nid'
  if(current_path() == 'node/add/article'){
    // Check current user role is 'manager'
    $roles = $user->roles;
    if(in_array('manager',$roles)){
      // return default theme for these page
      return variable_get('theme_default');
    }
  }
}

In case if we have multiple themes then return theme name in these function.

Note : The theme you want to activate must be enabled.

Register for DrupalCamp Bangalore - July 25-26 at CMRIT

The much-awaited event, DrupalCamp Bangalore is finally here and the Garden City is all set to welcome the Drupal enthusiasts from all over India. The event will be scheduled from July 25-26 at CMRIT Bangalore and will be featuring a series of curated sessions and sprints.

The excitement is in the air and we, the Valuebound team is constantly volunteering and taking part in every aspect of the DrupalCamp to make it a big success.
 
The mission is to evangelize and spread the vibrant and versatile open source platform, Drupal, across the globe. Join our hands, be a part and experience the dynamicity of Drupal. If you are not yet registered, gear up and grab a ticket right away.

Register yourself at http://drupalcampbangalore.org/ticket/register

Writing custom Drush commands in Drupal 7

As a drupal developer we use drush on daily basis. For example clearing the cache, downloading or enabling modules/themes, updating modules. All these commands comes with core but drupal also provides hooks to integrate with our custom modules.

Today we are discussing about how we can write drush commands through our custom module. We are taking example - “Count of nodes by type”.

$ drush node-count 

or

$ drush nc 

Example of using & output:

$  drush node-count article
article’s node count : 100

To achieve these we have to hook_drush_command(). Let’s create module called custom_dc, And check these code.

/**
 * Implementation of hook_drush_command().
 */
function custom_title_drush_command() {
  $items = array();
  $items['node-count'] = array(
    'callback' => 'custom_title_node_count',  // Callback function
    'description' => 'Drush command to get node count of particular node type.',
    'aliases' => array('nc'), // alias of command
    'examples' => array(      // List these example when user types : drush help nc
      'Get all nodes count' => 'drush nc',
      'Get articles node count' => 'drush nc article',
      'Get articles, pages node count' => 'drush nc article page',
    ),
  );
  return $items;
}

/*
 * Callback function for hook_drush_command().
 */
function custom_title_node_count() {
  // Get arguments passed in command, Ex: drush nc page blog
  $args = func_get_args();
  if ($args) {
    // Loop for types
    foreach($args as $type){
      // Query to get count of particular type
      $result = db_select('node', 'n')
        ->fields('n', array('nid'))
        ->condition('type', $type, '=')
        ->execute();
      $num_of_results = $result->rowCount();
      drush_print($type. "'s node count : " . $num_of_results);
    }

  }
  // If no type passed then return total count
  else {
    drush_print('No node types mentioned');

    $result = db_select('node', 'n')
      ->fields('n', array('nid'))
      ->execute();
    $num_of_results = $result->rowCount();

    drush_print('Count of all nodes : '. $num_of_results);
  }
}

This hook defined command “node-count”. 

Some points about hook_drush_command() implementation.

  • callback : These is callback function for these command.
  • alias :  Alias of these command, here ‘nc’ is alias so we can run command like these Ex: drush nc blog
  • examples :  Array of examples where it will display by help command
$ drush help nc
Drush command to get node count of particular node type.
Examples:
 Get all nodes count                       drush nc              
 Get articles node count                   drush nc article      
 Get articles, pages node count            drush nc article page
Aliases: nc

How to use newly created drush commands - Get all nodes count

drush nc

Get article nodes count

drush nc article

Get page nodes count

drush nc page

Get page, blog nodes count

drush nc page, blog

Installing & configuring Apache Solr-5.2.0 with Drupal 7 using Search API on Ubuntu 14.04

To install Solr Java Runtime Environment (JRE) version 1.7 or higher is needed. On your terminal check your Java version.

$ java -version

If JRE is available it will show you the version number. And if you got no result is found, then you have to installJRE. You can install the same using simple command in terminal

$ sudo apt-get -y install openjdk-7-jdk
$ mkdir /usr/java
$ ln -s /usr/lib/jvm/java-7-openjdk-amd64  /usr/java/default

Now we have JRE installed, lets install Solr.

Installing Solr is pretty easy. Browse to folder you want to install Solr and download the latest copy of Apache Solr  from here - http://www.apache.org/dyn/closer.cgi/lucene/solr

$ cd /opt
$ wget http://archive.apache.org/dist/lucene/solr/5.2.0/solr-5.2.0.tgz

Untar the tar ball and go to solr folder.

$ tar -xvf solr-5.2.0.tgz
$ cd /opt/solr-5.2.0

Now to install Solr as service run this command.

$ bin/install_solr_service.sh --strip-components=2

This will install Solr as a service and run in the background on your web server. By default it uses the port number 8983.

You can change default port number to one of your choice. Just run this line.

$ bin/solr start -p 8984 // Here 8994 would be your new port number

Your Solr should be up and running. Browse to http://your_ip_address:8983/solr

You can also stop Solr as service from the solr directory.

$ bin/solr stop

Check Solr Status if it is running or not.

$ bin/solr status

We have successfully installed Solr but open for everyone who knows our IP address. we need to secure it.

For authentication of solr server url http://your_ip_address:8983/solr we have to do some configuration.

Go to the folder and create a new file with name realm. properties

$ cd opt/solr/server/etc
$ nano /opt/solr/etc/realm.properties

Add username, password and role in this format -

USERNAME:PASSWORD, ROLE-NAME

eg. 
solr : solr_123, solr-admin

Save this file.

Now Edit /opt/solr/etc/webdefault.xml and add the following:

Save webdefault.xml file.

Now Edit /opt/solr/etc/jetty.xml

Now restart your Solr server.

$ cd /opt/solr/
$ bin/solr restart

Check with default port if authentication is working or not by visiting http://your_ip_address:8983/solr

Now it must be asking for username and password. Use the Username and Password which you added in /opt/solr/etc/realm.properties to login.

You should see your Solr admin console.

Configuring Solr with Drupal 7

Get the latest version of Search API Solr Search from Drupal ( Apache Solr Drupal module didn’t worked with Solr 5.2.0 though it used to work with Solr 4.4 )

$ cd /opt
$ wget  http://ftp.drupal.org/files/projects/search_api_solr-7.x-1.8.tar.gz
$ tar -zxf search_api_solr-*.tar.gz

We need to copy Solr configuration files from Search API Solr Search module to solr configuration directory.

$ rsync -av search_api_solr/solr-conf/5.x/  /opt/solr/example/files/conf/

Create new Solr core for your website andcopy Solr configuration files to new core.

$  mkdir /opt/solr/server/solr/valuebound // Here valuebound is name of my Solr Core
$ cp -r  /opt/solr/example/files/conf/  /opt/solr/server/solr/valuebound/ 

Restart Solr now

$ cd /opt/solr 
$ bin/solr restart

Open your Solr admin page - http://your_ip_address:8983/solr

Solr 5.2 admin configuration page

Click On Core Admin and create new core with same name which we used above to create Solr core directory.

Once again restart Solr.

Now we have Solr configured, secured with new core, lets configure our Drupal site to use Solr for search. Install below modules -

Enable these modules in your site module list page. Now we will create one search server and one search index to be used with Solr.

For Creating server and index we have to navigate to Search Api config page (http://valuebound.com/admin/config/search/search_api)

Drupal 7 Search Api config page

Click on Add server link. Name your Solr Server along with description and in Service class Select Solr As a Service.

Add server link for Solr Server

When you will select Service Class As Solr Service it will expand and you will below screen.

Solr Service Configuration in Drupal 7

We have four field

  1. HTTP protocol
    Select http
  2. Solr host
    If no authentication enabled, you have just add your solr server hostname or IP address of your server where Solr is installed.
    If you have Authentication enabled then server name would follow this pattern
    USERNAME:PASSWORD@IP_Address
    eg. solrserverusername:solrserverpassword@xxx.xxx.x.xxx
  3. Solr port
    Port number you have used in during installation of solr server eg. 8983
  4. Solr path
    In our case this would be /solr/valuebound

We have added Search server. Now we also need to add Index server. Navigate to Search Api config page (http://valuebound.com/admin/config/search/search_api) and click add Index server.

Add Index server in Drupal 7 for Apache Solr

Select Item Type “node” and select server which is created in previous step. Check “Index items immediately” then create index.

We have configured Solr server with Drupal.

Next Index all Content with solr server. Your Drupal search result would be served thru’ Apache Solr Server now.

How to disable account related e-mails in Drupal 7

Drupal 7 provides 8 basic email templates for registering, cancellation & password recovery. These settings we can find at ‘admin/config/people/accounts’ page.

account-seting-mail

In these templates, some of following templates has option to disable( checkbox above subject field ).

  • Account activation
  • Account blocked
  • Account canceled

But other templates by default enabled & those cannot be disabled through UI. So incase we don’t want these template then we can do it through programmatically by using hook_mail_alter(). 

In one of case we didn’t wanted to send default “Welcome (no approval required)” email template as we were using Rules to send custom email with some attachment. There is no option to send attachment in default email.

Now let’s look into the simple code how we can disable that. And later I will explain how we can disable for other default templates too. We have created module called no_emails.

/**
 * Implements hook_mail_alter().
 */
function no_emails_mail_alter(&$message) {
  if ($message['key'] == 'register_no_approval_required') {
    $message['send'] = FALSE;
  }
}

Here register_no_approval_required is the message key for ‘Welcome (no approval required)’ template, Following are other message keys in case if you want to disable them.

  • register_admin_created: Welcome message for user created by the admin.
  • register_no_approval_required: Welcome message when user self-registers.
  • register_pending_approval: Welcome message, user pending admin approval.
  • password_reset: Password recovery request.
  • status_activated: Account activated.
  • status_blocked: Account blocked.
  • cancel_confirm: Account cancellation request.
  • status_canceled: Account canceled.

Similarly we can disable Welcome (new user created by administrator) email template using below snippet.

/**
 * Implements hook_mail_alter().
 */
function no_emails_mail_alter(&$message) {
  if ($message['key'] == 'register_admin_created') {
    $message['send'] = FALSE;
  }
}

We have learned how can we disable Welcome (no approval required) template & Welcome (new user created by administrator) templates. You can use above mentioned message keys to disable other default email templates also.

How to get dynamic or Custom page titles in Drupal 7

Recently I was working in a project where we needed to show page title in format of [ node count associated with taxonomy term] [taxonomy term page is associated with] | [site name]. By default drupal 7 provides page title “term name | site name” for term pages. Our requirement was to get page title 125 vegetable recipe blog | my site name. Here 125 is node count of vegetable recipe tag. This is how we have  achieved this using  hook_preprocess_html().

Let’s create module called custom_title & create function custom_title_preprocess_html as follows in custom_title.module file.

/**
 * Implements hook_preprocess_html().
 */
function custom_title_preprocess_html(&$variables) {
  // Make sure current page is taxonomy/term/tid
  // In case if you use alias then you can use these way
  // Let’s say your term page is vegetables/tomato then use like
  // if( arg(0) = 'vegetables' && count(arg()) == 2 ){
  // and alternatively change loading term from name to tid
  if (arg(0) == 'taxonomy' && arg(1) == 'term' && is_numeric(arg(2))) {
    //loading term by tid
    $term = taxonomy_term_load(arg(2));

    //get node count by replacing token value
    $term_node_count = token_replace('[term:node-count]', array('term' => $term));

    //get site name
    $site_name = token_replace('[site:name]');
    $head_title = $term_node_count . " " . $term->name." blogs | " . $site_name;

    //add title
    $variables['head_title'] = $head_title;
  }
}

Now just enable this module and clear your Drupal cache. You should see  your page title like “ 125 vegetable blogs | site name ”. 

Similar to above example you can change page title like “Page Title | Krishna blog” using hook_preprocess_html(). In this case Krishna is node author. Custom or dynamic page title for node pages:

/**
 * Implements hook_preprocess_html().
 */
function custom_title_preprocess_html(&$variables) {
  // Make sure current page is node/nid
  // It will even if use aliases.
  if(arg(0) == 'node' && is_numeric(arg(1)) && count(arg()) ==2){
    //load node from nid
    $node = node_load(arg(1));
    //load user from uid
    $user = user_load($node->uid);
    //add title
    $head_title = $node->title . " | " . $user->name . " blog";
    $variables['head_title'] = $head_title;
  }
}

The way we have customized node page title & term page titles, similarly we can use hook_preprocess_html() hook to customize other page titles like user pages, search page titles or any custom pages.

Customizing node access in drupal 7

Drupal 7 provides accessing of nodes by roles & its permissions, The permissions can be set to different roles & based on permission nodes can be accessible for different operations like view, delete, create & update.

Let’s say we have content type ‘article’ & we have roles  HOD, CR, Student. And we have permissions set to Student role as can ‘view the published article’. CR role has permission that ‘can view published article & can edit own article’.

But in case of we need custom permission scenarios, lets discuss some examples -

  • If student is author then student can edit own article when it is in unpublished state
  • CR role wants to edit own article & Students articles (For unpublished state)

These are some scenarios where permissions will not give options to do these.

We came across some hooks in drupal 7 & found hook_node_access($node, $op, $account). Let’s discuss how we can achieve above scenarios. Create a module called custom_node_access.

Scenario 1 : If student is author then student can edit article when it is in unpublished state

/**
 * Implementation of hook_node_access().
 * 
 * Scenario 1 : If student is author then student can edit article when it is in unpublished state
 */
function custom_title_node_access($node, $op, $account) {
  // get type of node.
  $type = is_string($node) ? $node : $node->type;
  // Check content type is article
  if ($type == 'article') {
    // Check node object is loaded
    // Check node status is unpublished
    if (isset($node->nid) && $node->status  ==  0) {
      // Check operation is update
      if ($op == 'update') {
        // Check user is student
        // Here 2 is student role id
        if (array_key_exists(2, $account->roles)) {
          // Check node author & logged in user are same
          if($node->uid == $account->uid){
            // Access student to update these node
            return NODE_ACCESS_ALLOW;
          }
        }
      }
    }
  }
}

Scenario 2 : CR role wants to edit own article & Students articles (For unpublished state)

/**
 * Implementation of hook_node_access().
 * 
 * Scenario 1 : CR role wants to edit own article & Students articles (For unpublished state) 
*/
function custom_title_node_access($node, $op, $account) {
  // get type of node.
  $type = is_string($node) ? $node : $node->type;
  // Check content type is article
  if ($type == 'article') {
    // Check node object is loaded
    // Check node status is unpublished
    if (isset($node->nid) && $node->status == 0) {
      // Check operation is update
      if ($op == 'update') {
        // Check user is CR
        // Here 3 is CR role id
        if (array_key_exists(3, $account->roles)) {
          // load node author's user object
          $node_author = user_load($node->uid);

          // Check node author & logged in user are same
          // or node author is student (Here 2 is student role id)
          if($node->uid == $account->uid || array_key_exists(2, $node_author->roles)){
            // Access student to update these node
            return NODE_ACCESS_ALLOW;
          }
        }
      }
    }
  }
}

My First Tryst with creating a Drupal 8 Module 'Demo'

I spent the whole day trying to do something that I've been wanting to for quite some time now. I went through the changelog for Drupal 8 to see if I could build an initial level of custom modules in D8 and I would love to share what I have learned so far. Let us take a look at this simple D8 module (that really does nothing other than printing a 'Hello World' ) called 'demo'.Here I have listed out the steps involved while creating the Module with some inline explanation.

Step 1:

Create a Custom folder inside  /modules/custom/. Under Custom we have to create .info.yml (holds basic information about module). & .routing.yml (holds menu link and permission access). And then you need to create Controller.

Drupal 8 uses the Symfony HTTP Kernel, a system which gets the request and asks other systems to produce the requested output (a response object) and sends the response back to the client. The output is generated by a piece of code called the controller. In theory the controller can be either a pure PHP 4 function, a method on an object or even an anonymous function.

The second part of creating a page that outputs our content is to put the page controller in place. This could be a PHP 4 style function, but best practice in Drupal 8 is to use a controller class. This class is in a file named exactly after the controller provided in the routing file, ExampleController.php

For the above router the class needs to be placed in example/src/Controller directory and with name ExampleController.php. So the full path will look like, example/src/Controller/ExampleController.php.

Syntax: use src/ & Controller/ folder inside module directory(As per PSR-4 standard).

The .info file has been converted to YAML. This is the Symfony YAML component. So, the new file extension is .info.yml

For assignment = changed to :

For dependencies, use following format:

dependencies:
- block

For comment # changed to ;   

type key is required with values,indicate the extension.(e.g: module/theme).

name: demo
description: 'Demo module for Drupal 8'
type: module
core: 8.x

routing.yml is used to define routes and for handling the callback function.

Line 1:

Line 2: Path you want to register

Line 3: having Default page _title and _content refers to DemoController with method name demo

Line 4 : provide Permission.


 

Step 2:

The second part of creating a page that outputs our content is to put the page controller in place. This could be a PHP 4 style function, but best practice in Drupal 8 is to use a controller class. This class is in a file named exactly after the controller provided in the routing file, ExampleController.php

Create controller DemoController with a method demo( )

Create src/ & Controller/ folder inside module directory.(src/ is a PSR-4 standard).

Controller/ is a place to store controller. Create DemoController.php


On top, I have specified the class namespace.

Inside Controller class , we have demo( ) method. Which is rendering array.

To view the output all we need to do is clear the cache and navigate to mysite-name/demo

Download module using Github:  git@github-name:xaiwant/drupal8.git

We at Valuebound are committed to furthering your business initiatives with our Enterprise level web solutions. For further information on our service offerings, please Contact us.

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