Ok, please mail me via a contact from or email: wombatbuddy [at] gmail.com
Add info about the restriction of entity route parameters by specified bundles.
The reference: New 'bundle' property for the entity:* route parameters. The '_entity_bundles' route requirement is deprecated.
What about to use
if ( condition ) { render a form }
else { do not render } ?
If you need to left redirection just remove the save() method form the MyEntityForm class. The example
my_module.routing.yml
my_module.edit_nodes:
path: '/edit-nodes'
defaults:
_controller: '\Drupal\my_module\Controller\MyModuleController::editNodes'
requirements:
_permission: 'access content'
MyEntityForm.php
<?php
declare(strict_types=1);
namespace Drupal\my_module\Form;
use Drupal\Core\Form\FormStateInterface;
use Drupal\node\NodeForm;
/**
* Provides a My module form.
*/
final class MyEntityForm extends NodeForm {
/**
* {@inheritdoc}
*/
public function getFormId(): string {
// The dynamic form ID allows for the form to be
// reused on a page.
return parent::getFormId() . '-' . $this->getEntity()->id();
}
/**
* Redirect back to the Edit node forms.
*/
public function save(array $form, FormStateInterface $form_state) {
parent::save($form, $form_state);
$form_state->setRedirect('my_module.edit_nodes');
}
}
MyModuleController.php
<?php
declare(strict_types=1);
namespace Drupal\my_module\Controller;
use Drupal\Core\Controller\ControllerBase;
/**
* Class MyModuleController.
*/
class MyModuleController extends ControllerBase {
/**
* Render node edit forms.
*/
public function editNodes() {
$node1 = $this->entityTypeManager()->getStorage('node')->load(1);
$node2 = $this->entityTypeManager()->getStorage('node')->load(2);
$form1 = $this->entityFormBuilder()->getForm($node1, 'my_form_mode');
$form2 = $this->entityFormBuilder()->getForm($node2, 'my_form_mode');
return [
'#type' => 'container',
'#children' => [
'form1' => $form1,
'form2' => $form2,
],
'#title' => $this->t('Edit Nodes'),
];
}
}
What is the use case, why do you need to have several node forms on one page?
wombatbuddy → created an issue.
wombatbuddy → created an issue.
The reason why patch #2 is needed
In Drupal 11 PHPUnit has been upgraded from 9.5 to 10.5. And in PHPUnit 10 @dataProvider methods must be static.
References
1.
https://www.drupal.org/project/drupal/releases/11.0.0 →
2.
https://www.drupal.org/node/3365413 →
Tasks
1. In 1.0.x branch remove Drupal 11 support (core_version_requirement: ^10.2) and create a new release.
2. Create a new 2.0.x branch for Drupal 11 version (core_version_requirement: ^11), make changes, test it and create a new 2.0.1 release.
To increase your productivity as a developer, you can use the following tools:
1. Codeium.
2. ChatGPT.
3. Drush generate command.
To fix the issue replace the following line
with this one
$current_path_alias = \Drupal::service('path_alias.manager')->getAliasByPath($current_path);
Example of the code using dependency injection:
namespace Drupal\my_module\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Path\CurrentPathStack;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\path_alias\AliasManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a myblock block.
*
* @Block(
* id = "my_module_myblock",
* admin_label = @Translation("MyBlock"),
* category = @Translation("Custom"),
* )
*/
final class MyblockBlock extends BlockBase implements ContainerFactoryPluginInterface {
/**
* Constructs the plugin instance.
*/
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
private readonly CurrentPathStack $pathCurrent,
private readonly AliasManagerInterface $pathAliasManager,
) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): self {
return new self(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('path.current'),
$container->get('path_alias.manager'),
);
}
/**
* {@inheritdoc}
*/
public function build(): array {
$path = $this->pathCurrent->getPath();
$alias = $this->pathAliasManager->getAliasByPath($path);
$build = [];
$build['#markup'] = $this->t('Alias: @alias', ['@alias' => $alias]);
return $build;
}
}
You can store a webform data using State API → or user.data service. You can create a controller which will get data from the state and return them to with the AjaxResponse or JsonResponse. Then you can attach the JavaScript library to the webform 1 → and do the Ajax request to the controller. Also, you can extract the data from the state in the hook_form_FORM_ID_alter for the webform 1 and modify it.
And what’s the best way to set up embedded viewing for interactive content within Drupal?
You may look at the H5P → module.
It looks like you can do it in a Webform submission handler. You may look at the Webform Product → and Commerce Webform Order → modules. Also, I'm available to work on it.
For two different fields you can use the
"Condition Groups" →
. Let's say you need to get nodes in which either the value of the "field_first_name" is equal to Poul or the value of the "field_last_name" is equal to Smith. The example:
?filter[my-group][group][conjunction]=OR
&filter[filter-1][condition][path]=field_first_name
&filter[filter-1][condition][value]=Poul
&filter[filter-1][condition][memberOf]=my-group
&filter[filter-2][condition][path]=field_last_name
&filter[filter-2][condition][value]=Smith
&filter[filter-2][condition][memberOf]=my-group
If you are filtering by only one field, you can use either the "Condition Groups" → or the "IN" → operator. Let's say we want to get all nodes where the value of "field_first_name" is either Poul or Ivan. The example using the "Condition Group":
?filter[my-group][group][conjunction]=OR
&filter[filter-1][condition][path]=field_first_name
&filter[filter-1][condition][value]=Poul
&filter[filter-1][condition][memberOf]=my-group
&filter[filter-2][condition][path]=field_first_name
&filter[filter-2][condition][value]=Ivan
&filter[filter-2][condition][memberOf]=my-group
The example using the "IN" operator:
?filter[field_first_name][condition][path]=field_first_name
&filter[field_first_name][condition][operator]=IN
&filter[field_first_name][condition][value][1]=Poul
&filter[field_first_name][condition][value][2]=Ivan
The code to exclude first level parent terms
// Exclude first level parent terms.
foreach ($terms as $term) {
if ($term->depth != 0) {
$options[$term->name] = $term->name;
}
}
The code for displaying the hierarchy of terms
// Display the hierarchy of the taxonomy terms.
foreach ($terms as $term) {
$indent = str_repeat('-', $term->depth);
$options[$term->name] = $indent . $term->name;
}
The solution without coding
Let's say we have a content type called "Article" that has a taxonomy field called "filed_tag".
1. Install the "Better Exposed Filters Select" module.
2. Add the relationship "Taxonomy term referenced from field_tags" and check the "Require this relationship" option.
3. Add the contextual filter for Name (the "Taxonomy term" category).
4. Change the "Exposed form style" to the "Better Exposed Filters".
5. Scroll down the "Exposed form options" window and select the "BEF Select" Exposed filter widget.
6. To enable multi selection, open the exposed filter settings and select the "In (comma-separated)" operator.
The screensots of the example
1.
https://www.drupal.org/files/change-text-filter-to-select-1.png →
2.
https://www.drupal.org/files/change-text-filter-to-select-2.png →
3.
https://www.drupal.org/files/change-text-filter-to-select-3.png →
4.
https://www.drupal.org/files/change-text-filter-to-select-4.png →
5.
https://www.drupal.org/files/change-text-filter-to-select-5.png →
6.
https://www.drupal.org/files/change-text-filter-to-select-6.png →
7.
https://www.drupal.org/files/change-text-filter-to-select-7.png →
8.
https://www.drupal.org/files/change-text-filter-to-select-8.png →
It seems that since the module ECA → was created, using the Rules module no longer makes sense. Therefore, I decided to stop supporting this module. As an alternative, consider using ECA → and ECA Webform → modules. But if you still want to use the Rules module, you can use the Webform Rules → module.
The patch #2 does not solve the problem for the node Title field. The select still shows tiles of all node bundles.
Did you rebuild the cache after altering the settings.php? (if no, you can do it with the following Drush command: drush cr).
It will be good if we can see line numbers (you can create screenshots, upload images to image hosting and share the links here). Could you at least show the code of 75, 76, 77 lines?
ParseError: syntax error, unexpected '$databases' (T_VARIABLE) in /data/sites/web/www/sites/default/settings.php on line 77 #0
Share more code of the settings.php to we can see what is above the 77 line (it is possible that you missed a semicolon at the end of the line).
You have two options:
1. Create a custom Ajax command, see
1)
Creating custom ajax command In Drupal 8 →
.
2) Creating a Custom Ajax Command in Drupal 8.
2. Create a custom jQuery method and run it using the
InvokeCommand →
, see
How to create custom JQuery function and how to use it?
The example
use Drupal\Core\Form\FormStateInterface;
/**
* Implements hook_form_FORM_ID_alter() for user_register_form.
*/
function my_module_form_user_register_form_alter(&$form, FormStateInterface $form_state) {
// We only redirect if the new user is not created by the administrator.
if ($form['administer_users']['#value'] === FALSE) {
$form['actions']['submit']['#submit'][] = 'my_module_user_register_form_submit';
}
}
/**
* Custom form submission handler for the "user_register_form".
*
* Redirect the newly created user to the user profile page.
*/
function my_module_user_register_form_submit(&$form, FormStateInterface $form_state) {
$form_state->setRedirect('user.page');
}
wombatbuddy → created an issue.
I don't think that this is possible, but you can cached data in the backend instead. See Cache API → . The example
use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheableResponse;
/** implement hook jsonapi_response_alter
*
* @param array $data
* The decoded JSON data to be altered.
* @param \Drupal\Core\Cache\CacheableResponse;
* The response.
*/
function my_module_jsonapi_response_alter(array &$data, CacheableResponse $response) {
$cacheableMetadata = $response->getCacheableMetadata();
$cacheableMetadata->addCacheTags(['node_list:article']);
$cacheableMetadata->addCacheContexts(['url.path.is_front']);
// The maxAge value is set by default.
// $cacheableMetadata->setCacheMaxAge(Cache::PERMANENT);
}
Also, instead of manipulating caching at the response level, you can do it on entity level, see https://stackoverflow.com/a/68523830
You can implement the hook provided by the JSON:API Response Alter → module or create your own EventSubscriber (see the source code of the module). The example:
use Symfony\Component\HttpFoundation\Response;
/**
* Implements hook_jsonapi_response_alter().
*
* Add the 'Cache-Control' header to the JSON:API response.
*
* @param array $data
* The decoded JSON data to be altered.
* @param \Symfony\Component\HttpFoundation\Response $response
* The response.
*/
function my_module_jsonapi_response_alter(array &$data, Response $response) {
$response->headers->set('Cache-Control', 'max-age=3600');
}
You can try to export the missing styles configurations from the first project and then import them into the second project.
If the "Internal Page Cache" module is enabled then it caches pages for anonymous users. What data do you fetch via JSON API?
It looks like the reason of the issue is that empty block is cached. You can try to replace the build() method with the code like this:
public function build() {
$build['#cache']['max-age'] = 0;
$menu = $this->buildLandingPageData();
// We will return a render array that will be cached.
if ($menu['is_landing_page']) {
$build['#data']['menu'] = $menu;
$build['#theme'] = 'ob_landing_page';
}
// We will return an empty render array that will not be cached.
else {
$build['#cache']['max-age'] = 0;
}
return $build;
}
If you want to format a text using HTML tags, you should switch to the "Source" mode. Click on the "Three dots" button in the right up corner of the CKEditor toolbar. This button has the "Show more items" tip when the mouse pointer is on it. After that the menu will appear. In this menu click in the "Source" button. This button has the "Source" tip when the mouse pointer is on it.
If you share the code of the custom block, maybe someone will help.
What template are you talking about?
Also, share the error message (see
"Enable verbose error logging for better backtracing and debugging" →
or visit /admin/reports/dblog).
1. Visit /admin/structure/block
("Structure" > "Block layout").
2. Select a region and click on the "Place block" button.
3. Click on the "+ Add content block" button.
4. Enter a text of the instructions to the "Body" field and click on the "Save and configure" button.
5. Scroll down to the "Visibility" settings, click on the "Role" tab and check the "Authenticated user" option.
6. Click on the "Save block" button.
7. Click on the "Save blocks" button.
Add the info about the "Context Pinning" for Codeium AI assistant.
Added the information about Codeium AI assistant for code development.
If you want a view to be updated using Ajax, you should enable Ajax in the view configuration.
If you can sponsor this feature, you may contact me.
A possible solution is posted here: https://www.drupal.org/forum/support/theme-development/2024-08-23/image-... →
Since the use case assumes that the video field will have a single video file, the following solution is possible:
1. Create a copy of "field.html.twig" and rename it to "field--field-video.html.twig".
2. Copy the following code to the YOUR_THEME.theme file:
use Drupal\image\Entity\ImageStyle;
/**
* Implements hook_preprocess_HOOK() for field_video template.
*/
function YOUR_THEME_NAME_preprocess_field__field_video(&$variables) {
$node = $variables['element']['#object'];
$videoPosterOriginalUrl = $node->field_video_poster->entity->getFileUri();
// Feel free to replace the "medium" image style with yours.
$videoPosterStyledUrl = ImageStyle::load('medium')->buildUrl($videoPosterOriginalUrl);
$variables['items'][0]['content']['#attributes']->setAttribute('poster', $videoPosterStyledUrl);
}
3. Rebuild the caches.
As an alternative solution, you can try the
Video →
module and the patch from the
#3177537
✨
HTML
Needs review
issue.
Also in the
#2954834
✨
Add poster image to HTML5 media videos
Needs work
issue, work is underway to add this feature to the Media module.
I don't fully understand the use case, but it might make sense to use listbox elements that won't allow more than 1 hour for each class. But if you really need to allow more than 10 hours, you could use code like this:
{% set hours = data.2402291330 + data.2402291445 + data.2402291545 + data.2402291630 + data.2403010900 + data.2403011015 + data.2403011130 + data.2403011200 + data.2403011315 + data.2403011430 %}
Total Conference hour(s) credit earned: {{ (hours < 10) ? hours : 10.0 }}
As a solution without creating custom code, you can consider using the
Webform →
module. For example, see
1. Attaching webforms to nodes.
2. Placing webforms as blocks.
The reason why some tests fail is that if a prefix length is invalid then we display different messages on PostgreSQL and MySQL. The solution is to display the same message ("Invalid IP address format.").
wombatbuddy → created an issue.
wombatbuddy → created an issue.
To run tests in parallel on PostgreSQL and MySQL, we also need to set the following variable:
variables:
_PHPUNIT_CONCURRENT: 1
Reference:
https://project.pages.drupalcode.org/gitlab_templates/jobs/phpunit/
Check tests on Drupal with MySQL as some tests fell on Gitlab CI.
wombatbuddy → created an issue.
wombatbuddy → created an issue.
wombatbuddy → created an issue.
Try the
Field Formatter Range →
module. On the screenshot below is the example of formatter settings in the view
https://www.drupal.org/files/show-the-last-value.png →
If you can to sponsor this work, you may contact me via contact form.
If this two different webforms and they are on the same page, then you can accomplish it with a JavaScript code. One way is add a JS to a theme or to a custom module, see "Adding assets (CSS, JS) to a Drupal module via *.libraries.yml" → . Anothe solution is to use the Asset Injector → module. If you need the assistance you can contact me via contact form.
wombatbuddy → created an issue.
wombatbuddy → created an issue.
The screenshot uploaded by you is not available.
You can try to integrate CKEditor 5 plugins in the Drupal module, see "How to integrate CKEditor 5 plugin in the Drupal 9/10 module?". As the example, you can take the
CKEditor 5 Plugin Pack →
module. (If you have a budget for this, I can work on it).