Professional Documents
Culture Documents
Extending Templates
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.
{% 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:
Example:
{{ content|safe_join(", ")|lower }}
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.
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):
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 %}
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' %}
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.
10
$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.
See also
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) {
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.
/src/SampleEvent.php
namespace Drupal\dn_event\Form;
use Symfony\Component\EventDispatcher\Event;
}
You can define multiple custom functions and that can be called while dispatching or subscribing
events.
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.
This function will return events array with event and callback function details as below,
}
Here 800 is the priority.
<?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() {
/**
* Subscriber Callback for the event.
* @param SampleEvent $event
*/
public function doSomeAction(SampleEvent $event) {
}
So in doSomeAction function we are getting fname that we passed in form submission in variable
$event->getReferenceID().
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
https://api.drupal.org/api/drupal/core%21core.api.php/group/events/
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
global $base_url;
<?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 {
global $base_url;
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
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;
}
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.
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.