Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 15

Extending templates

Extending a template means that you can use the contents of an existing template on your template
and apply your own modifications to it.

Twig templates can be extended with the following syntax:

{% extends 'example.html.twig' %}
See more at https://symfony.com/doc/current/templates.html#template-inheritance-and-layouts

In Drupal we can see many examples that use extends in core. e.g.

In core/modules/block/templates/block.html.twig we have:

<div{{ attributes }}>

Filters - Modifying Variables In Twig Templates:


Filters in Twig can be used to modify variables. Filters are separated from the variable by a pipe
symbol. They may have optional arguments in parentheses. Multiple filters can be chained. The
output of one filter is applied to the next.

Example:
{{ content|safe_join(", ")|lower }}

You may have to render an item before you filter it:


{{ item|render|filter }}

Twig comes with many filters built into it, which you can review in their official documentation.
Drupal has a variety of filters native to it.

hese are declared in TwigExtension::getFilters().

Translation filters
trans
This filter (alternatively, t) will run the variable through the Drupal t() function, which will return a
translated string. This filter should be used for any interface strings manually placed in the template
that will appear for users.

Example:
<a href="{{ url('<front>') }}" title="{{ 'Home'|t }}" rel="home" class="site-logo"></a>

An example with replacements (see documentation for the t() function for more details):

{% set name = '@label Introduction' |t({'@label': node.title.value}) %}


placeholder
This filter escapes content to HTML and formats it using drupal_placeholder(), which makes it display
as emphasized text.

Example:
{% trans %}Submitted on {{ date|placeholder }}{% endtrans %}

Unsafe translation
Some patterns are unsafe and should not be used because they pass a variable directly to translation.
This not only inflates the list of strings for translation but is also a potential vulnerability, particularly
if the output can be entered by a user. Some examples of improper translation:

