Drupal 10
Displaying 1 - 20 of 48REACT: Controlled or Uncontrolled components
The form is one of the most-used HTML elements in web development.
Since the introduction of React, the way forms have been handled has changed in many ways.
In React, there are two ways to handle form data in our components:
The first way is the Controlled Component:
We handle form data by using the state within the component to handle the form data.
The Second way is Uncontrolled Component:
We let the DOM handle the form data by itself in the component.
Code Snippet
Controlled Component
import React, { Component } from 'react';
class App extends Component {
state = {
message: ''
}
updateMessage = (newText) => {
console.log(newText);
this.setState(() => ({
message: newText
}));
}
render() {
return (
<div className="App">
<div className="container">
<input type="text"
placeholder="Your message here.."
value={this.state.message}
onChange={(event) => this.updateMessage(event.target.value)}
/>
<p>the message is: {this.state.message}</p>
</div>
</div>
);
}
}
Tag-Based Caching IN Drupal Views
tag-based caching in Drupal views
Tag-based caching enhances the performance of your website by allowing fine-grained invalidation of cached content.
This is particularly important for dynamic websites where content changes frequently, but you still want to leverage caching to reduce server load and improve page load times.
Messenger Api: How to set message
Drupal set message was deprecated in Drupal 8.5 and will be removed before Drupal 9.
Time for a roundup of this new API and how to use it.
Code Snippet
\Drupal::messenger()->addMessage('This is a regular message');
\Drupal::messenger()->addStatus('This is a status message, meaning status is OK or successful (green).');
\Drupal::messenger()->addError('This is an error message (red)');
\Drupal::messenger()->addWarning('This is a warning message (orange)');
Sending JSON with Basic Authentication Credentials
To post JSON to a server with Basic Authentication credentials, you need to make an HTTP POST or PUT request, include the JSON in the body of the HTTP message, and pass the "Authorization: Basic [token]" HTTP header to the server.
The [token] is a Base64 encoded string of user credentials in the form of a login:password string.
In this POST JSON with a Basic Authentication Credentials Example, we send a POST request with JSON body and "Authorization: Basic [token]" header to the ReqBin echo URL.
Code Snippet
<script>
var USERNAME="admi";
var PASSWORD="chanud";
var person = {
firstName:"tester2",
lastName:"drupal",
userName:"tester2drupal",
eMail:"teter2@drupalvip.com",
pass1:"teter2drupal",
passConfirm:"teter2drupal",
role:"Affiliate"
};
$.ajax({
type: "POST",
url: 'https://mydomain/api/route',
dataType: 'json',
headers: {
"Authorization": "Basic " + btoa(USERNAME + ":" + PASSWORD)
},
data: person,
//data: JSON.stringify(person),
success: function (data) {
$("response").html(data.msg);
},
});
</script>
Drupal 7 to Drupal 9 in an hour, is it possible
Countless blog posts have been written about migrating from Drupal 7 to 8/9/10.
Some recommend how to begin breaking down this rather overwhelming endeavor into manageable pieces.
Others provide concrete technical recommendations for very specific Drupal 7 setups.
DrupalVIP technical notebook & support
How To Attach Library To A Specific Content Type
If you need to upload a library with a module during its operation, in Drupal it's called attaching file.
Attaching a library can be done in several ways depending on your needs.
Remember that the library is always registered by its module or theme name followed by the library name.
DrupalVIP technical notebook & support
Code Snippet
function rwcenter_page_attachments(array &$attachments) {
$attachments['#attached']['library'][] = 'rwcenter/content';
$node = \Drupal::routeMatch()->getParameter('node') ?? \Drupal::routeMatch()->getParameter('node_preview');
if (is_null($node)) {}
else {
if ($node->getType()=='rwcenter') {
$attachments['#attached']['library'][] = 'rwcenter/content';
}
}
}
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.
Code Snippet
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.
Code Snippet
<?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
Code Snippet
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
Code Snippet
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;
}
Drupal module info file
Drupal uses .info files to store metadata about themes and modules.
For modules, the .info file is used for:
- Rendering information on the Drupal Web GUI administration pages;
- Provide criteria to control module activation and deactivation;
- Notifying Drupal about the existence of a module;
- Specifying the module's dependencies on other Drupal projects
for general administrative purposes in other contexts.
This .info file is required for the system to recognize the presence of a module.
Code Snippet
name: Hello World Module
description: Creates a page showing "Hello World".
package: Custom
type: module
core_version_requirement: ^9.4 || ^10
dependencies:
- drupal:link
- drupal:views
- paragraphs:paragraphs
- webform:webform (>=6.1.0)
test_dependencies:
- drupal:image
configure: hello_world.settings
configure_parameters:
pluginId: hello_world_plugin
php: 8.0
hidden: true
required: true
# Set the module lifecycle status deprecated
lifecycle: deprecated
lifecycle_link: https://www.drupal.org/node/3223395#s-aggregator
# Note: do not add the 'version' or 'project' properties yourself.
# They will be added automatically by the packager on drupal.org.
# version: 1.0
# project: 'hello_world'
entityQuery intro and examples
A node can include a few fields.
Every field is a table in the database.
So If I need to find a specific node, doing it with SQL means doing complicated queries, which might have few joins and many conditions, The Drupal platform created a simpler way to deal with it: EntityQuery
DrupalVIP technical notebook & support
Code Snippet
$query = \Drupal::entityQuery('node')
->condition('type', 'page')
->condition('field_some_field', 14)
->accessCheck(TRUE);
$results = $query->execute();
The node access system
All node access modules are queried using hook_node_grants() to assemble a list of "grant IDs" for the user.
This list is compared against the table.
If any row contains the node ID in question (or 0, which stands for "all nodes"), one of the grant IDs returned, and a value of TRUE for the operation in question, then access is granted.
Note that this table is a list of grants; any matching row is sufficient to grant access to the node.
DrupalVIP technical notebook & support
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
Code Snippet
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>
);
}