Drupal Problems and Solutions

DrupalABC aims to provide solution to programming problems faced by Drupal developers.Start learning by reading some of the latest problems below-

How to limit meta description of an article to 150 characters in Drupal 8

By default meta tag, module  use node summary/body token to populate meta description of the content type having body field. It does not follow the standard practice of meta description of length between 135 to 150 characters. Even if you set summary length between 135 and 150, your meta description might end with incomplete word and provide a bad search engine preview. You can create a custom token which meets both the criteria i.e 1. The length between 135 and 150 and  2. The last word might be incomplete because of the character limit. You can create a custom token in following way: 

/**
 * Implements hook_token_info(). 
 */
function custom_module_token_info() {
  $info = [];
  $info['tokens']['custom_module']['node_body_summary'][] = 'A token to extract desired characters from
  Node body to be used in meta descriptions';
  return $info;
}
/**
 * Implements hook_tokens(). 
 */
function custom_modules_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata)
{
$replacements = [];
if ($type == 'custom_module'){
  foreach ($tokens as $name => $original)
  {
    // Find the desired token by name.
    switch ($name) {
      case 'node_body_summary': 
      $replacements[$original] = get_node_body_summary();
       break;
    }
  }
}
return $replacements;
}
/** 
 *Implements function to get node body summary.
 */
function get_node_body_summary(){
  $node = \Drupal::routeMatch()->getParameter('node');
  $type = $node->getType(); $summary = "";
  if ($type != 'article') {
    $text = strip_tags($node->body->value);
    $text = substr($text, 0, 150);
    $summary = substr($text, 0, strrpos($text, ".") + 1);
    if (strlen($summary) < 135) {
      $summary = substr($text, 0, 145) . "...";
    }
  } 
  return $summary;
}

How to do partial match search in Drupal 8 using solr and search API

To do partial match searching in Drupal 8, index the required field as Fulltext NGram and alter the schema.xml in such a way : 

Replace this 

    <fieldType name="edge_n2_kw_string" class="solr.TextField" omitNorms="true" positionIncrementGap="100">
      <analyzer type="index">
        <tokenizer class="solr.KeywordTokenizerFactory"/>
        <filter class="solr.LowerCaseFilterFactory"/>
        <filter class="solr.EdgeNGramFilterFactory" minGramSize="2" maxGramSize="25" />
      </analyzer>
      <analyzer type="query">
        <tokenizer class="solr.KeywordTokenizerFactory"/>
        <filter class="solr.LowerCaseFilterFactory"/>
      </analyzer>
    </fieldType>

 With :

    <fieldType name="edge_n2_kw_text" class="solr.TextField" omitNorms="true" positionIncrementGap="100">
      <analyzer type="index">
        <charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ISOLatin1Accent.txt"/>
        <tokenizer class="solr.WhitespaceTokenizerFactory"/>
        <filter class="solr.LowerCaseFilterFactory"/>
        <filter class="solr.NGramFilterFactory" minGramSize="2" maxGramSize="25" />
      </analyzer>
      <analyzer type="query">
        <charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ISOLatin1Accent.txt"/>
        <tokenizer class="solr.WhitespaceTokenizerFactory"/>
        <filter class="solr.LowerCaseFilterFactory"/>
      </analyzer>
    </fieldType>

How to create custom token in Drupal 8

In Drupal 8 custom token can be created in following way :

It is good practice to write code related to tokens in tokens.inc file. Include the tokens.inc file in your module in following way.

module_load_include('inc', 'custom_module', 'custom_module.tokens');

Now in your custom_module.tokens.inc file, extend the hooks => hook_tokens_token_info and hook_tokens in this way.

/** * Implements hook_token_info(). */
function custom_module_token_info()
{ $info = []; $info['tokens']['custom_module']['node_body_summary'][] = 'A token to extract desired characters from
Node body to be used in meta descriptions';
return $info;
}
/** * Implements hook_tokens(). */
function custom_module_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata)
{ $replacements = []; if ($type == 'custom_module_token') { foreach ($tokens as $name => $original) { switch ($name) { case 'node_body_summary': $replacements[$original] = = 'My Custom Token'; break; } } }
return $replacements;
}

 

Now you can use this token like this : [custom_module:node_body_summary];

How to create controller which provides filter and results alongside

 In Drupal 8 a filter is nothing but a form, it can be displayed above results provided by controller in following way.

//Getting form markup in $form variable.Replace example_drupalabc with your custom module.
$form = \Drupal::formBuilder()->getForm('Drupal\example_drupalabc\Form\FilterForm');
//Adding $form in $build array.
$build['filter'] = $form;
//Now your controller can add other data in various ways.Some of them are:
$build['links'] = [ 'data' => [ '#type' => 'operations', '#links' => $links, ],
];
$build['requests_table'] = [ '#theme' => 'table', '#rows' => $rows, '#header' => $header,
];
//You can also add a pager.
$build['pager'] = [ '#type' => 'pager', '#weight' => 100,
];
//Don't forget to return $build.
return $build;

 

 

How to redirect to a page after form submit in Drupal 8

You can redirect the user to any page after form submission in the following way.

//Don't forget to include this in beginning. This will only work in submitForm function.
use Drupal\Core\Url;
//Constructing a URL.Will redirect to example-page with query paramter q = 5.
$response = Url::fromUserInput('/example-page?q=5');
$form_state->setRedirectUrl($response);