{# DO NOT DO THIS #}
{{ var1|t }}
{{ var1|placeholder }}
{% trans %}{{ var1 }}{% endtrans %}

Including Part Template

Many themers prefer to keep header/footer codes in a separate file and call the file in page.html.twig

Process
Let's say you have created following file in your theme folder for the header:

THEME_NAME/templates/includes/header.html.twig
And now you want to include this file in:

page.html.twig
The recommended method
The correct method for Drupal 8 themes is to use Twig namespaces to declare the current theme
"templates" directory. Here is an example:

{% include '@THEME_NAME/includes/header.html.twig' %}

Services and dependency injection in Drupal 8+


6 Nov 2023 — Dependency injection is the preferred method for accessing and using services
in Drupal 8+ and should be used whenever possible. Rather than ...

Drupal 8+ introduces the concept of services to decouple reusable functionality and makes these
services pluggable and replaceable
by registering them with a
service container.
In Drupal 8+ speak, a service is any object managed by the services container.

Drupal 8+ introduces the concept of services to decouple reusable functionality and makes these
services pluggable and replaceable by registering them with a
service container.

Laravel hacking is a common problem that can further cause vulnerabilities to other supporting XSS
and different files. Most casualties of website hacks find that their site pages are diverted to other
malicious websites.

Laravel offers following security features to allow developers reduce the Laravel vulnerabilities in the
application.

Laravel Authentication System


Reduce Laravel Vulnerabilities From CSRF (Cross Site Request Forgery)
Protection against XSS (Cross Site Scripting)
SQL Injection
Improve Laravel Application Security
Laravel Security Packages

How do I pass variables to JavaScript?


Asked 7 years, 9 months ago
Modified 1 year, 7 months ago
Viewed 28k times

10

In your MODULENAME.module file:

$testVariable = 'himanshu';
drupal_add_js(array('MODULENAME' => array('testvar' => $testVariable)), array('type' => 'setting'));
drupal_add_js(drupal_get_path('module', 'MODULENAME') . '/MODULENAME.js');
In MODULENAME.js file:

(function($) {
Drupal.behaviors.MODULENAME = {
attach: function (context, settings) {
alert(settings.MODULENAME.testvar);
}
};
})(jQuery);

$element['#attached']['js'][] = array(
'data' => array('myModule' => array('basePath' => base_path())),
'type' => 'setting',
);
This variable would then be referenced from JS side like:

console.log( Drupal.settings.myModule.basePath );
function hook_views_query_alter
Same name and namespace in other branches
Alter the query before it is executed.

Parameters
\Drupal\views\ViewExecutable $view: The view object about to be processed.

\Drupal\views\Plugin\views\query\QueryPluginBase $query: The query plugin object for the query.

See also

In Drupal 8, best practice is to use hook_views_query_alter() in MYMODULE.views_execution.inc file.


If instead it is placed in MYMODULE.views.inc, it will be executed only when rebuilding the views
cache, causing your view to function properly once and then not subsequently.

MYMODULE.views_execution.inc file should have this structure...

use Drupal\views\ViewExecutable;
use Drupal\views\Plugin\views\query\QueryPluginBase;

/**
* Implements hook_views_query_alter().
*/
function MYMODULE_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {

// Only for my_view view.


if ($view->id() == 'my_view') {
// some action
}

How to create custom event and subscribe to core events in


Drupal 9

Event Subscriber – A function which reacts to an event.


Event Dispatcher – process of triggering events throughout the system
You have to understand the below points about event concept in Drupal.

Event Subscribers – Sometimes called “Listeners”, are callable methods or functions that react to an
event being propagated throughout the Event Registry.
Event Registry – Where event subscribers are collected and sorted.
Event Dispatcher – The mechanism in which an event is triggered, or “dispatched”, throughout the
system.
Event Context – Many events require a specific set of data that is important to the subscribers to an
event. This can be as simple as a value passed to the Event Subscriber, or as complex as a specially
created class that contains the relevant data.
Here we are going to discuss the topics below in this article.

How to define a event in Drupal 9?


How dispatch an event in Drupal 9?
How to subscribe the dispatched event in Drupal9?
How to subscribe to Core events in Drupal 9?
Here we are experimenting with the custom module dn_event.

Download sample module here

How to define an event in Drupal 9?


In order to define an event , create a class SampleEvent in your custom module /src path.

/src/SampleEvent.php

Extend class from Symfony\Component\EventDispatcher\Event

So sampleEvent class will look like below,

namespace Drupal\dn_event\Form;

use Symfony\Component\EventDispatcher\Event;

class SampleEvent extends Event {

const SUBMIT = 'event.submit';


protected $referenceID;

public function __construct($referenceID)


{
$this->referenceID = $referenceID;
}

public function getReferenceID()


{
return $this->referenceID;
}

public function myEventDescription() {


return "This is as an example event";
}

}
You can define multiple custom functions and that can be called while dispatching or subscribing
events.

How to dispatch an event in Drupal 9?


We can define events anywhere in our module code. First we have to include namespace.

use Drupal\dn_event\SampleEvent;
Then when you want to dispatch an event, add below code snippets in that place, here we are
dispatching SampleEvent in a form submission function. Here fname is the one of the form field.

// load the Symfony event dispatcher object through services


$dispatcher = \Drupal::service('event_dispatcher');

// creating our event class object.


$event = new SampleEvent($form_state->getValue('fname'));

// dispatching the event through the ‘dispatch’ method,


// passing event name and event object ‘$event’ as parameters.
$dispatcher->dispatch(SampleEvent::SUBMIT, $event);
In Above code we are setting referenceID value as fname,

How to subscribe to the dispatched event in Drupal 9?


Create the class file in module path /src/EventSubscriber/SampleEventSubScriber.php

We have to extend this class with EventSubscriberInterface

In this class we have to define function getSubscribedEvents function

This function will return events array with event and callback function details as below,

public static function getSubscribedEvents() {

$events[SampleEvent::SUBMIT][] = array('doSomeAction', 800);


return $events;

}
Here 800 is the priority.

Complete code of SampleEventSubScriber.php provided below.

<?php

/**
* @file
* Contains \Drupal\dn_event\ExampleEventSubScriber.
*/

namespace Drupal\dn_event\EventSubscriber;

use Drupal\Core\Config\ConfigCrudEvent;
use Drupal\Core\Config\ConfigEvents;
use Drupal\dn_event\SampleEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
* Class ExampleEventSubScriber.
*
* @package Drupal\dn_event
*/
class SampleEventSubScriber implements EventSubscriberInterface {

/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {

$events[SampleEvent::SUBMIT][] = array('doSomeAction', 800);


return $events;

/**
* Subscriber Callback for the event.
* @param SampleEvent $event
*/
public function doSomeAction(SampleEvent $event) {

\Drupal::messenger()->addMessage("The Example Event has been subscribed, which has bee


dispatched on submit of the form with " . $event->getReferenceID() . " as Reference");
}

}
So in doSomeAction function we are getting fname that we passed in form submission in variable
$event->getReferenceID().

Tag event subscriber with event_subscriber

Create dn_event.services.yml file in module path. Add below in this file.

services:
sample_events.event_subscriber_sample:
class: Drupal\dn_event\EventSubscriber\SampleEventSubScriber
tags:
- { name: 'event_subscriber' }
So in this sample module, we have one form , which can bee accessed using /student/add page.

In routing.yml

dn_event.add_student:
path: '/students/add'
defaults:
_title: 'Add Students'
_form: '\Drupal\dn_event\Form\StudentForm'
requirements:
_access: 'TRUE'
Clear the cache. The event will be dispatched while submitting this form and the subscribe handler
captures the event.
Access the page /students/add

You can see the form below.

How to subscribe to Core events in Drupal 9?


Below page provides list of events already available in Drupal Core,

https://api.drupal.org/api/drupal/core%21core.api.php/group/events/

So in this section we are going to create a subscriber that subscribes KernelEvents::REQUEST

You can see list of available kernel events in Drupal in below page.

https://api.drupal.org/api/drupal/vendor%21symfony%21http-kernel%21KernelEvents.php/class/
KernelEvents/9.3.x

So this kernel request event will be dispatched when a Request event occurs at the very beginning of
request dispatching. For example if hitting a custom form URL in your browser Kernel Request event
occurs first before redirection to the page.

So here, we are redirecting to log in page if user is not logged in while accessing the URL –
/students/add

So we will subscribe to the kernel request event,

Create class RedirectEventSubscriber class in module path


/src/EventSubscriber/RedirectEventSubscriber.php

In this class below provided getSubscribedEvents() function.

public static function getSubscribedEvents() {


$events[KernelEvents::REQUEST][] = array('checkAuthStatus');
return $events;
}
Here checkAuthStatus is the call back function like doSomeAction in the previous example, so in
this we are writing our actual action when a kernel request event occurs. Based on the below
condition we are redirecting to the login page.

public function checkAuthStatus(GetResponseEvent $event) {

global $base_url;

if(\Drupal::routeMatch()->getRouteName() == 'dn_event.add_student' && \Drupal::currentUser()-


>isAnonymous()){
$response = new RedirectResponse($base_url . '/user/login', 301);
$event->setResponse($response);
$event->stopPropagation();
return;
}
}
Here dn_event.add_student is the route name of path /students/add in routing.yml file.
See full source code of the file /src/EventSubscriber/RedirectEventSubscriber.php

<?php

namespace Drupal\dn_event\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;

/**
* Event subscriber subscribing to KernelEvents::REQUEST.
*/
class RedirectEventSubscriber implements EventSubscriberInterface {

public function checkAuthStatus(GetResponseEvent $event) {

global $base_url;

if(\Drupal::routeMatch()->getRouteName() == 'dn_event.add_student' && \Drupal::currentUser()-


>isAnonymous()){
$response = new RedirectResponse($base_url . '/user/login', 301);
$event->setResponse($response);
$event->stopPropagation();
return;
}
}

public static function getSubscribedEvents() {


$events[KernelEvents::REQUEST][] = array('checkAuthStatus');
return $events;
}
}
Finally update services.yml with RedirectEventSubscriber class.

services:
sample_events.event_subscriber_sample:
class: Drupal\dn_event\EventSubscriber\SampleEventSubScriber
tags:
- { name: 'event_subscriber' }

dn_event.redirect_subscriber:
class: Drupal\dn_event\EventSubscriber\RedirectEventSubscriber
arguments: []
tags:
- {name: event_subscriber}
Contents
What is a queue?
[module name].info.yml
Adding items to the queue
Custom queue worker
Queue UI
Enabling the modules
Queue Manager Interface
Inspection of queue items
Sections
Title
What is a queue?
Body
A queue is simply a list of stuff that gets worked through one by one, one analogy could be a
conveyor belt on a till in a supermarket, the cashier works through each item on the belt to scan
them.

Queues are handy in Drupal for chunking up large operations, like sending emails to many people. By
using a queue, you are trying to avoid overloading the servers resources which could cause the site
to go offline until the resources on the server are free'd up.

Title
[module name].info.yml
Body
First we need to create a new folder for our module in the modules/custom folder called for example
custom_queue, then just like in the other tutorials previous to this one, we need to tell Drupal that
we have added a new module by adding a file inside the custom_queue module called
custom_queue.info.yml. The contents of this file should look a bit like the below, note I have set a
dependency for the queue_ui module, so I wouldn't enable the module yet if you have downloaded
that module

name: 'Custom queues'


type: module
description: 'The description.'
package: Custom
core: 8.x
core_version_requirement: ^8 || ^9
dependencies:
- drupal:queue_ui
Title
Adding items to the queue
Body
There are a few different ways of adding items to the queue. For example we can use nod insert/
update node hooks to add nodes to the queue on creation and update.

Below is some code that you can use to add items to the queue that can be dropped into your logic/
hook of choice. The code grabs the queue by the name that will be used in our queue worker.

Then create a new object and add your required properties and assign the values as needed then call
the createItem function and pass the object you just created as a parameter to the function.

$queue = \Drupal::service('queue')->get('custom_queue');
$item = new \stdClass();
$item->nid = $node_id;
$item->update = $update;
$queue->createItem($item);
Title
Custom queue worker
Body
First of all, what are queue workers, they are designed to work through each item in the queue that
the worker is assigned to and applies the supplied logic to each item as needed. The queue worker
generally processes items on cron, but you can use drush to work through the queue items.

Now inside your module, create a src folder with a folder called Plugin inside, then inside that folder
create another folder called QueueWorker. Now create a new php file that will contain your queue
worker php class. In our example, the class would be called CustomQueue.php.

The full class is below, but I want to first draw attention to an annotation towards the top of the
class, this tells Drupal that we are adding a queue worker with the item of custom_queue, the
human name of Custom Queue and that on cron, the queue worker should process as many items as
it can in 60 seconds. If there are still items to process, then when the cron job runs again, the queue
worker will process some more and it will keep doing this until all items have been processed.

* @QueueWorker(
* id = "custom_queue",
* title = @Translation("Custom Queue"),
* cron = {"time" = 60}
*)
In my below example queue worker, I am bringing in the Entity Type Manager and Database
Connection functionality into the class via dependency injection. But you should bring in the
functionality as needed.

Finally add a function for processItem, which takes one parameter which is the queue item. You can
then access each property of the object and process the queue item as you need too. You don't need
to worry about removing the item from the queue once finished, this will be done for you.

<?php

namespace Drupal\custom_queue\Plugin\QueueWorker;

use Drupal\Core\Annotation\QueueWorker;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Queue\QueueWorkerBase;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
* Custom Queue Worker.
*
* @QueueWorker(
* id = "custom_queue",
* title = @Translation("Custom Queue"),
* cron = {"time" = 60}
*)
*/
final class CustomQueue extends QueueWorkerBase implements ContainerFactoryPluginInterface {

/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;

/**
* The database connection.
*
* @var \Drupal\Core\Database\Connection
*/
protected $database;

/**
* Main constructor.
*
* @param array $configuration
* Configuration array.
* @param mixed $plugin_id
* The plugin id.
* @param mixed $plugin_definition
* The plugin definition.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\Core\Database\Connection $database
* The connection to the database.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition,
EntityTypeManagerInterface $entity_type_manager, Connection $database) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->entityTypeManager = $entity_type_manager;
$this->database = $database;
}

/**
* Used to grab functionality from the container.
*
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
* The container.
* @param array $configuration
* Configuration array.
* @param mixed $plugin_id
* The plugin id.
* @param mixed $plugin_definition
* The plugin definition.
*
* @return static
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id,
$plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('entity_type.manager'),
$container->get('database'),
);
}

/**
* Processes an item in the queue.
*
* @param mixed $data
* The queue item data.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* @throws \Drupal\Core\Entity\EntityStorageException
* @throws \Exception
*/
public function processItem($data) {
$nid = $data->nid;
$update = $data->update;

// Processing of queue items logic goes here.


}

}
Title
Queue UI
Body
There is a useful module to being able to see how many items are in the queue and be able to view
the contents of each queue item. This module is usefully known as the Queue UI module. The project
page is available at: https://www.drupal.org/project/queue_ui.
You can then use composer to add the module to your site, using a command along the lines of the
below.

composer require 'drupal/queue_ui:^2.2'


Title
Enabling the modules
Body
Once the module has been added, you can go to enable your custom queue worker module, note
that when you enable the module, it should also enable the queue ui module. The site will notify you
that there are other modules to enable, you simply agree to this and Drupal will enable the queue ui
module for you.

Destructors
Constructors
Interfaces
Class type hints
Abstract classes
Static properties and methods
Final properties and methods
A whole suite of magical methods
Now, objects are both assigned and passed by reference rather than by value. So, the necessity to
liberally sprinkle ampersands throughout your code is not required.

Features of PHP 5
PHP5 comes with a completely rewritten MySQL from older versions. Numerous developers power
their websites with MySQL.
The latest versions of MySQL, 4.1 and 5.0, showcases many new features, some of which demand
notable changes to the extension. Therefore, PHP 5 comes with a completely new and enhanced
MySQL extension. Dubbed MySQLi for the MySQL Improved extension, MySQL Improved offers:
Prepared statements
SSL connections
Multi-query functions
Bound input and output parameters
PHP 5 fixes the main flaws in PHP 4’s XML extensions. The new XML extensions, firstly, allow you to
work together as a unified whole. Secondly, extensions are standardized on a single XML library:
libxml2. Thirdly, they fully comply with W3 specifications. Fourthly, you can efficiently process data
and lastly provide you with the right XML tool for your job.
PHP 5 gives a different model of error checking than what’s available in PHP 4. It’s known as
exception handling. With the help of exceptions, you’re freed from the necessity of checking the
return value of every function. Alternatively, you can set apart programming logic from error
handling and put them in adjoining blocks of code.
PHP 5 now has a usable SOAP extension (Simple Object Access Protocol) written in C. Simple Object
Access Protocol or SOAP has become one of the essential elements for web services and PHP5
upholds SOAP clients with/without WSDL files (Web Service Definition Language).
Iterator is a new feature added with PHP5. This iterator assists us to use ‘for each’ loop with the help
of several data structures like database results, directory listing, and XML documents.
PHP 7 has been equipped with the ability to use a null coalescing operator. This operator assigns a
variable on the basis of whether or not the first value is null. The benefit of this operator is that it
reduces the syntax required to check if a value is null and assign something else.
The old-fashioned error handling doesn’t exist anymore and has been replaced with object-oriented
exceptions. This change is implemented to make it easier for developers to find and fix errors in their
code.
The most interesting new feature of PHP 7 is that PHP7 is now 2x faster than PHP 5. PHP 7 combines
static type hinting, which makes it possible for many of the tools available for static analysis and
static error detection.
PHP7 allows for quality, scalable and cost-effective development.
The syntax for variable dereferencing has been changed, thereby making it more harmonious.

You might also like