Skip to content

MahmoudSayed96/drupal-code-snippets

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

87 Commits
 
 

Repository files navigation

Drupal PHP cheatsheet

Custom Module Development

  • Module file structure
|-- modules
  | -- custom
    |-- hello_world
      |-- hello_world.info.yml
      |-- hello_world.routing.yml
      |-- src
        |-- Controller
  • .info.yml:

    Contains all information about module [name, description, core, version, type]

name: Hello World Module
description: Creates a page showing "Hello World".
package: Custom

type: module
core: 8.x
core_version_requirement: ^8 || ^9
  • .routing.yml

    Containes custom routing refear to controller callback function

hello_world.my_page:
  path: "/mypage/page"
  defaults:
    _controller: '\Drupal\hello_world\Controller\HelloWorldController::myPage'
    _title: "My first page in Drupal"
  requirements:
    _permission: "access content"

hello_world.my_page

This is the machine name of the route. By convention, route machine names should be module_name.sub_name. When other parts of the code need to refer to the route, they will use the machine name.

path

This gives the path to the page on your site. Note the leading slash (/).

defaults

This describes the page and title callbacks. @todo: Where can these defaults be overridden?

requirements

This specifies the conditions under which the page will be displayed. You can specify permissions, modules that must be enabled, and other conditions.


URL

URL generation###

@see https://www.hashbangcode.com/article/drupal-9-programmatically-creating-and-using-urls-and-links.
@see https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Url.php/class/Url/8.2.x.

When adding a URL into a string, for instance in a text description, core recommends we use the \Drupal\Core\Url class. This has a few handy methods:

  • Internal URL based on a route - ### Url::fromRoute()### , Example: Url::fromRoute('user.register')->toString()
  • Internal URL based on a path - ### Url::fromInternalUri()### , Example: Url::fromInternalUri('node/add')
  • External URL - ### Url::fromUri### , Example: Url::fromUri('https://www.acquia.com')

    When you need to constrict and display the link as text you can use the toString() method: Url::fromRoute('user.register')->toString().

Short snippet that shows how to get url parameters in drupal 8. to get query parameter form the url, you can us the following. If you have the url for example /page?uid=123&num=452. To get all params, use:. $param = \Drupal::request()->query->all();. To get "uid" from the url, use:. $uid = \Drupal::request()->query->get('uid');.

To get "num" from the url, use:

$num = \Drupal::request()->query->get('num');

// Remove ar or en from the path. php $path = preg_replace('/\/(ar|en)/', '', $request->getPathInfo());

URL in TWIG

