Skip to main content

Code Example

Displaying 1 - 20 of 45

Creating a Block in Drupal 10 Programmatically

Drupal's great feature is Custom Block. blocks are easy and fast to set in any region, with Drupal9 you can even set the same block in a few regions.
There are a few technical options to create a block, here we will overview the programming option only.
so, what is a block?
Blocks are chunks of content with ID and classes which can be placed in manipulated within the page. 

namespace Drupal\my_module\Plugin\Block;

use Drupal\Core\Block\BlockBase;
use Drupal\Core\Block\BlockPluginInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Cache\UncacheableDependencyTrait;

/**
 * Provides a 'SetTask' Block.
 *
 * @Block(
 *   id = "dashboard_newtask_block",
 *   admin_label = @Translation("Dashboard New Task"),
 *   category = @Translation("DrupalVIP"),
 * )
 */
class NewTaskBlock extends BlockBase implements BlockPluginInterface {
    use UncacheableDependencyTrait;
    
    /**
    * {@inheritdoc}
    */
    public function build() {
        // Do NOT cache a page with this block on it.
        \Drupal::service('page_cache_kill_switch')->trigger(); 
        // build from form               
        $build = \Drupal::formBuilder()->getForm('Drupal\drupalvip_dashboard\Form\NewTaskForm');
        $build['#attributes']['class'][] = 'my_class';
        $build['#cache']['max-age'] = 0;
        $build['#cache']['contexts'] = [];
        $build['#cache']['tags'] = [];                   
        return $build;
    }       
  
    /**
    * {@inheritdoc}
    */
    public function blockForm($form, FormStateInterface $form_state) {
        $form = parent::blockForm($form, $form_state);
        $config = $this->getConfiguration();
        $form['block_note'] = [
            '#type' => 'textfield',
            '#title' => $this->t('Note'),
            '#description' => $this->t('block note '),
            '#default_value' => isset($config['block_note']) ? $config['block_note'] : '',
        ];
        return $form;
    }  

    /**
    * {@inheritdoc}
    */
    public function blockSubmit($form, FormStateInterface $form_state) {
        parent::blockSubmit($form, $form_state);        
        $values = $form_state->getValues();
        $this->configuration['block_note'] = $values['block_note'];
    }    
    
} // end of class

Custom Block: Create fast and simple

Blocks are individual pieces of your site’s web page layout. They are placed inside the regions of your theme, and can be created, removed, and rearranged in the Block layout (admin/structure/block) administration page.

Examples of blocks include the Who’s online listing, the main navigation menu, and the breadcrumb trail. The main page content is also a block.

<?php

namespace Drupal\basic_module\Plugin\Block;

use Drupal\Core\Block\BlockBase;

/**
 * Block annotation
 * 
 * @Block(
 *      id = "basic_block",
 *      admin_label = @Translation("Basic Block"),
 * )
 */
class BasicBlock extends BlockBase {
   /**
     * {@inheritDoc}
     */
    public function build() {
        $markup = '';
        $markup .= '<div>';
        $markup .= '    <p>Anything can come here: code, variables, html, etc.  </p>' ;
        $markup .= '</div>';
        return [
            '#type' => 'markup',
            '#markup' => $markup,
        ];
    }    
    
} // end of class

Success Message After Submitting Form

In building a custom form you must keep in mind a few issues:

elements, functionality, and response for best user experience 

DrupalVIP technical notebook & support

public function submitForm(array &$form, FormStateInterface $form_state) {
  $this->logger('user')->notice('Deleted %ip', ['%ip' => $this->banIp,]);
  $this->messenger()->addStatus($this->t('The IP address %ip was deleted.', [    '%ip' => $this->banIp,  ]));
  $form_state->setRedirectUrl($this->getCancelUrl());
}

Open Ajax Modal Dialog from Controller

Dialogs are often called dialog boxes, modal windows, or pop-up windows. 
Whatever you call them, they are a quick and easy way to display additional information without reloading the entire page. 
Dialog boxes can display just some static text, any node or form of your page, a views page, or any custom markup you'll feed them. 

DrupalVIP technical notebook & support

        public function requestResidenceUpload(Request $request): AjaxResponse {
            $arg = $request->get('arg1');
            
            // Add an AJAX command to open a modal dialog with the form as the content.      
            $response = new AjaxResponse();
            $modal_form = $this->formBuilder->getForm('Drupal\mymodule\Form\MyForm', $arg);
            $response->addCommand(new OpenModalDialogCommand('Upload', $modal_form, ['width' => 600, 'height'=>600]) );
            return $response;        
        } 

How to pass a Function as a Prop

Props or properties in react are a functional argument by which different components communicate with each other. 
Props is just a data/information that allows us to pass in JSX tags. 
With the help of props, we can pass values like JavaScript objects, arrays or functions, etc.

DrupalVIP technical notebook & support

import React from "react";

function Course(props) {
  return (
    <div>
      <ul>
        <li>{props.courseName}</li>
      </ul>
    </div>
  )
}

function App() {
  return (
    <div>
      <h1>Guvi Courses</h1>
      <Course courseName="Full Stack Development"  />
    </div>
  );
}

export default App;

Fetch and display data from API in React js

When you develop an application, you will often need to fetch data from a backend or a third-party API. 
In this article, I will try to go through the process of fetching and displaying data from a server using React Fetch.

DrupalVIP technical notebook & support

import React, { useEffect, useState } from "react";

function handleClick() {
    alert('You clicked node ');
}

export default function RWTaskIssues({nodeid}) {        
    const FetchAPI = '/rwtask/issues?task=' + nodeid + '&op=get';
    console.log("api fetch: " + FetchAPI);
    
    const [issues, setIssues] = useState([]);
    const fetchData = () => {
        fetch(FetchAPI)
            .then(response => {
                return response.json();
            })
            .then(response => {
                console.log("response data: " + response.data.items);
                setIssues(response.data.items);
            });
    };

    useEffect( () => {
        fetchData();
    }, []) ;   
    
    console.log("issues data: " + issues);
    
    return (
        <div className="block block-layout-builder block-field-blocknoderwtaskfield-rwtask-issue">
            <h2 className="block-title">תיאור הבעיה</h2>
            <div className="block-content">               
                {issues.length > 0 && (
                    <div className="field field-name-field-rwtask-issue field-type-text-long field-label-hidden field-items">
                        {issues.map(item => (
                            <div key={item.key} className="field-item" dangerouslySetInnerHTML={{__html: item.value}} />
                        ) ) }
                    </div>
                )}
                <button onClick={handleClick}>
                    Edit
                </button>            
            </div>
        </div>
    );        
}

React in Drupal - starter

This is a starter-kit or tips to ignite the use of react under Drupal

import React from 'react';
import ReactDOM from 'react-dom';

let helloElement = React.createElement(
  "h1",
  { id: "greeting", className: "hello" },
  "Hello, World!"
);
let rootElement = document.getElementById("react-root");
ReactDOM.createRoot(rootElement).render(helloElement);

How to prevent drupal to filter out style attribute from custom block code

When creating custom block, the inherit function build() return an element, usualy it include tag: #markup,

but it seems that it filter out the attributes, so how can we overwrite it correctly without the filter?

In other words we want to prevent drupal to filter out style attribute from custom block code

The '#markup' is filtered in ->ensureMarkupIsSafe(), which is called from within ->doRender().

The same does not apply to '#children' .

 

Custom controller with JSON response

how to create a custom controller with JSON response in Drupal 8.

this might work on Drupal 9 and 10, but I never tested it on these versions.

use Symfony\Component\HttpFoundation\JsonResponse;

/**
 * Class JsonApiArticlesController
 * @package Drupal\mymodule\Controller
 */
class JsonApiArticlesController {

  /**
   * @return JsonResponse
   */
  public function index() {
    return new JsonResponse([ 'data' => $this->getData(), 'method' => 'GET', 'status'=> 200]);
  }

  /**
   * @return array
   */
  public function getData() {

    $result=[];
    $query = \Drupal::entityQuery('node')
      ->condition('type', 'article')
      ->sort('title', 'DESC');
    $nodes_ids = $query->execute();
    if ($nodes_ids) {
      foreach ($nodes_ids as $node_id) {
        $node = \Drupal\node\Entity\Node::load($node_id);
        $result[] = [
          "id" => $node->id(),
          "title" => $node->getTitle(),
        ];
      }
    }
    return $result;
  }
}
use Symfony\Component\HttpFoundation\JsonResponse;

// if you know the data to send when creating the response
$response = new JsonResponse(['data' => 123]);

// if you don't know the data to send or if you want to customize the encoding options
$response = new JsonResponse();
// ...
// configure any custom encoding options (if needed, it must be called before "setData()")
//$response->setEncodingOptions(JsonResponse::DEFAULT_ENCODING_OPTIONS | \JSON_PRESERVE_ZERO_FRACTION);
$response->setData(['data' => 123]);

// if the data to send is already encoded in JSON
$response = JsonResponse::fromJsonString('{ "data": 123 }');

Form Element 'table' with TableDrag and TableSelect

Building and rendering a table required writing a custom/dedicated theme function for most tables in Drupal 7.

Drupal 8 introduces a new element '#type' => 'table', which comes with built-in, optional support for TableDrag and TableSelect, and which requires no more custom plumbing for most use-cases.

Note: The following conversion example shows both TableDrag and TableSelect in a single table for brevity, but they are usually not combined in a single table.

Drupal let you create your own custom middlewares

Middleware can be used to intercept and modify HTTP requests before they reach the application, allowing developers to inspect and filter the requests based on specific criteria. 

This can be useful for adding additional security measures, handling errors and exceptions, or modifying the request/response header.