{# Link to frontpage view. #}
<a href="{{ path('view.frontpage.page_1') }}">{{ 'View all content'|t }}</a>
<br>
{# Link to user entity/profile page. #}
<a href="{{ path('entity.user.canonical', {'user': user.id}) }}">{{ 'View user profile'|t }}</a>
<br>
{# Link to node page. #}
<a href="{{ path('entity.node.canonical', {'node': node.id}) }}">{{ 'View node page'|t }}</a>
<br>
{# Add a destination query parameter. Simple Example #}
<a href="{{ path('user.login', {}, {'query': {'destination': path('<current>') }}) }}">{{ 'View node page'|t }}</a>.
<br>
{# Add a destination query parameter. Advanced Example, registration_form.simple_form is a custom route from a custom module with the name registration_form #}
{% set redirect_path = path('registration_form.simple_form', {'node': node.id}) %}
<a href="{{ path('user.register',{},{'query':{'destination': redirect_path }}) }}">{{ 'Register'|t }}</a>

Images

Render images with image styles

@source https://www.webomelette.com/how-render-your-images-image-styles-drupal-8

URL only

$style = \Drupal::entityTypeManager()->getStorage('image_style')->load('thumbnail');
$url = $style->buildUrl('public://my-image.png');

Render image

$render = [
  '#theme' => 'image_style',
  '#style_name' => 'thumbnail',
  '#uri' => 'public://my-image.png',
  // optional parameters
];

Example

@todo to be refined.

if ($paragraph && $paragraph->hasField('field_image') && !$paragraph->get('field_image')->isEmpty()) {
  $entity_img_id = $paragraph->get('field_image')->first()->getValue()['target_id'];
  $image = \Drupal::entityTypeManager()->getStorage('file')->load($entity_img_id);
  $style = \Drupal::entityTypeManager()->getStorage('image_style')->load('thumbnail');
  $uri = $style->buildUrl($image->getFileUri());

  return [
    '#theme' => 'image',
    '#style_name' => 'thumbnail',
    '#uri' => $uri,
  ];
}

Responsive image

$file = $paragraph->get('field_image')->entity;

if ($file) {
  $image = \Drupal::service('image.factory')->get($file->getFileUri());

  $logo_build = [
    '#theme' => 'responsive_image',
    '#responsive_image_style_id' => 'promoted_teaser',
    '#uri' => $file->getFileUri(),
  ];

  // Add the file entity to the cache dependencies.
  // This will clear our cache when this entity updates.
  $renderer = \Drupal::service('renderer');
  $renderer->addCacheableDependency($logo_build, $file);

  $build['#image_p'.$paragraph_counter] = $logo_build;
}

Load media entity & get a field

use Drupal\media\Entity\Media;

$media = Media::load($nid);
$file_uri = $media->field_media_file->entity->getFileUri();

Show Image Field In Twig

  • Get the image as tag <img>
{{fields.field_my_image_field.content|render|striptags('<img>')|trim|raw}}
  • Get the image as URL
{{fields.field_my_image_field.content|render|striptags|trim|raw}}

show you how to loop images in Twig and dynamically add image styles to them in Drupal 8.

{% for item in content.field_images['#items'] %}
  {% set image = {
    '#theme':      'image_style',
    '#style_name': 'medium',
    '#uri':        item.entity.uri.value,
    '#alt':        item.alt,
    '#width':      item.width,
    '#height':     item.height
  } %}
  {{ image }}
{% endfor %}

JavaScript

Drupal 8 Js, how to create a global Drupal Js function

/**
 * Attaches the single_datetime behavior.
 *
 * @type {Drupal~behavior}
 */
(
  function ($, Drupal, drupalSettings) {
    "use strict";
    Drupal.behaviors.leafletCurrentLocation = {
      attach: function (context, drupalSettings) {
        // Code....
      },
    };
  }
)(jQuery, Drupal, drupalSettings);

JavaScript behaviors

(function ($, Drupal, drupalSettings, once) {
  Drupal.behaviors.mainBehavior = {
    attach: function (context, drupalSettings) {
      once("mainBehavior", "html", context).forEach(function () {
        console.log(drupalSettings);
        console.log(context);
      });
    },
  };
})(jQuery, Drupal, drupalSettings, once);

How to Run a JavaScript Code at Browser Closing Time

(function ($) {
  Drupal.behaviors.page_load_progress = {
    attach: function (context, settings) {
      window.onbeforeunload = close_event_function;
      function close_event_function() {
        //Enter your code before run window close;
        return null;
      }
    },
  };
})(jQuery);

DateTime

Inserting the value from Datetime field form

@see https://drupal.stackexchange.com/questions/204103/inserting-the-value-from-datetime-field-form

  // Get a date string suitable for use with entity query.
  $date = new DrupalDateTime();
  // This is a date/time from my local timezone.
  $date = DrupalDateTime::createFromFormat('d-m-Y: H:i A', '28-12-2021: 10:00 AM');
  $date = new \Drupal\Core\Datetime\DrupalDateTime(); 
  $date->setTimezone(new \DateTimezone(DateTimeItemInterface::STORAGE_TIMEZONE));
  $string = $date->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT);
  
  // Query datetime database (datetime field).
  $query = \Drupal::entityQuery('node')
  ->condition('type', 'event')
  ->condition('status', 1)
  ->condition('field_event_datetime.value', $query_date, '=')
  ->sort('title', 'ASC');
  $nids = $query->execute();
  $count = count($nids);

Retrive datetime field value from node

@see https://github.com/selwynpolit/d9book/tree/main/web/modules/custom/date_examples

$event_node = Node::load(1);
dump($event_node->field_event_datetime->date->format('m/d/y g:i a', ['timezone'=>'Africa/Cairo']));
dump($event_node->field_event_datetime->date->format('m/d/y g:i A', ['timezone'=>'Africa/Cairo']));
dump($event_node->field_event_datetime->date->format('F j, Y', ['timezone'=>'Africa/Cairo']));
dump($event_node->field_event_datetime->date->format('g:i A', ['timezone'=>'Africa/Cairo']));

DateTime Object

use Drupal\Core\Datetime\DrupalDateTime;

   //Convert Timestamp to Drupal DateTime
   $drupalDateTime = DrupalDateTime::createFromTimestamp($row->created);

   print $drupalDateTime->format('r');
  //Will return "Wed, 13 Oct 2021 17:40:39 +0300"

   print $drupalDateTime->__toString()
  //Will return 2021-10-13 17:40:39 Europe/Athens

  print $drupalDateTime->format('Y-m-d H:i:s')
  //Will return "2021-10-13 17:40:39"

  print $drupalDateTime->format('Y-m-d H:i:s P')
  //Will return "2021-10-13 17:40:39 +03:00"

Set datetime-local html default value

<div class="form-group">
  <label for="">موعد الاختبار</label>
  <?php $datetime = new DateTime($row['start_date']); ?>
  <input
    type="datetime-local"
    class="form-control"
    name="start_date"
    value="<?= $datetime->format('Y-m-d\TH:i:s'); ?>"
    required
  />
</div>

How to Change Date Format from UTC Timezone to Any Required Timezone

In Drupal, usually the date field value is saved in the database in UTC timezone format. One of our requirements for a project was to show the date in the site's timezone format. So we generated a general function to convert date in UTC timezone to any required timezone and format it. Just use the below function to convert date in UTC timzone to a given timezone and the format date using a valid timestamp.

/**
 * Function to get date/time on user's timezone
 * @param  int $timestamp
 *  Timestamp to be converted to date
 * @param string timezone
 *  Timezone to which date is to be converted
 * @param  string $format
 *  Format to which date to convert
 * @return string
 *  Formatted date.
 */
function get_date_on_given_timezone($timestamp, $new_timezone, $format = 'd/m/Y H:i:s') {
  if (!empty($timestamp)) {
    // Database timezone.
    $db_timezone = 'UTC';
    $date_object = new DateObject($timestamp, new DateTimeZone($db_timezone));
    // Convert from the database time zone to site's time zone.
    $date_object->setTimezone(new DateTimeZone($new_timezone));
    $new_date = date_format_date($date_object, 'custom', $format);
    return $new_date;
  }
}

User

Drupal 8 Current User Object, useful methods, and what they return

get current user in Drupal 8

$current_user = \Drupal::currentUser();

$uid = $current_user->id();
// It returns user id of current user.

$user_mail = $current_user->getEmail();
// It returns user email id.

$user_display_name = $current_user->getDisplayName();
// It returns user display name.

$user_account_name = $current_user->getAccountName()
// It returns user account name.

$user_roles = $current_user->getRoles();
// It returns array of current user has.

$current_user->isAnonymous();
// It returns true or false.

$current_user->isAuthenticated();
// It returns true or false.

$current_user->getLastAccessedTime();
// It returns the timestamp of the last logged-in time for this user

Check if the current user is an admin.

$user = \Drupal::currentUser()->getRoles();
  if(!in_array("administrator", $user) && $form_id == 'user_form') {
   unset($form['account']);
  }

Drupal 8 programmatically block and unblock a user

/**  @var \Drupal\user\UserInterface $user */
$user = \Drupal\user\Entity\User::load(USER_ID_HERE);
$user->block();
// $user->activate();
$user->save();

Code snippet that can be used to Log in user programmatically in Drupal 8

use Drupal\user\Entity\User;
use Symfony\Component\HttpFoundation\RedirectResponse;


$user = User::create([
  'name' => $userEmail,
  'mail' => $userEmail,
  'pass' => $password,
  'status' => 1,
]);
user_login_finalize($user);
$user_destination = \Drupal::destination()->get();
$response = new RedirectResponse($user_destination);
$response->send();

Drupal: How to inject a Service into a Class (Controller, Form, Plugin Block, etc) and why not into another service Class

Profile Module

// Load profile by user id and profile type.
 $profile = \Drupal::entityTypeManager()
        ->getStorage('profile')
        ->loadByProperties([
          'uid' => $doctor_id,
          'type' => 'doctor_profile',
        ]);
 // Get filed data.
 $hcp_profile = reset($hcp_profiles);
 $address = $hcp_profile->get('field_user_address')->getValue();
 //Or
 $full_name = $profile->field_full_name->value;

Reset user password using uid

public function restPass()
  {
    $user = \Drupal\user\Entity\User::load(85);
    kint($user);
    die();
    $user->setPassword('admin');
    $user->save();
    return [
      '#type' => 'markup',
      '#markup' => 'Done'
    ];
  }

Get user url

$variables['user_url'] = Url::fromRoute('entity.user.canonical', ['user' => $account->id()])->setAbsolute()->toString();

Node

How to programmatically update an entity reference field

@see https://stefvanlooveren.me/blog/how-programmatically-update-entity-reference-field-drupal-8

Render node body field.

$body = \Drupal\Component\Utility\Unicode::truncate(preg_replace('/[^\w$\x{0080}-\x{FFFF}]+/u', ' ',strip_tags($node->get('body')->value) ), 200, true, true);

Render a node

On drupal 8 every elements (almost) are an entity, as any entity you can render a node.

@see http://www.drupal8.ovh/en/tutoriels/339/render-a-node-or-an-entity

$nid = 1;
$entity_type = 'node';
$view_mode = 'teaser';
$view_builder = \Drupal::entityTypeManager()->getViewBuilder($entity_type);
$storage = \Drupal::entityTypeManager()->getStorage($entity_type);
$node = $storage->load($nid);
$build = $view_builder->view($node, $view_mode);
$output = render($build);
// Note : you can also use if you don't want to use different entity types.
$node = Node::load($nid);

Get node field value from html scope

function hook_preprocess_html(&$variables) {
  // If current page is a node full page.
  $node = \Drupal::request()->attributes->get('node');
  if ($node) {
    // Get entity reference field entities and loop.
    $node_paragraphs = $node->get('field_paragraphs')->referencedEntities();

    foreach ($node_paragraphs as $entity) {
      // Check entity type and for a not empty field.
      if ($entity->getType() === "card" && !($entity->get('field_media')->isEmpty())) {
        // Add body class.
        $variables['attributes']['class'][] = "has-intro-banner";
      }
    }
  }
}

Get current node id

$node = \Drupal::routeMatch()->getParameter('node');
if ($node instanceof \Drupal\node\NodeInterface) {
  $nid = $node->id();
}

Get decrypted field values during entity insert/update hook

The following explains the situation on a foo node when attempting to get the value of the text field
field_bar during a form-alter, a node pre-save, a node insert, and a node update:

/**
 * Implements hook_form_BASE_FORM_ID_alter().
 *
 * Alter the edit Foo node form.
 */
function mymodule_form_node_foo_edit_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  /**  @var \Drupal\node\Entity\Node $foo_node */
  $foo_node = $form_state->getFormObject()->getEntity();
  // Value 1 is correct.
  $bar_value_1 = $foo_node->field_bar->getString();
  // Value 2 is correct.
  $bar_value_2 = $foo_node->field_bar->getValue();
  // Value 3 is correct.
  $bar_value_3 = $foo_node->field_bar[0]->value;
  // Value 4 is correct.
  $bar_value_4 = $foo_node->get('field_bar')->getValue();
}

/**
 * Implements hook_ENTITY_TYPE_presave().
 */
function mymodule_node_presave(EntityInterface $entity) {
  // Value 1 is correct.
  $bar_value_1 = $entity->field_bar->getString();
  // Value 2 is correct.
  $bar_value_2 = $entity->field_bar->getValue();
  // Value 3 is correct.
  $bar_value_3 = $entity->field_bar[0]->value;
  // Value 4 is correct.
  $bar_value_4 = $entity->get('field_bar')->getValue();
}
/**
 * Implements hook_ENTITY_TYPE_insert().
 */
function mymodule_node_insert(EntityInterface $entity) {
  // Value 1 returns `[ENCRYPTED]`.
  $bar_value_1 = $entity->field_bar->getString();
  // Value 2 returns `[ENCRYPTED]`.
  $bar_value_2 = $entity->field_bar->getValue();
  // Value 3 returns `[ENCRYPTED]`.
  $bar_value_3 = $entity->field_bar[0]->value;
  // Value 4 returns `[ENCRYPTED]`.
  $bar_value_4 = $entity->get('field_bar')->getValue();

  /* @var $field_encrypt_process_entities \Drupal\field_encrypt\FieldEncryptProcessEntities */
  $field_encrypt_process_entities = \Drupal::service('field_encrypt.process_entities');
  $field_encrypt_process_entities->decryptEntity($entity);

  // Value is STILL `[ENCRYPTED]`.
  $bar_value_1 = $entity->field_bar->getString();
  // Value is STILL `[ENCRYPTED]`.
  $bar_value_2 = $entity->field_bar->getValue();
  // Value is STILL `[ENCRYPTED]`.
  $bar_value_3 = $entity->field_bar[0]->value;
  // Value is STILL `[ENCRYPTED]`.
  $bar_value_4 = $entity->get('field_bar')->getValue();
}

/**
 * Implements hook_ENTITY_TYPE_update().
 */
function mymodule_node_update(EntityInterface $entity) {
  // Value 1 returns `[ENCRYPTED]`.
  $bar_value_1 = $entity->field_bar->getString();
  // Value 2 returns `[ENCRYPTED]`.
  $bar_value_2 = $entity->field_bar->getValue();
  // Value 3 returns `[ENCRYPTED]`.
  $bar_value_3 = $entity->field_bar[0]->value;
  // Value 4 returns `[ENCRYPTED]`.
  $bar_value_4 = $entity->get('field_bar')->getValue();

  /* @var $field_encrypt_process_entities \Drupal\field_encrypt\FieldEncryptProcessEntities */
  $field_encrypt_process_entities = \Drupal::service('field_encrypt.process_entities');
  $field_encrypt_process_entities->decryptEntity($entity);

  // Value is STILL `[ENCRYPTED]`.
  $bar_value_1 = $entity->field_bar->getString();
  // Value is STILL `[ENCRYPTED]`.
  $bar_value_2 = $entity->field_bar->getValue();
  // Value is STILL `[ENCRYPTED]`.
  $bar_value_3 = $entity->field_bar[0]->value;
  // Value is STILL `[ENCRYPTED]`.
  $bar_value_4 = $entity->get('field_bar')->getValue();
}

Create node programmatically

Try this Code in MigrateContentController:

<?php

namespace Drupal\migrate_contents\Controller;
use Drupal\taxonomy\Entity\Term;
use Drupal\Core\Controller\ControllerBase;
use Drupal\node\Entity\Node;

class MigrateContentController extends ControllerBase {

 function migrateContent() {
 $updated = 0;
 $data = array(
   'type' => 'ip_range',
   'title' => '192.168.7.100/24',
   'field_ip_range_gw' => '192.168.7.100',
   'field_ip_range_hidden' => '',
   'field_ip_range_blocked' => '192.168.7.200',
   'field_ip_range_access_type' => 'Blocked',
   'field_ip_threshold' => '20',
   'field_ip_range_sec_zone' => 'C2',
   'field_ip_range_vlan_name' => 'Network58',
   'field_ip_range_vlan_tag' => '4054',
   'field_ip_range_comment' => 'Ip ranges from 192.168.7.100 to 192.168.7.255',
 );
 $node = Node::create($data);
 $node->save();
 $updated++;

 return array(
   '#markup' => $updated,
 );
 }
}

Rendering fields

@see https://www.metaltoad.com/blog/drupal-8-entity-api-cheat-sheet @see Long answer https://www.computerminds.co.uk/articles/rendering-drupal-8-fields-right-way

$node->field_my_thing->get(0)->view();

$node->field_my_thing->view();

$node->field_my_thing->view('teaser');

$node->field_my_thing->view([
  'type' => 'image',
  'label' => 'hidden',
  'settings' => array(
    'image_style' => 'larger_thumbnail',
    'image_link' => 'content',
  ),
]);

Form

Render form in twig template @see https://www.developersdocs.com/blog/drupal-8-theming-define-custom-template-file-form

Add cancel button to form

  // Add cancel button to form.
  $form['actions']['cancel'] = [
    '#type' => 'submit',
    '#weight' => 999,
    '#value' => t('Cancel'),
    '#submit' => ['redirect_to_action'],
    '#limit_validation_errors' => [],
    '#attributes' => [
      'class' => ['btn-cancel']
    ]
  ];
/**
 * Cancel form.
 *
 * @param array $form
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 */
function redirect_to_action(array &$form, FormStateInterface $form_state): void {
  $form_state->setRedirect('<front>');
}

Redirect after login

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;

/**
 * Implements hook_form_FORM_ID_alter().
 */
function MYCUSTOMMODULE_form_user_login_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  $form['#submit'][] = 'MYCUSTOMMODULE_user_login_form_submit';
}

/**
 * Custom submit handler for the login form.
 */
function MYCUSTOMMODULE_user_login_form_submit($form, FormStateInterface $form_state) {
  $url = Url::fromRoute('/your/destination/path');
  $form_state->setRedirectUrl($url);
}

Code snippet that can help you to get field values in hook_form_alter in Drupal 8.

Example of entity reference field:

$form['field_name']['widget'][0]['target_id']["#value"]

PHP Example of text field:

$form['field_name']['widget']["#value"]

How to use ConfirmFormBase to confirm the action of delete nodes in drupal 8.

https://codimth.com/blog/web/drupal/how-use-confirmformbase-confirm-action-delete-nodes-drupal-8

Save config form value

/**
 * {@inheritdoc}
 */
public function submitForm(array &$form, FormStateInterface $form_state) {
  parent::submitForm($form, $form_state);
  $config = $this->config(self::CONFIG_SETTINGS);
  $skip = ["submit", "form_build_id", "form_token", "form_id", "op"];
  foreach ($form_state->getValues() as $key => $value) {
    if (!in_array($key, $skip)) {
      $config->set($key, $value);
    }
  }
  $config->save();
}

Taxonomy

How to filter for the top level of a taxonomy in view

@see (https://www.drupal.org/forum/support/post-installation/2010-07-22/how-to-filter-for-the-top-level-of-a-taxonomy-in-view)

  1. Filter > Parent term >is equal to
  2. Leave it blank.

Get entity reference field (taxonomy) value

$termId = $relationshipEntities['profile']->get('field_job_title')->target_id;
$term = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->load($termId);
$termValue = $term->get('field_public')->value;

Get all taxonomy terms from node

function hook_preprocess_node(&$variables) {

  //make sure you have Devel module installed, then you can use ksm() to explore variables
  //ksm($variables['node']);

  if ($variables['node']->hasField('field_permit_city')) {
    //this will give you the referenced terms on the node as objects
    $term_objects = $variables['node']->get('field_permit_city')->referencedEntities();
    $term_labels = [];
    foreach ($term_objects as $term_object) {
      print $term_object->id(); //the id of the term
      print $term_object->label(); //the term title
      $term_labels[] = $term_object->label(); //build an array of term labels
    }
    //send an array of term titles over to the node twig template
    $variables['my_custom_template_variable'] = $term_labels;
  }
}

Load nodes by term id

$termIds = [3,56,456];
 $nodes = \Drupal::entityTypeManager()->getStorage('node')->getQuery()
 ->latestRevision()
 ->condition('field_tags', $termIds)
 ->execute();

Get taxonomy term from node using entity refrence

$term_name = $node
->get('field_subspecialty_category')
->referencedEntities()[0]
->getTranslation($lang)
->label();

Block

Render Block Programtically.

/**
 * Render block.
 *
 * @param string $blockName
 *   Block machine name.
 *
 * @return string|array
 */
function yourModule_render_block(string $blockName): string|array {
  $block = Block::load($blockName);
  if ($block) {
    return \Drupal::entityTypeManager()
      ->getViewBuilder('block')
      ->view($block);
  }
  return '';
}

Set block class for custom block bundles.

@see https://www.drupal.org/node/2724333

/**
 * Implements hook_preprocess_block().
 */

function hops_preprocess_block(&$variables) {
  // Add class for a specific block id.
  $block_id = $variables['elements']['#id'];
  switch ($block_id) {
    case '':
      $variables['attributes']['class'][] = '';
      break;

    default:
      break;
  }

  if (isset($variables['elements']['content']['#block_content'])) {
    $variables['attributes']['class'][] = 'block--'. $variables['elements']['content']['#block_content']->bundle();
  }
}

Ways to find the block ID

drush ev "print_r(array_keys(\Drupal::service('plugin.manager.block')->getDefinitions()));"

If you know part of the ID, you can search for it by adding grep to the end. For example, I have a block that I know has “profile” in the ID, but I don’t know the full ID. I can find it my using this command:

drush ev "print_r(array_keys(\Drupal::service('plugin.manager.block')->getDefinitions()));" | grep profile

Disable block caching in drupal 8

class MYCUSTOMBLOCK extends BlockBase {
  /**
   * {@inheritdoc}
   */
    public function build() {
        return array(
            '#markup' => ""
        );
    }
    /**
     * {@inheritdoc}
     */
    public function getCacheMaxAge() {
        return 0;
    }
}

How can I programmatically display a block?

@see https://drupal.stackexchange.com/questions/171686/how-can-i-programmatically-display-a-block

Content Blocks

$bid = ??? // Get the block id through config, SQL or some other means
$block = \Drupal\block_content\Entity\BlockContent::load($bid);
$render = \Drupal::entityTypeManager()->
  getViewBuilder('block_content')->view($block);
return $render;

Plugin blocks

$block_manager = \Drupal::service('plugin.manager.block');
// You can hard code configuration or you load from settings.
$config = [];
$plugin_block = $block_manager->createInstance('system_breadcrumb_block', $config);
// Some blocks might implement access check.
$access_result = $plugin_block->access(\Drupal::currentUser());
// Return empty render array if user doesn't have access.
// $access_result can be boolean or an AccessResult class
if (is_object($access_result) && $access_result->isForbidden() || is_bool($access_result) && !$access_result) {
  // You might need to add some cache tags/contexts.
  return [];
}
$render = $plugin_block->build();
// In some cases, you need to add the cache tags/context depending on
// the block implemention. As it's possible to add the cache tags and
// contexts in the render method and in ::getCacheTags and
// ::getCacheContexts methods.
return $render;

Config entities

$block = \Drupal\block\Entity\Block::load('config.id');
$render = \Drupal::entityTypeManager()
  ->getViewBuilder('block')
  ->view($block);
return $render;

Views

Make a view to render content based on each category

@see https://drupal.stackexchange.com/questions/98881/how-to-display-multiple-products-under-each-category-in-a-views-grid

Views Tutorials

@see https://drupal-tools.web.cern.ch/how-to/view-tutorials

Make custom filter

@see https://tech.axelerant.com/how-to-use-hookviewsdataalter-in-drupal-8

How to load a view via ajax without breaking ajax functionality?

@see https://pixelthis.gr/content/drupal8-how-load-view-ajax-without-breaking-ajax-functionality

Render a profile view

  $uid = $variables['user']->id();
  $args = [$uid];
  $view = \Drupal\views\Views::getView('profiles');
  if (is_object($view)) {
    $view->setArguments($args);
    $view->setDisplay('user_view');
    $view->preExecute();
    $view->execute();

    // @see https://drupal.stackexchange.com/questions/219475/get-result-view-with-formatter-programmattically
    $profileFields = [];
    foreach ($view->result as $rid => $row) {
      foreach ($view->field as $fid => $field ) {
        $profileFields[$rid][$fid . '-value'] = $field->getValue($row);
        $profileFields[$rid][$fid . '-render'] = $field->render($row);
        $profileFields[$rid][$fid] = $field->advancedRender($row);
      }
    }
    $variables['profileFields'] = $profileFields;
  }

Database

Work with the database in Drupal

@see https://drupaloutsourcing.com/blog/work-database-drupal-8

How do I specify in which database my schema should be created?

<?php

/**
 * @file
 * Install, update and uninstall functions for the d8module module.
 */

function d8module_schema_otherdb() {
  $schema['mytable'] = array(
    'description' => 'My table description',
    'fields' => array(
      'myfield' => array(
        'description' => 'My field description',
        'type' => 'serial',
        'size' => 'medium',
        'not null' => TRUE,
        'unsigned' => TRUE,
      ),
    ),
    'primary key' => array('myfield'),
  );
  return $schema;
}

/**
 * Implements hook_install().
 */
function d8module_install() {
  \Drupal\Core\Database\Database::setActiveConnection('otherdb');
  $connection = \Drupal\Core\Database\Database::getConnection();

  $schema = d8module_schema_otherdb();
  foreach ($schema as $name => $table) {
    $connection->schema()->createTable($name, $table);
  }

  \Drupal\Core\Database\Database::setActiveConnection();
}

/**
 * Implements hook_uninstall().
 */
function d8module_uninstall() {
  \Drupal\Core\Database\Database::setActiveConnection('otherdb');
  $connection = \Drupal\Core\Database\Database::getConnection();

  $schema = d8module_schema_otherdb();
  foreach ($schema as $name => $table) {
    $connection->schema()->dropTable($name);
  }

  \Drupal\Core\Database\Database::setActiveConnection();
}

Entity Query: Get all the node entities between a daterange

@see https://pixelthis.gr/content/entity-query-get-all-node-entities-between-daterange

Drop custom table from database.

// Using this hook in file mymodule.install
function hook_uninstall(){
    $table = 'your_table_name';
    $schema = Database::getConnection()->schema();
    $schema->dropTable($table);
}

Load node by entityQuery

$query = \Drupal::entityQuery('node')
    ->condition('status', 1)
    ->condition('changed', REQUEST_TIME, '<')
    ->condition('title', 'cat', 'CONTAINS')
    ->condition('field_tags.entity.name', 'cats');
$nids = $query->execute();

DATABASE OPERATIONS

Now we can checkout the select, update, and delete operations in Drupal 8. For a field selection use.

$query = \Drupal::database()->select('table_name', 'alias')
  ->fields('alias', ['field1', field2])
  ->condition('field3', $condition);
$results = $query->execute();
while ($content = $results->fetchAssoc()) {
  // Operations using $content.
}

For a single field selection we can use $last_paper_id = $last_paper->fetchField();

For update query execution in Drupal 8, we can use.

$table = 'table_name';
\Drupal::database()->update($table)
  ->fields(array('field1' => $value1, 'field2' => $value2))
  ->condition('field3', $condition1)
  ->condition('field4', $condition2)
  ->execute();

For content deletion.

$query = \Drupal::database()->delete('table_name');
  $query->condition('field1', $condition1);
  $query->condition('field2', $condition2);
  $query->execute();

Now checkout other database statements in Drupal 8 from this Link

Select

For retrieving single value from Table###

/**
 * select table 'node_field_data' from database
 * select field 'title' fropm table 'node_field_data'
 * get data for content type = ‘page’
 * Limit query and only fetch one entry
 */
$getSingleValue = \Drupal::database()->select('node_field_data', 'nfd');
$getSingleValue->addField('nfd', 'title');
$getSingleValue->condition('nfd.type', 'page');
$getSingleValue->range(0, 1);
$title = $getSingleValue->execute()->fetchField();

For retrieving single row from Table###

/**
 * select table 'node_field_data' from database
 * select fields ('nid', 'title', 'status' from table 'node_field_data'
 * get data for content type = ‘page’
 * Limit query and only fetch one entry
 */
$getValues = \Drupal::database()->select('node_field_data', 'nfd');
$getValues->fields('nfd', ['nid', 'title', 'status']);
$getValues->condition('nfd.type', 'page');
$getValues->range(0, 1);
$singleRow = $getValues->execute()->fetchAssoc();

For retrieving single row from Table using Operator (‘IN’)###

/**
 * select table 'node_field_data' from database
 * select fields ('nid', 'title', 'status' from table 'node_field_data'
 * get data for content type IN ‘page’
 * Limit query and only fetch one entry
 */
$getValues = \Drupal::database()->select('node_field_data', 'nfd');
$getValues->fields('nfd', ['nid', 'title', 'status']);
$getValues->condition('nfd.type', 'page' , 'IN');
$getValues->range(0, 1);
$singleRow = $getValues->execute()->fetchAssoc();

With Multiple rows and Table###

/**
 * select table 'node_field_data' from database
 * select fields ('nid', 'title', 'status' from table 'node_field_data'
 * INNER join on Table 'users_field_data' and select field 'name' from table
 * get data for content type IN ‘page’
 * fetch all data with 'nid' as key for result
 */
$content = \Drupal::database()->select('node_field_data', 'nfd');
$content->fields('nfd', ['nid', 'title', 'status']);
$content->addField('ufd', 'name');
$content->join('users_field_data', 'ufd', 'ufd.uid = nfd.uid');
$content->condition('nfd.type', 'page');
$contentData = $content->execute()->fetchAllAssoc('nid');

Update

For update single row###

/**
 * Existing table 'node_clinical_trial' has entry
 * 'secondary progressive MS' on ID 5
 * Lets update to 'Multiple Sclerosis' using update
 */

$content = \Drupal::database()->update('node_clinical_trial', 'nct');
$content->fields('nct', ['disease' => 'Multiple Sclerosis']);
$content->condition('nct.entity_id', 5);
$content->execute();

Delete

For delete single row###

/**
 * Existing table 'node_clinical_trial'
 * has entry 'diabetes' on ID 6
 * which is not MS type disease
 * Lets delete that entry using delete
 */
$content = \Drupal::database()->delete('node_clinical_trial', 'nct');
$content->condition('nct.entity_id', 6);
$content->execute();

Insert

For Adding data

/**
 * Add 'disease' & 'physician' name in Master table
 * 'node_clinical_trial'
 * Use insert
 */

$content = \Drupal::database()->insert('node_clinical_trial');
$content->fields(['disease', 'physician']);
$content->values(['Psoriasis','Dr.Holmes']);
$content->execute();

How to Add Join in Views Query Alter

Debug Query

// Debug.
dump($query->__toString());
dump($query->sqlQuery->__toString());

Services

Inject a Service in Drupal 8

Is a good practice to inject a service whenever is possible. You can verify the service name by Looking at the Drupal Static Service Container wrapper class Reading the code on the Drupal Class you can find the httpClient method:

/**
 * Returns the default http client.
 *
 * @return \GuzzleHttp\Client
 *   A guzzle http client instance.
 */
public static function httpClient() {
  return static::getContainer()->get('http_client');
}

Inject the service

Now that you know the service name http_client Inject into a Class (Controller, Form, Plugin Block, etc)

 /**
   * Guzzle Http Client.
   *
   * @var GuzzleHttp\Client
   */
  protected $httpClient;

 /**
   * Constructs a new Class.
   *
   * @param \GuzzleHttp\Client $http_client
   *   The http_client.
   */
  public function __construct(
    Client $http_client
  ) {
    $this->httpClient = $http_client;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('http_client')
    );
  }

Inject a service into a service Class

// modules/custom/example/example.services.yml
services:
  example.default:
    class: Drupal\example\DefaultService
    arguments: ["@http_client"]
// modules/custom/example/src/DefaultService.php
/**
 * GuzzleHttp\Client definition.
 *
 * @var GuzzleHttp\Client
 */
protected $http_client;
/**
 * Constructor.
 */
public function __construct(Client $http_client) {
  $this->http_client = $http_client;
}

Theme

Adding suggestions to views and preprocessing them

@see https://pixelthis.gr/content/drupal-9-adding-suggestions-views-and-preprocessing-them

How to add html tags (span,div,strong etc) in your Menu Item Title

@see https://pixelthis.gr/content/drupal-8-how-add-html-tags-spandivstrong-etc-your-menu-item-title

How to pass the base url to drupalSettings for global access

/**
 * Implements hook_page_attachments_alter().
 *
 * @inheritdoc
 */
function your_theme_page_attachments_alter(&$page) {
  global $base_url;
  $page['#attached']['drupalSettings']['baseURL'] = $base_url;
}

Access views-view-unformatted.html.twig fields.

{% if title %}
 <h3>{{ title }}</h3>
{% endif %}
{% for row in rows %}
 {%
    set row_classes = [
      default_row_class ? 'views-row',
    ]
  %}
 <div{{row.attributes.addClass(row_classes)}}>
  {# {{- row.content -}} #}
  {{row.content['#row']._entity.title.value}}
  {{row.content['#row']._entity.field_video_url.value}}
  {{file_url(row.content['#row']._entity.field_video_thumbnail.entity.uri.value)}}
 </div>
{% endfor %}

Getting Drupal 8 Field Values in Twig

Article

Rewrite the output of a field

$variables["items"][0]["content"] = "";

Provide frontpage variant

try {
  $isFront = \Drupal::service('path.matcher')->isFrontPage();
}
catch (Exception $e) {
  $isFront = FALSE;
}

Drush

@see https://www.drupal.org/node/1023440

EXPORT DATABASE ON LIVE SERVER

Drush, use this command, which will include only the structure and not the contents of the cache tables, and gzip-compress.

drush sql:dump --gzip --structure-tables-list="cache,cache_*" --result-file='PATH/TO/BACKUPFILE.sql'

If you are using MySQL and have access to the command line, use this command after truncating the cache tables (substituting in your site’s database name, user name, and password):

mysqldump -u'USERNAME' -p'PASSWORD' DATABASENAME | gzip > PATH/TO/BACKUPFILE.sql.gz

IMPORT DATABASE ON LIVE SERVER

If you are using MySQL and have access to the command line, use this command (substituting in your site’s database name, user name, and password; if you made a gzip-compressed backup file, you will also need to uncompress it first):

gunzip < PATH/TO/BACKUPFILE.sql.gz | mysql -u'USERNAME' -p'PASSWORD' DATABASENAME

If you prefer to use Drush, use this command:

drush sql:query --file='PATH/TO/BACKUPFILE.sql.gz'

Unlock bloqued used

drush uublk username to unblock the user

Taking advantage of Drupal Console debugging capabilities

drupal container:debug

If you do not want to see the full list of services you can use | grep http

drupal container:debug | grep http

But you may do not know the service name, then I higly recommend you to use peco interactive filtering tool

drupal container:debug | peco | awk -F ' ' '{print $1}' | xargs drupal container:debug

You can find peco at https://github.com/peco/peco

Apply Patches with composer in drupal 9.

run this command to get the module:. composer require cweagans/composer-patches. Add this to your composer.json file:.

"extra": {
    "enable-patching": true,
    "patches": {
        ...
        ...
     }
}

Generate hshad salat $settings['hash_salt']

drush php:eval "echo \Drupal\Component\Utility\Crypt::randomBytesBase64(55)"

Links

@see https://agaric.coop/blog/creating-links-code-drupal-8

use Drupal\Core\Link;
$link = Link::createFromRoute('This is a link', 'entity.node.canonical', ['node' => 1]);

More flexibility with URL object

use Drupal\Core\Link;
use Drupal\Core\Url;
$link = Link::fromTextAndUrl('This is a link', Url::fromRoute('entity.node.canonical', ['node' => 1]));

Internal links which have no routes

$link = Link::fromTextAndUrl('This is a link', Url::fromUri('base:robots.txt'));

External links:

  use Drupal\Core\Url;
  use Drupal\Core\Link;
  $link = !empty($url) ? Link::fromTextAndUrl($this->t('Newsletter'), Url::fromUri($url, [
    'attributes' => [
      'target' => '_blank',
      'class' => ['button']
    ],
  ])) : '';
  $html_link = $link->toString();

Using the data provided by a user

$link = Link::fromTextAndUrl('This is a link', Url::fromUserInput('/node/1');

Linking entities.

$link = Link::fromTextAndUrl('This is a link', Url::fromUri('entity:node/1'));

Drupal usually expects a render array if you are going to print the link, so the Link object has a method for that

$link->toRenderable();

Add links inside a t() method. Need to pass the link as a string.

$link = Link::fromTextAndUrl('This is a link', Url::fromRoute('entity.node.canonical', ['node' => 1]));
$this->t('You can click this %link' ['%link' => $link->toString()]);

Re-import Installed Module Configuration Using Drush

drush config-import --partial --source=modules/custom/<module_name>/config/install --yes

Twig

Access views-view-unformated.html.twig content.

{# taxonomy field #}
{{ row.content['#row']._entity.field_course_categories.entity.name.value }}
{{ row.content['#row']._entity.field_name[0].value }}
{{ view.field.field_name.original_value }} {# working for translations #}

Paragraphs

Load paragraph fields values

$paragraph = $node->field_paragraph->getValue();
// Loop through the result set.
foreach ( $paragraph as $element ) {
  $p = \Drupal\paragraphs\Entity\Paragraph::load( $element['target_id'] );
  $text = $p->field_name->getValue();
}
{{ drupal_dump(paragraph) }}
{{ drupal_dump(paragraph.field_button_style) }}
{{ drupal_dump(paragraph.field_button_style.value) }}
To print out single fields I usually use, `{{ paragraph.field_action.value }}`. I think that should also work for you.

In the case of an entity reference field, you need to use `{{ paragraph.field_action.entity.field.value }}`.

Paragraph Module

load the paragraphs content.

$node  = \Drupal\node\Entity\Node::load(1);
$paragraph = $node->field_paragraph->getValue();
// Loop through the result set.
foreach ( $paragraph as $element ) {
  $p = \Drupal\paragraphs\Entity\Paragraph::load( $element['target_id'] );
  $text = $p->field_name->getValue();
}

Suggestion paragraph

  // Paragraphs.
  if ($hook === 'paragraph' && !empty($variables['elements']['#paragraph'])) {
    $paragraph = $variables['elements']['#paragraph'];
    $node = \Drupal::routeMatch()->getParameter('node');
    if ($node) {
      $sanitized_view_mode = strtr($variables['elements']['#view_mode'], '.', '_');

      $suggestions[] = 'paragraph__' . $sanitized_view_mode;
      $suggestions[] = 'paragraph__' . $paragraph->bundle() . '__' . $node->bundle();
      $suggestions[] = 'paragraph__' . $paragraph->bundle() . '__' . $node->bundle() . '__' . $sanitized_view_mode;
    }
  }

General

Useful Links

import translation file using drush command

drush locale:import ar sites/default/translation/ar.po --type=customized --override=all -y

Return access not allowed from theme.

/**
 * Implements hook_preprocess_page().
 */
function my_theme_preprocess_page(&$variables) {
  $current_route_name = \Drupal::routeMatch()->getRouteName();
  $current_user = \Drupal::currentUser();
      if (!$current_user->hasPermission('permission name')) {
      throw new \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException();
    }
}

Make field unique field

use Drupal\Core\Entity\EntityTypeInterface;
// if you make a field belongs to a node just change $entity_type to 'node'
function hook_entity_bundle_field_info_alter(&$fields, EntityTypeInterface $entity_type, $bundle) {
  // D8 => $entity_type->id()
  // D9 => $entity->getEntityTypeId()
  if ($entity_type->id() === 'user') {
    if (isset($fields['field_user_id'])) {
      $fields['field_user_id']->addConstraint('UniqueField', ['message' => t('this id is used before with another user')]);
    }
  }
}

PHP: Get current year seasons, per year not just for the current year

@see https://pixelthis.gr/content/php-get-current-year-seasons-year-not-just-current-year

Drupal class => https://api.drupal.org/api/drupal/core%21lib%21Drupal.php/class/Drupal/8

DRUPAL CONSOLE

Installing.

composer require drupal/console:~1.0 --prefer-dist --optimize-autoloader --sort-packages

Middlware for redirect issues

// module.service.yml
services:
  http_middleware.your_module:
    class: Drupal\your_module\RedirectMiddleware
    tags:
      - { name: http_middleware}
<?php

// Service class.
namespace Drupal\your_module;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Drupal\Core\Routing\TrustedRedirectResponse;
use Drupal\Core\Url;

/**
 * Executes redirect before the main kernel takes over the request.
 */
class RedirectMiddleware implements HttpKernelInterface {

  /**
     * The wrapped HTTP kernel.
     *
     * @var \Symfony\Component\HttpKernel\HttpKernelInterface
     */
  protected $httpKernel;

  /**
     * The redirect URL.
     *
     * @var \Symfony\Component\HttpFoundation\RedirectResponse
     */
  protected $redirectResponse;

  /**
     * Constructs a RedirectMiddleware
     * object.
     *
     * @param \Symfony\Component\HttpKernel\HttpKernelInterface $http_kernel
     *   The decorated kernel.
     */
  public function __construct(HttpKernelInterface $http_kernel) {
        $this->httpKernel = $http_kernel;
      }

  /**
     * {@inheritdoc}
     */
  public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = TRUE) {
        $response = $this->httpKernel->handle($request, $type, $catch);
        return $this->redirectResponse ?: $response;
  }

  /**
     * Stores the requested redirect response.
     *
     * @param \Symfony\Component\HttpFoundation\RedirectResponse|null $redirectResponse
     *   Redirect response.
     */
  public function setRedirectResponse(?RedirectResponse $redirectResponse) {
        $this->redirectResponse = $redirectResponse;
  }

}

// USING
$middleware = \Drupal::service('http_middleware.your_module');
$response = new RedirectResponse(Url::fromUserInput($url)->toString());
$middleware->setRedirectResponse($response);

OR

use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;

/**
 * Implements hook_user_login().
 */
function greenacorn_user_login(AccountInterface $account) {
  $roles = $account->getRoles();
  // user.reset.login == reset
  // user.login == login
  $route_name = \Drupal::routeMatch()->getRouteName();
  if ($route_name != 'user.reset.login' && in_array('client', $roles)) {
    $destination = Url::fromUserInput('/my-issues')->toString();
    \Drupal::service('request_stack')->getCurrentRequest()->query->set('destination', $destination);
  }
}

Render view programitcally

 $view = \Drupal\views\Views::getView('geographical_statistics');
// Execute the view.
$view->execute();
$view_result = $view->result;
foreach ($view_result as $obj){
// Code...
}

Show error messages

$config['system.logging']['error_level'] = 'verbose';

Show twitter timeline

<a class="twitter-timeline" href="https://twitter.com/{field_twitterhandle}">
  Tweets by {field_name}</a
>
<script
  async
  src="https://platform.twitter.com/widgets.js"
  charset="utf-8"
></script>

Install drupal console

$composer require drupal/console:~1.0 --prefer-dist --optimize-autoloader --sort-packages --no-update --dev
$composer update drupal/console

Fast site install with lando & config management

$ lando drush site-install standard --account-name=admin --account-pass=admin --db-url='mysql://drupal8:drupal8@database/drupal8' --site-name=Test site
# Get uuid from source
$ drush config-get "system.site" uuid
# @see https://drupal.stackexchange.com/questions/150481/how-can-i-import-the-configuration-on-a-different-site/217126
# Set local uuid
$ drush config-set "system.site" uuid "fjfj34-e3bb-2ab8-4d21-9100-b5etgetgd99d5"

Import drupal 8 configuration into a fresh install website

@see https://www.dannyenglander.com/blog/drupal-8-development-how-import-existing-site-configuration-new-site

$ drush cget system.site uuid
'system.site:uuid': bfb11978-d1a3-4eda-91fb-45decf134e25
$ drush cset system.site uuid bfb11978-d1a3-4eda-91fb-45decf134e25
$ drush ev '\Drupal::entityManager()->getStorage("shortcut_set")->load("default")->delete();'

Install Drupal Console

@see https://drupalconsole.com/docs/en/

$ composer require drupal/console:~1.0 --prefer-dist --optimize-autoloader
$ composer update drupal/console --with-dependencies

Testing

@todo description

~/Sites/siteName ᐅ vendor/bin/dcr web/themes/contrib/file
phpcs --standard=Drupal dir/file
phpcbf --standard=Drupal dir/file
~/Sites/siteName/web ᐅ eslint dir/file.js

Setting up a local developent website standard workflow

@see https://pixelthis.gr/content/drupal-8-setting-local-developent-website-standard-workflow)

Drupal with Docker

@see https://medium.com/drupal-stories/drupal-dev-environment-on-docker-3c795f2ac7aa

Change breadcrunb

/**
 * Implement hook_system_breadcrumb_alter().
 *
 * @param \Drupal\Core\Breadcrumb\Breadcrumb $breadcrumb
 * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
 * @param array $context
 *
 * @return void
 */
function my_module_system_breadcrumb_alter(\Drupal\Core\Breadcrumb\Breadcrumb &$breadcrumb, \Drupal\Core\Routing\RouteMatchInterface $route_match, array $context) {
  if ($breadcrumb !== NULL) {
    $current_route_name = \Drupal::routeMatch()->getRouteName();
    $links = $breadcrumb->getLinks();
    if ($current_route_name === 'entity.user.edit_form') {
      array_pop($links);
      $breadcrumb = new \Drupal\Core\Breadcrumb\Breadcrumb();
      $breadcrumb->setLinks($links);
    }
  }
}

Diable cache in local development

@see https://www.drupal.org/node/2598914

Disable password experation

  $u = \Drupal\user\Entity\User::load(1);
  $u->set("field_password_expiration", "0");
  $u->save();

Replace file after uploaded

    try {
      $values = $form_state->getValues();
      $files = $values['my_file'];
      /** @var \Drupal\file\Entity\File $file */
      $file = File::load($files[0]);
      // Gets content from file.
      $file_real_path = \Drupal::service('file_system')->realpath($file->getFileUri());
      $file_contents = file_get_contents($file_real_path);
      // Saves new file with fixed name and replaces any existing file.
      \Drupal::service('file.repository')
        ->writeData($file_contents, 'private://my_files/import.csv', FileSystemInterface::EXISTS_REPLACE);
      // Deletes the uploaded file.
      $file->delete();
  
    } catch (\Throwable $e) {
      \Drupal::messenger()->addError('check logs messages');
    }

SITE BUILDING CASES

  1. Create parent terms based on parent id @see (https://www.youtube.com/watch?v=v5s6DPc23cI)

Step 1: Create a View to Display Nodes with Taxonomy Terms

Create a View for Content:

Go to Structure > Views > Add view. Name your view (e.g., "Node Taxonomy Hierarchy"). Set Show to Content (since you want to display nodes and their terms). Set Filter by content type to limit the view to the relevant content type if needed. Set the Display Type:

Choose Unformatted list or Table based on your preference. Select Create a Page if you want this view to be accessible via a URL route.

Step 2: Add Relationships to Include Taxonomy Terms and Their Parents

Add Relationships for Taxonomy Terms:

Under Advanced, click Add next to Relationships. Add Parent Term Relationships: Click Add again under Relationships and choose Taxonomy term: Parent term. Select the parent relationship for the taxonomy term. Apply the relationship. Configure the contextual filter: When the filter value is NOT available: Set this to "Provide default value" > Term ID from URL.

Step 3: Add Fields to Display the Terms and Their Parent Terms

Add Fields for Each Level of Terms:

Step 4: Configure Display and Path (Optional)

Set a Path for the View: If you created a page display, set a URL path in Page settings > Path (e.g., /node-terms-hierarchy). Customize the Sorting and Filters (Optional): Add any sorting or filtering options you need. For example, filter by a specific taxonomy vocabulary if your content type uses multiple vocabularies.

Step 5: Save and Test the View

Save your view, and test it by visiting the path you configured. The view should display each node with the associated taxonomy term hierarchy, showing direct terms and all levels of parents.

About

Drupal CMS development tips

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published