# Question
Title: Similar content with contextual filter by url
There are two types of content (as an example):

1. fruits
2. vegetables

They share the same vocabulary and similar terms. Catalog structure:

```
-Fruits
--juices
---for children
---for men
---for women
-Vegetables
--juices
---for children
---for men
---for women

```

Url path for mango: /fruits/mango

I want to show similar vegetable juices for children in the fruit node, if the path matches the difference only with the first part of the url.

Need to show similar content if url path matches /%/juices/for-children

I found this solution (Create view with path relative to taxonomy term), but it doesn’t help me, because the paths change there at the end.

# Answer
The only way I was able to solve this problem was by installing the module https://www.drupal.org/project/term\_reference\_tree

And then I manually match the related terms together. Like in previous versions in drupal (6,7)

Then created a view.

Relationship:

* taxonomy term (with limit by vocabulary)
* field\_related\_terms (the field you have created with Taxonomy Term Reference Tree Widget)

Contextual Filter: taxonomy term: field\_related\_terms (with relationship)

When the filter value is NOT in the URL

* **Provide default value**
* **Term id from URL**
* **Load default filter for related taxonomy blocks**
* **Filter by items that contain any of the terms**

In section more: **Allow multiple values**

This is how it works. But how to achieve this only in a view without a module and without manual matching of related terms, I did not understand.
> 0 votes

---
Tags: 8, views, taxonomy-terms
---


# Question
Title: Get raw node id value in views template without errors
I need to get the raw node id value in a views template, but the debug comments are interfering. Based on this issue I am using the following:

```
{{ row.columns.nid |render|striptags|trim }}

```

Which actually works, but I am also getting errors in the dblog relating the render method:

```
User error: "0" is an invalid render array key
User error: "wrapper_element" is an invalid render array key
User error: "attributes" is an invalid render array key
User error: "default_classes" is an invalid render array key

```

Is there a better way to access the raw nid in a views template?

# Answer
> 1 votes
I assume this is about a views table template, then this topic might help How to access raw data in twig template using views table format.

Otherwise you could simply use

```
{{ row._entity.id }}

```

---
Tags: views, 9
---


title: Hide pane based on cart state

text:
# Question
Title: Hide pane based on cart state
Can anyone point me to a right direction. I have created a custom Checkout flow and it has payment pane in it.

I'm trying to skip payment pane if the Cart state changed (default cart state is draft) I couldn't find any documentation for this in Drupal Commerce documentation or through Google.

I don't know what hook is available for this (if there is any) or where to start.

Thanks

# Answer
Turns out there's already a documentation for this and I missed it. For anyone who has the same problem,

You can implement the `isVisible()` function on your custom checkout pane. https://docs.drupalcommerce.org/commerce2/developer-guide/checkout/create-custom-checkout-pane
> 2 votes

---
Tags: commerce
---


# Question
Title: In event subscriber, how to redirect if value doesnt exist?
I am trying to check a condition before page load, if value exists to load page if not to redirect.

I am following this page

I have created a /mymodule/mymodule.services.yml file and a /mymodule/src/MyModuleSubscriber.php file.

In MyModuleSubscriber.php I would like to check if a value exists, if it does to load site as normal, if the value doesn't exist to perform redirect.

This is the code, but not sure how to write it correctly. Do I need to put an else statement or just leave blank?

Is this correct way to check a value exists on every page load?

```
class MyModuleSubscriber implements EventSubscriberInterface {

      public function checkForRedirect(GetResponseEvent $event) {

          $baseUrl = $event->getRequest()->getBaseUrl();

          if($value == null &&
             $baseURL !== '/MyModulePage') {
              $event->setResponse(new RedirectResponse($baseUrl.'/MyModulePage'));
          }
      }

  /**
   * {@inheritdoc}
   */
  static function getSubscribedEvents() {
    $events[KernelEvents::REQUEST][] = array('MyModuleLoad', 200);
    return $events;
  }
}

```

Edit:

```
      $path = \Drupal::service('path.current')->getPath();

      if($path !== '/MyModulePage') {
          $event->setResponse(new RedirectResponse('/MyModulePage'));
      }

```

# Answer
Yes, this is a correct approach. You don't need an else statement. If you don't set a response the event propagation doesn't stop and event subscribers with a lower priority get a chance to set a response. The priority depends on $value. It's unclear in your question, but if it doesn't depend on anything Drupal specific then set a priority \>300.

Best practice is to use a cacheable response and add any dependencies of $value to the response. If you don't have any then still use this response. It tells Drupal that you are fine with that it is cached how you want to redirect this path.

Example:

*core/lib/Drupal/Core/EventSubscriber/RedirectLeadingSlashesSubscriber.php*

```
<?php

namespace Drupal\Core\EventSubscriber;

use Drupal\Core\Cache\CacheableRedirectResponse;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Redirects paths starting with multiple slashes to a single slash.
 */
class RedirectLeadingSlashesSubscriber implements EventSubscriberInterface {

  /**
   * Redirects paths starting with multiple slashes to a single slash.
   *
   * @param \Symfony\Component\HttpKernel\Event\RequestEvent $event
   *   The RequestEvent to process.
   */
  public function redirect(RequestEvent $event) {
    $request = $event->getRequest();
    // Get the requested path minus the base path.
    $path = $request->getPathInfo();

    // It is impossible to create a link or a route to a path starting with
    // multiple leading slashes. However if a form is added to the 404 page that
    // submits back to the same URI this presents an open redirect
    // vulnerability. Also, Drupal 7 renders the same page for
    // http://www.example.org/foo and http://www.example.org////foo.
    if (strpos($path, '//') === 0) {
      $path = '/' . ltrim($path, '/');
      $qs = $request->getQueryString();
      if ($qs) {
        $qs = '?' . $qs;
      }
      $event->setResponse(new CacheableRedirectResponse($request->getUriForPath($path) . $qs));
    }
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    $events[KernelEvents::REQUEST][] = ['redirect', 1000];
    return $events;
  }

}

```

---

If $value is Drupal specific, for example you get it from an entity, use the default priority 0 and set the entity as cache dependency. In this case you need to set response headers to prevent that the browser is caching the redirect result for this path. Use LocalRedirectResponse for local or TrustedRedirectResponse for external URLs. See this great answer Disabling Page Cache for Redirect Response
> 5 votes

---
Tags: 9, event-subscribers
---


title: How do I fix a var-dumper conflict?

text:
# Question
Title: How do I fix a var-dumper conflict?
My upgrade is failing. I am at 8.9.19 and I used upgrade-status to make sure all my modules are compatible with next major core version. I am following instructions at https://www.drupal.org/docs/upgrading-drupal/upgrading-from-drupal-8-to-drupal-9-or-later

When I get to step 3, running composer update, I get these problems:

```
- Root composer.json requires drupal/devel ^2.1 -> satisfiable by drupal/devel[2.1.0, 2.x-dev (alias of dev-2.x)].
- drupal/core-recommended 9.1.0-alpha1 requires symfony/var-dumper v5.1.7 -> satisfiable by symfony/var-dumper[v5.1.7].
- Conclusion: don't install symfony/var-dumper v5.1.7 (conflict analysis result)
- drupal/core-recommended 9.2.0-alpha1 requires symfony/var-dumper v5.2.6 -> satisfiable by symfony/var-dumper[v5.2.6].
- Conclusion: don't install symfony/var-dumper v5.2.6 (conflict analysis result)
- drupal/core-recommended 9.3.0-alpha1 requires symfony/var-dumper v5.3.8 -> satisfiable by symfony/var-dumper[v5.3.8].
- Conclusion: don't install symfony/var-dumper v5.3.8 (conflict analysis result)
- drupal/core-recommended[9.2.0-beta1, ..., 9.2.0-beta2] require symfony/var-dumper v5.2.8 -> satisfiable by symfony/var-dumper[v5.2.8].
- Conclusion: don't install symfony/var-dumper v5.2.8 (conflict analysis result)
- drupal/core-recommended 9.2.0-beta3 requires symfony/var-dumper v5.3.0-RC1 -> satisfiable by symfony/var-dumper[v5.3.0-RC1].
- Conclusion: don't install symfony/var-dumper v5.3.0-RC1 (conflict analysis result)
- drupal/core-recommended[9.0.0-beta3, ..., 9.0.0-rc1] require symfony/var-dumper v5.0.8 -> satisfiable by symfony/var-dumper[v5.0.8].
- Conclusion: don't install symfony/var-dumper v5.0.8 (conflict analysis result)
- drupal/core-recommended[9.0.0, ..., 9.0.12] require symfony/var-dumper v5.1.0 -> satisfiable by symfony/var-dumper[v5.1.0].
- Conclusion: don't install symfony/var-dumper v5.1.0 (conflict analysis result)
- drupal/core-recommended[9.1.0-beta1, ..., 9.1.7] require symfony/var-dumper v5.1.8 -> satisfiable by symfony/var-dumper[v5.1.8].
- Conclusion: don't install symfony/var-dumper v5.1.8 (conflict analysis result)
- drupal/core-recommended[9.0.13, ..., 9.1.x-dev] require symfony/var-dumper v5.1.11 -> satisfiable by symfony/var-dumper[v5.1.11].
- Conclusion: don't install symfony/var-dumper v5.1.11 (conflict analysis result)
- drupal/core-recommended[9.2.0-rc1, ..., 9.2.x-dev] require symfony/var-dumper v5.3.0 -> satisfiable by symfony/var-dumper[v5.3.0].
- Conclusion: don't install symfony/var-dumper v5.3.0 (conflict analysis result)
- drupal/core-recommended 9.0.0-alpha1 requires composer/installers v1.7.0 -> satisfiable by composer/installers[v1.7.0].
- drupal/core-recommended[9.0.0-alpha2, ..., 9.0.0-beta2] require composer/installers v1.8.0 -> satisfiable by composer/installers[v1.8.0].
- composer/installers[v1.7.0, ..., v1.8.0] require composer-plugin-api ^1.0 -> found composer-plugin-api[2.1.0] but it does not match the constraint.
- drupal/core-recommended[9.3.x-dev, ..., 9.4.x-dev] require symfony/var-dumper v5.3.10 -> satisfiable by symfony/var-dumper[v5.3.10].
- Conclusion: don't install symfony/var-dumper v5.3.10 (conflict analysis result)
- Root composer.json requires drupal/core-recommended ^9 -> satisfiable by drupal/core-recommended[9.0.0-alpha1, ..., 9.4.x-dev].

```

I don't understand the issues or what to do. var-dumper is not in my `composer.json`, but I do see it in k

I have also tried running update with -W, no change. How do I tell what version is being used? Do I need to install or delete something? Running symfony/var-dumper shows this:

```
drupal/devel           2.1.0    requires   symfony/var-dumper (~2.7|^3|^4)
psy/psysh              v0.10.9  requires   symfony/var-dumper (~5.0|~4.0|~3.0|~2.7)
symfony/error-handler  v4.4.30  requires   symfony/var-dumper (^4.4|^5.0)
symfony/http-kernel    v3.4.49  conflicts  symfony/var-dumper (<3.3)

```

Here is my complete `composer.json`:

```
{
    "name": "drupal-composer/drupal-project",
    "description": "Project template for Drupal 8 projects with composer",
    "type": "project",
    "license": "GPL-2.0-or-later",
    "authors": [
        {
            "name": "",
            "role": ""
        }
    ],
    "dependencies": {
    },
    "repositories": {
        "drupal": {
            "type": "composer",
            "url": "https://packages.drupal.org/8"
        }
    },
    "require": {
        "php": ">=7.0.8",
        "composer/installers": "^1.2",
        "cweagans/composer-patches": "^1.6",
        "drupal/addanother": "^1.0",
        "drupal/admin_toolbar": "^2.3",
        "drupal/adminimal_admin_toolbar": "^1.11",
        "drupal/adminimal_theme": "^1.5",
        "drupal/advagg": "^4.1",
        "drupal/backup_migrate": "^5.0@RC",
        "drupal/bamboo_twig": "^5.0-alpha1",
        "drupal/better_exposed_filters": "^5.0",
        "drupal/block_field": "^1.0@RC",
        "drupal/blog": "^3.0",
        "drupal/classy_paragraphs": "^1.0@beta",
        "drupal/coffee": "^1.0",
        "drupal/config_delete": "^1.17",
        "drupal/config_inspector": "^1.1",
        "drupal/config_update": "^1.7",
        "drupal/console": "~1.0",
        "drupal/contentimport": "^9.3",
        "drupal/context": "^4.0@beta",
        "drupal/core-composer-scaffold": "^9",
        "drupal/core-project-message": "^9",
        "drupal/core-recommended": "^9",
        "drupal/createandcontinue": "^1.2",
        "drupal/cshs": "^2.3",
        "drupal/ctools": "^3.4",
        "drupal/d8w3css": "^1.17",
        "drupal/devel": "^2.1",
        "drupal/disable_messages": "^2.0",
        "drupal/draggable_dashboard": "^1.4",
        "drupal/ds": "^3.7",
        "drupal/editablefields": "^1.0@beta",
        "drupal/email_registration": "^1.1",
        "drupal/empty_page": "^3.0",
        "drupal/entity": "^1.1",
        "drupal/entity_browser": "^2.5",
        "drupal/entity_print": "^2.2",
        "drupal/entity_reference_revisions": "^1.8",
        "drupal/entity_usage": "^2.0@beta",
        "drupal/examples": "^3.0",
        "drupal/extlink": "^1.5",
        "drupal/field_group": "^3.1",
        "drupal/graphql": "^3.0",
        "drupal/graphql_core": "^3.0",
        "drupal/homebox": "1.x-dev",
        "drupal/htmlmail": "^3.0@alpha",
        "drupal/image_effects": "^3.0",
        "drupal/inline_entity_form": "^1.0@RC",
        "drupal/jquery_ui": "^1.4",
        "drupal/jquery_ui_accordion": "^1.1",
        "drupal/jquery_ui_datepicker": "^1.1",
        "drupal/libraries": "^3.0@alpha",
        "drupal/link_attributes": "^1.11",
        "drupal/mailcontrol": "^1.2",
        "drupal/maillog": "^1.0@beta",
        "drupal/mailsystem": "^4.3",
        "drupal/menu_per_role": "^1.3",
        "drupal/metatag_head_title": "^1.1",
        "drupal/module_filter": "^3.1",
        "drupal/multiple_registration": "^2.92",
        "drupal/openapi": "^2.0@RC",
        "drupal/openapi_ui": "^1.0@RC",
        "drupal/paragraphs": "^1.12",
        "drupal/pathauto": "^1.8",
        "drupal/profile": "^1.1",
        "drupal/publication_date": "^2.0@beta",
        "drupal/publishcontent": "^1.3",
        "drupal/redirect": "^1.6",
        "drupal/registration_types": "^1.0@beta",
        "drupal/rename_admin_paths": "^2.0",
        "drupal/responsive_menu": "4.4.1",
        "drupal/save_edit": "^1.3",
        "drupal/sendgrid_integration": "^1.7",
        "drupal/simple_sitemap": "^3.10",
        "drupal/simplelogin": "^6.0",
        "drupal/system_stream_wrapper": "^1.0@alpha",
        "drupal/tablesorter": "^2.0@beta",
        "drupal/taxonomy_manager": "^2.0",
        "drupal/term_csv_export_import": "^3.0@alpha",
        "drupal/token": "^1.7",
        "drupal/twig_debugger": "^1.1",
        "drupal/twig_field_value": "^2.0",
        "drupal/twig_tweak": "^2.6",
        "drupal/twigsuggest": "^1.0@beta",
        "drupal/typed_data": "^1.0@alpha",
        "drupal/upgrade_status": "^3.11",
        "drupal/vertical_tabs_config": "^1.3",
        "drupal/viewfield": "^3.0@beta",
        "drupal/views_autocomplete_filters": "^1.3",
        "drupal/views_bulk_edit": "^2.4",
        "drupal/views_bulk_operations": "^3.9",
        "drupal/views_conditional": "^1.3",
        "drupal/views_natural_sort": "^2.0@alpha",
        "drupal/views_taxonomy_term_name_into_id": "^1.0@alpha",
        "drupal/watchdog_prune": "^2.1",
        "psr/log": "^1.1",
        "twig/extensions": "^1.5",
        "vlucas/phpdotenv": "^4.0",
        "webflo/drupal-finder": "^1.0.0",
        "zaporylie/composer-drupal-optimizations": "^1.0"
    },
    "require-dev": {
        "drupal/core-dev": "^9"
    },
    "conflict": {
        "drupal/drupal": "*"
    },
    "minimum-stability": "dev",
    "prefer-stable": true,
    "config": {
        "sort-packages": true
    },
    "autoload": {
        "classmap": [
            "scripts/composer/ScriptHandler.php"
        ],
        "files": ["load.environment.php"]
    },
    "scripts": {
        "pre-install-cmd": [
            "DrupalProject\\composer\\ScriptHandler::checkComposerVersion"
        ],
        "pre-update-cmd": [
            "DrupalProject\\composer\\ScriptHandler::checkComposerVersion"
        ],
        "post-install-cmd": [
            "DrupalProject\\composer\\ScriptHandler::createRequiredFiles"
        ],
        "post-update-cmd": [
            "DrupalProject\\composer\\ScriptHandler::createRequiredFiles"
        ]
    },
    "extra": {
        "composer-exit-on-patch-failure": true,
        "patchLevel": {
            "drupal/core": "-p2"
        },
        "drupal-scaffold": {
            "locations": {
                "web-root": "web/"
            }
        },
        "installer-paths": {
            "web/core": ["type:drupal-core"],
            "web/libraries/{$name}": ["type:drupal-library"],
            "web/modules/contrib/{$name}": ["type:drupal-module"],
            "web/profiles/contrib/{$name}": ["type:drupal-profile"],
            "web/themes/contrib/{$name}": ["type:drupal-theme"],
            "drush/Commands/contrib/{$name}": ["type:drupal-drush"]
        }
    }
}

```

# Answer
> 3 votes
It's the devel module that prevents you from installing. As this line indicates, it requires a version of `symfony/var-dumper` that is not compatible with Drupal 9:

```
drupal/devel           2.1.0    requires   symfony/var-dumper (~2.7|^3|^4)

```

If you change devel to the current version, e.g. `^4.1` then it should install.

---
Tags: 9, upgrading
---


# Question
Title: Upgrading from 8.9.19 to 9 fails because of root composer.json require (^8.8.0)
My upgrade is failing. I am at 8.9.19 and I used `upgrade-status` to make sure all my modules are compatible with next major core version. I am following instructions at https://www.drupal.org/docs/upgrading-drupal/upgrading-from-drupal-8-to-drupal-9-or-later

When I get to step 3, running `composer update`, I'm getting a slew of problems of the form

```
- drupal/core-recommended 9.0.0 requires drupal/core 9.0.0 -> found drupal/core[9.0.0] but it conflicts with your root composer.json require (^8.9.19)

```

mentioning all 9.x versions. I can post my entire composer.json if that will help, but I think these are the relevant lines:

```
        "drupal/core": "^8.9.19",
        "drupal/core-composer-scaffold": "^9",
        "drupal/core-project-message": "^9",
        "drupal/core-recommended": "^9",
...
    "require-dev": {
        "drupal/core-dev": "^9"
    },

```

I had originally created the project with

```
composer create-project drupal-composer/drupal-project:8.x-dev www --stability dev --no-interaction

```

Any suggestions, or pointers to a different tutorial on upgrading, would be greatly appreciated.

# Answer
> 0 votes
Solved, I had to remove the `drupal/core` package from the `composer.json` and update the Devel module to fix a conflict with `symfony/var-dumper`.

---
Tags: updating, composer
---


# Question
Title: Migrate Json data with non-numeric unique identifier (from facebook...)
I am trying to fetch posts form facebook, using **migrate**.

## My question is:

**in my migration conf.yml how should I set the source:ids key to handle non-numeric IDs, like the ones provided by facebook that look like that 1333842536759100\_23306506123438**

---

**Some details:**

I fetch a json from FB that look like that:

```
{
   "data": [
      {
         "permalink_url": "URL",
         "created_time": "2021-11-06T16:59:16+0000",
         "is_popular": false,
         "message": "xxxxx",
         "id": "1333842536759100_23306506123438"
      }, {...}
   ]
}

```

In my source YML i've got:

```
source:
  plugin: url
  data_fetcher_plugin: http
  data_parser_plugin: json
  track_changes: false
  urls:
    - 'XXX'
  item_selector: data
  fields:
    -
      name: id
      label: 'Unique post identifier'
      selector: id
   [...]
  ids:
    id:
      type: string

```

But when I try to import, I get:

```
Numeric value out of range: 1264 Out
   of range value for column 'sourceid1' at row 1: INSE
  RT INTO "migrate_map_facebook_posts" ("source_ids_has
  h", "sourceid1", "source_row_status", "rollback_actio
  n", "hash") VALUES (:db_insert_placeholder_0, :db_ins
  ert_placeholder_1, :db_insert_placeholder_2, :db_inse
  rt_placeholder_3, :db_insert_placeholder_4); Array
  (
      [:db_insert_placeholder_0] => c21c5df349e2f4591c8
  34b5342c35d69fca6f9aed586b75227057791d41b097b
      [:db_insert_placeholder_1] => 1333842536759100_23306506123438
      [:db_insert_placeholder_2] => 3
      [:db_insert_placeholder_3] => 0
      [:db_insert_placeholder_4] =>
  )

```

Despite the ID type being set as "string", and I see in my DB the column being int(13)...

How can I handle this non-numeric facebook ID ?

# Answer
> 0 votes
It turns out I was looking in the wrong place: my yml was fine at this point, but before, I did import the migration conf with ids as integer.

The problem was that the database tables created by migrate (migrate\_map\_YOURMIGRATIONNAME and migrate\_message\_YOURMIGRATIONNAME ) won't get updated if you merely change and reimport your migration configuration.

In the end, I had to drop them manually for them to get recreated with the right structure.

---
Tags: migrations, 9, social-network
---


title: Use async with drupal_http_request()

text:
# Question
Title: Use async with drupal_http_request()
I need to make an asynchronous call with `drupal_http_request()`. Is it possible?

# Answer
With drupal\_http\_request this is not possible. But you can have a look at the module HTTP Parallel Request & Threading Library which allows you to do non-blocking requests.

From the module page:

> Using stream\_select() it will send http requests out in parallel. These requests can be made in a blocking or non-blocking way. Blocking will wait for the http response; Non-Blocking will close the connection not waiting for the response back. The API for httprl is similar to the Drupal 7 version of drupal\_http\_request().
> 0 votes

---
Tags: 7, http-request
---


# Question
Title: How to edit file 'description' label and help text
I want to edit the file upload description label and the help sentence underneath it:

I tried the below code:

```
function mymodule_field_widget_form_alter(&$element, FormStateInterface &$form_state, $context) {
  if (isset($element['#field_name'] == 'field_file_description') {
      // Add process callback to change field description.
      $element['#process'][] = 'chg_desc';
    }
  }
}

function chg_desc($element, FormStateInterface $form_state, $form) {
  $element['#description'] = t('Trying to edit desc help');
  return $element;
}

```

It does not have any impact on the field label and help text. How can they be changed?

# Answer
I'm going to assume that the machine name of your file field is `field_file_description`.

According to FileWidget.php#L414, the description is it's own element in the form, so instead of `$element['#description']` it should be `$element['description']['#description']`. I just tested that and it works.

Here is a working code sample:

```
function mymodule_field_widget_form_alter(&$element, FormStateInterface &$form_state, $context) {
  if (!array_key_exists('#field_name', $element)) {
    return;
  }
  if ($element['#field_name'] == 'field_file_description') {
    // Add process callback to change field description.
    $element['#process'][] = 'mymodule_process_field_file_description';
  }
}

function mymodule_process_field_file_description($element, FormStateInterface $form_state, $form) {
  $element['description']['#title'] = t('Help!!!');
  $element['description']['#description'] = t('Trying to edit desc help');
  return $element;
}

```
> 1 votes

---
Tags: 8, hooks, files
---


title: How to create a custom example module?

text:
# Question
Title: How to create a custom example module?
I want to create a custom module *in minimum*, i.e. a module which can be installed but generally doesn't do anything just for the sake of understanding how are custom modules get created after some hard time with the documentation.

**example.info.yml**

```
name: example
type: module
core_version_requirement: ^8 || ^9
description: 'example'

```

**example.php**

```
<?php
?>

```

Assuming that this is the way to go and nothing essential is missing, how is the connection between the two files is done (shouldn't I notify example.info.yml about example.php)?

# Answer
**How the files are connected**

Drupal will automatically execute the PHP file with the module name **and the extension .module**; this is a special case.

So, you need to rename **example.php** to **example.module**.

If you want to add additional PHP files that are not classes, you will need to include them.

For example, if I add a file **example.mail.php**, and I want to include that, I need to include it in **example.module** like this:

`include_once 'example.mail.inc';`

But I do not need to include **example.module** because it is a special case. **example.module** will always be executed if it exists.

**Verifying example.module is included**

You can use the Devel module with kint to debug Drupal, and this is a relatively easy way to check if a file is being included.

If you enable the Devel module, add the following code to **example.php**, and then rebuild the cache, Drupal will use kint to print the form ID on every page that includes a form.

```
function example_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  kint($form_id);
}

```
> -1 votes

---
Tags: 9
---


# Question
Title: How can one programmatically get the bundle constraint for an entity reference field?
I'm working in the context of a Views plugin. I have `$entity_type` and `$field`, as required in the snippet below. How can I get the bundle constraint for the entity reference field programmatically?

```
/** @var Drupal\field\Entity\FieldStorageConfig $field_configuration */
$field_configuration = FieldStorageConfig::loadByName($entity_type, $field);

```

`$field_configuration->getType()` gives me "entity\_reference"

`$field_configuration->getSettings()['target_type']` gives me "taxonomy\_term"

...but what methods return the vocabulary or vocabularies (bundles) that the entity reference field is set to be limited by (if at all) in its configuration?

# Answer
> 2 votes
The types allowed by an entity reference field is stored in the field config (`FieldConfig.php` and the `field.field.*` yaml), not the field storage config (`FieldStorageConfig.php` and the `field.storage.*` yaml).

If you take a peek at one instance of a `field.field.*` yaml of an entity reference field, you'll see the `settings.handler_settings.target_bundle` property containing a list of allowed bundles for that entity reference field. To get this data from code, you'll need `FieldConfig::load(id)` or `FieldConfig::loadByName($entity_type_id, $bundle, $field_name)` depending on what data you have at hand. Once you get the field config instance, there is a `getSetting()` method which you can use to grab `handler_settings`.

---
Tags: views, entities, 9
---


# Question
Title: how to import 3 xml selectors in one drupal field using the migrate plus module?
the migrate\_plus migration conf i had so far was

```
process:
  title: title
  body: job_description
  field_job_diffusion: offer_type
  field_job_statut: statut
  field_job_domaine: domaine
  field_job_campus: campus
  field_job_niveau_etudes: study_level
  field_job_emailapi: application_email

```

It works for single XML selector to single field mapping and migration. I need now to get the value from 3 xml selectors and put them in one multivalued field.

How can i achieve this?

# Answer
> 1 votes
The docs has a list of process plugins from core and migrate plus you can use to manipulate the data before they get set on the field.

`get` is the plugin used by Drupal when you use the shorthand mapping syntax (i.e. how you're doing it right now). However, you can write the longhand version, *it also accepts an array* as source, which it will then treat as a multi-value source. Simply pop an array of the source field names into an array as the `source`:

```
process:
  field_phone_numbers:
    -
      plugin: get
      source:
        - main_number
        - mobile_number
        - office_number

```

---
Tags: migrations, importing-exporting
---


# Question
Title: How can I let users select existing media entities in a webform?
I am a beginner in drupal and I am creating a course form I would like you to help me with a field in the webform. I need to add a field where users can add an image and documents but from the files that I have in drupal media, not from my computer. I tried with webform entity view and file entity browser but they did not work for me, I can upload my images and documents but from the computer and it is not what I want. Or maybe I did not use it correctly, I hope for your help, thank you very much.

# Answer
Guys use the field type Entity radio and select the type of content you need, in this case it was medium, and it brought me the values that I have in drupal, thank you very much for your help
> 0 votes

---
Tags: media, webforms
---


# Question
Title: How get the view mode\third_party_settings of a field inside hook_preprocess_image_formatter(&$variables)
I'm on D9.

I've added a custom option to the image field formatter following Drupal guidelines

In the preprocess of the field I can get the settings I've created:

```
function my_module_preprocess_field(&$variables) {
  if ($variables["element"]["#formatter"] === 'image') {
    $entity = $variables['element']['#object'];
    $view_mode = $variables['element']['#view_mode'];
    $field_name = $variables['element']['#field_name'];

    $entity_display = EntityViewDisplay::collectRenderDisplay($entity, $view_mode);
    $field_display = $entity_display->getComponent($field_name);

    $variables['my_settings'] = isset($field_display["third_party_settings"]["my_module"]["my_settings"]) && $field_display["third_party_settings"]["my_module"]["my_settings"];
  }
}

```

However, the `field.html.twig` file is not good for my need: I have to pass this settings to the `image-formatter.html.twig` file, because I need to place a `div` right after the `img` tag and not outside the `a`.

Unfortunately, I can't get that information in the preprocess of the image formatter, because I can't find a way to get the view mode:

```
function my_module_preprocess_image_formatter(&$variables) {
  $item = $variables['item'];
  $entity = $item->getEntity();
  $field = $item->getFieldDefinition();

  //todo how get the view_mode\the third_party_settings?
  $entity_display = EntityViewDisplay::collectRenderDisplay($entity, $missing_view_mode);
}

```

Is that possible?

EDIT:

Thanks 4k4 answer, what I've done:

1. Added inside the preprocess field function:

```
    if (!empty($variables['items'])) {
      foreach ($variables['items'] as &$item) {
        $item['content']['#item_attributes']['my_settings'] = $my_settings;
      }
    }

```

And then added a *image preprocess function* in order to have that info as variable and not attribute - more a preference than a strict necessity.

```
function my_module_preprocess_image(&$variables) {
  $variables['my_settings'] = $variables["attributes"]["my_settings"] ?? FALSE;
  unset($variables["attributes"]["my_settings"]);
}

```

# Answer
> 2 votes
I would add the view mode or the third party setting to the image attributes. Then it is available in both nested templates, `image_formatter` and `image`. You can remove it after you've stored it in a local variable, if you don't want that the attribute is rendered. But normally no one cares about an additional attribute.

---
Tags: theming, entities, 9
---


# Question
Title: How to create a view that lists all taxonomy terms of a vocabulary, filtered by a term id?
I have a lot of different vocabularies. On The taxonomy page (the standard view provided) I would like to add a block (view) that takes the current taxonomy id from the url/page and displays all taxonomy terms belonging to the same vocabulary. I tried adding a contextual filter, but when I choose term id from url, the view only shows one term, but I would like to show all terms of the vocabulary the term belongs to.

Of course I could create a block for each vocabulary, but as I have a lot, I'm searching for a more dynamic approach.

For Example: on the page /taxonomy/term/39 I would like to add a block (view) that takes the taxonomy id 39 and lists all terms of the vocabulary the id 39 belongs to.

# Answer
> 1 votes
I created a views argument\_default plugin that did the trick:

```
public function getArgument() {
  if (($taxonomy_term = $this->routeMatch->getParameter('taxonomy_term')) && $taxonomy_term instanceof TermInterface) {
    $vocabulary = $taxonomy_term->bundle();
    return $vocabulary;
  }
}

```

---
Tags: views, taxonomy-terms, 9
---


# Question
Title: How to alter Layout Builder block visiblity?
Is there a hook to alter block access for blocks placed using Layout Builder? I see there is hook\_block\_access; but sadly this is not triggered when the block is placed using Layout Builder.

There is also work going on here: https://www.drupal.org/project/drupal/issues/2916876#comment-14279293 to allow standard block visibility settings to be made available to Layout Builder blocks; but this only allows for the defined visibilify plugins. Is this my only option, to create a custom block visiblity plugin and use it with that patch?

# Answer
> Is this my only option, to create a custom block visiblity plugin and use it with that patch?

No, configuring visibility of a block instance is not the only option. You can also control access on plugin level. If you add BlockPluginTrait::blockAccess to the plugin class you control all block instances of this plugin.

However, most common in Layout Builder are inline custom blocks. The plugin for these blocks implements already this method, checking access of the underlying block content entity. So in this case you can use a hook, but for `block_content`:

```
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Session\AccountInterface;

/**
 * Implements hook_ENTITY_TYPE_access().
 */
function mymodule_block_content_access(EntityInterface $entity, $operation, AccountInterface $account) {
  if ($operation == 'view') {
    if ($entity->id() == 123) {
      return AccessResult::forbidden();
    }
  }
  return AccessResult::neutral();
}

```
> 1 votes

---
Tags: blocks, 9, layout-builder
---


# Question
Title: How to get the base URL of a site in Queue API?
I am trying to get the base url of the drupal 8 website in a queue process but I am getting http://default as the base url. What am I missing here?

```
  public function testUrl() {
    global $base_url;
    var_dump($base_url);
    $host = \Drupal::request()->getSchemeAndHttpHost();
    var_dump($host); // output - http://default
    $host2 = \Drupal::request()->getHost();
    var_dump($host2); // output - default
    $uri = \Drupal::request()->getUri();
    var_dump($uri); // output - http://default
    $url = \Drupal\Core\Url::fromUserInput('/', ['absolute' => TRUE])->toString();
    var_dump($url); // output - http://default
    $url_options = [
      'absolute' => TRUE,
      'language' => \Drupal::languageManager()->getCurrentLanguage(),
    ];
    $site_url = \Drupal\Core\Url::fromRoute('<front>', [], $url_options)->toString();
    var_dump($site_url); // output - http://default
    var_dump($_SERVER['SERVER_NAME']); // output - NULL
    die;
  }

```

# Answer
The process running the queue worker will be setting that default host. For example, drush cron

You may need to set the public host name with the drush request, via uri or use a drush alias.

```
drush --uri=http://example.com cron

```

More info https://docs.drush.org/en/8.x/usage/
> 2 votes

---
Tags: 8, uri, queue
---


title: Webform 6.1.0 help text not showing

text:
# Question
Title: Webform 6.1.0 help text not showing
I updated my webform Module from 5.3.0 to 6.1.0,

I have one the Following Error: the help text isn't displaying its content on any form on my site (Example of help icon in the shared image)

It should return the following when i do the mouseover:

I tried:

* searching on google: no clear solution
* changing the css and js file persmissions to 777
* looked into my console: no return when i do mouseover on the help icon ...

Someone have any idea what can it be?

# Answer
Webform has several libraries that need to be installed via Composer. Follow the installation instructions in the documentation and make sure you have the libraries installed.
> 0 votes

---
Tags: 8, webforms, debugging
---


# Question
Title: Drupal modal does not render remote forms (Mautic)
I'm trying to embed Mautic forms in my drupal site. I created a controller pointing to '/mautic-form\` and in the twig template I have this:

```
<script type="text/javascript" src="//mautic.coachingrealista.com/mautic/form/generate.js?id=3"></script>

```

When I go to that page (`/mautic-form`), the form renders well:

But when I use it inside a modal, it does not render that form:

```
<a data-dialog-options="{"width":800}" data-dialog-type="modal" href="/mautic-form" class="use-ajax">LEARN MORE</a>

```

I looked on the JS console and I didn't see any error.

It's doing fine with the requests:

What am I doing wrong?

# Answer
It looks like that it is a Mautic issue, I posted it in the Mautic GitHub issue: https://github.com/mautic/mautic/issues/10563

Actually, the form is generated but in the head so I did a walkaround moving the form from there to the div where I wanted to be with JS.
> 0 votes

---
Tags: theming, javascript, modal-dialogs
---


# Question
Title: Migrate accessing source fields by name instead of by selector?
I'm working on the MongoDB source plugin and I'm able to do the migration, but I have to make strange compromises. When defining the source fields, I have to set name the same as selector, like this.

```
fields:
  -
    name: _id
    label: 'Unique ID'
    selector: _id

```

That works, but if I decide to change field name and keep selector, the migration fails.

```
fields:
  -
    name: node_id
    label: 'Unique ID'
    selector: _id

```

I get this error.

> 'node\_id' is defined as a source ID but has no value.

Why is that? Why is the source array accessed by name instead of by selector?

# Answer
Selectors are handled by data processor plugins. Initially I tried to use iterator object provided by MongoDB collection object. That works, but selectors are not supported. Then I saw how custom data processor is made in Migrate plus module, for parsing json and made one based on that. Basically I'm using collection iterator to get full json and then my custom data processor works with that json the similar way as Migrate Plus json data processor does.
> 0 votes

# Answer
You can change the name of source fields, but you must not change the name of source fields used as source IDs.

```
source:
  fields:
    -
      name: _id
      label: 'Unique ID'
      selector: _id
  ids:
    _id:   <-- this is the problem, you can not rename source fields used here
      type: integer

```

On the first migration the module creates a mapping table `migration_map_MIGRATION_ID` for each remote source row \<=\> local entity. After that, you no longer can change the name of source fields used as source IDs.

The only way around this is a complete rollback, then manually deleting those migration tables (including table `migration_message_MIGRATION_ID` ) and then you can make a fresh start.
> 1 votes

---
Tags: migrations
---


# Question
Title: Get all entity reference options from a field name
I would like to create a node programatically and one field `field_supervisors` has an entity reference field for the node type `People`.

In order to set the correct entity reference information I need to set:

```
[
  ["target_id" => 1],
  ["target_id" => 2],
  // etc..
]

```

How can I get the individual `id` of the entity reference from the `field_supervisors`. Do I really need to look up the node `People` before to get the id like `$node->id()` or is there a way to return something like this pseudo code:

`Field->field_supervisors->allReferencedEntitiyOptions` which will return all `People` that are available ?

Thanks

# Answer
> 1 votes
> Do I really need to look up the node People before to get the id

Yes, there's no auto-magic method for that. It's not a lot of code though. Without DI, for example:

```
$ids = \Drupal::entityQuery('node')->condition('type', 'person')->execute();

```

---
Tags: entities, 9
---


# Question
Title: How to add noindex / nofollow robot metatags to Views subpages
I have a big view with lots of filters, and Google and friends are killing one of my sites after a cache clear.

How could I add noindex and nofollow metatags in this views' subpages header? I would like to keep the views main page free of these tags. As I understand the Metatag module is not yet up to the task.

Another idea just came to my mind: Adding nofollow to Views sorting links would achieve nearly the same.

I inquired and no such feature will happen in Views http://drupal.org/node/1758354

# Answer
> 2 votes
Altering robots.txt could be an option. For example this would stop google from accessing your pager.

```
    # Disallow all URL variables except for page
    Disallow: /*?page=*&*
    Disallow: /*?page=0*

```

More examples on Views and SEO can be found here.

# Answer
> 0 votes
This solution now fails as any canned links to a filtered solution trigger google search index to consider the page important and flag the robots.txt, the robots noindex metatag is required to fix this alert in the google search console. A method for adding the metatag to a filtered view is now REQUIRED for a site to function without an error alert.

---
Tags: views, meta-tags, 7
---


# Question
Title: How can I create a notification entity with Rules module
I have installed a notification system and I want to create notifications with Rules when a project content is updated to waiting for approval status.

The rule looks like this:

```
uuid: 3165768f-15f5-4c35-a7e6-3f862b526f10
langcode: en
status: true
dependencies: {  }
id: project_updated
label: 'Project updated'
events:
  -
    event_name: 'rules_entity_update:node--project'
description: ''
tags: {  }
config_version: '3'
expression:
  id: rules_rule
  uuid: 4cead148-c63e-409d-a3e1-f9042c993fb6
  weight: 0
  conditions:
    id: rules_and
    uuid: b6e39609-9972-4805-af43-f2bdc66dc10b
    weight: 0
    conditions:
      -
    id: rules_condition
    uuid: 6d3b93ac-10ad-4b21-bbfd-1971c1aa44cc
    weight: 0
    context_values:
      operation: '=='
      value: waiting_for_approval
    context_mapping:
      data: node.moderation_state.value
    context_processors:
      operation:
        rules_tokens: {  }
      value:
        rules_tokens: {  }
    provides_mapping: {  }
    condition_id: rules_data_comparison
    negate: false
  actions:
    id: rules_action_set
    uuid: 39c0aaa8-f216-4255-a87b-484e94e075fc
    weight: 0
    actions:
      -
    id: rules_action
    uuid: 543fe5c3-83d0-4e46-932c-a197747868fb
    weight: 0
    context_values:
      token: '[current-date:raw]'
      token_entity: ''
    context_mapping: {  }
    context_processors:
      token:
        rules_tokens: {  }
      token_entity:
        rules_tokens: {  }
    provides_mapping:
      token_value: unix_time
    action_id: rules_token_get_token_value
      -
    id: rules_action
    uuid: 92aeaa68-c475-4ae7-97aa-2f74d72b89ff
    weight: 0
    context_values:
      user_id:
        - '1'
      provider_id: project
      notification_type: waiting_for_approval
      created: '{{ unix_time }}'
      title: 'New project waiting for approval: {{ node.title }}'
      priority: '3'
    context_mapping: {  }
    context_processors:
      user_id:
        rules_tokens: {  }
      provider_id:
        rules_tokens: {  }
      notification_type:
        rules_tokens: {  }
      created:
        rules_tokens: {  }
      title:
        rules_tokens: {  }
      priority:
        rules_tokens: {  }
    provides_mapping: {  }
    action_id: 'rules_entity_create:notification'

```

It's getting triggered and it's actually being executed the reactions (actions) also. However it does not create the entity, and I don't receive any error in the Recent log messages. With a little xdebug I've found that the tokens are replaced.
`unix_time` to a UNIX timestamp
`node.title` to the saved node title.

However, for some reason, the notification entity is not being created. How can I create an entity with rules if not like this?

# Answer
> 1 votes
Most likely you just need to add a "Save entity" action. Entities that are part of the context (in this case the project node) are automatically saved, but any entities you create during the rule may need to be explicitly saved.

---
Tags: rules, 9, notifications
---


# Question
Title: Geofield map : add marker on click listener
I've added a google map which I feed thanks to the Geofield module.

I'd like to add an onClick event to each marker to have a custom behavior.

this is what I've done this far :

```
  Drupal.behaviors.geofieldGoogleMapInteraction = {
    attach: function (context, settings) {
      if (context !== document) {
        return;
      }

      // React on geofieldMapInit event.
      $(document).on('geofieldMapInit', function (e, mapid) {
        var map = Drupal.geoFieldMapFormatter.map_data[mapid].map;
        var markers = Drupal.geoFieldMapFormatter.map_data[mapid].markers;
        map.addMarkerAddedCallback(function(markerClicked) { // is not a function
          triggerClick(markerClicked);
        });

        function triggerClick(markerClicked) {
          console.log("click !")
        }
        $.each(markers, function (storeId, marker) {
          if(parseInt(storeId) !== 56) return;
          const properties = marker.geojsonProperties;
          $(marker).on('click', function() {
            console.log("click") // not triggered
          });
        })
      });
    }
  };

```

I can't manage to trigger the on click of the marker ,I've got nothing in my console. Where am I wrong ?

EDIT : this is the source code of a single marker. I don't see any sign of how the marker id could be retrieved... (I have cluster and single markers at the same time)

# Answer
> 4 votes
If it help someone, this is what I came up with :

```
  $(document).on('geofieldMapInit', function (e, mapid) {
    var map = Drupal.geoFieldMapFormatter.map_data[mapid].map;
    var markers = Drupal.geoFieldMapFormatter.map_data[mapid].markers;

    $.each(markers, function (storeId, marker) {
      const properties = marker.geojsonProperties;
      google.maps.event.addListener(marker, 'click', function() {
        console.log('click ' + storeId)
      })
    })
  });

```

---
Tags: javascript, 9, google-maps
---


title: Creating twig files for the a view

text:
# Question
Title: Creating twig files for the a view
Hi there I'm new to Drupal. I have made a test project, where I've made a custom content-type called 'persons' it has a couple of values. And I made it able to custom style it by making a twig file called 'node--persons.html.twig'. Now I have built a listing view, where I loop through all the 'persons'. It's called 'People view' But I can't get it to work to make a working twig file that is able to properly style every person item in a loop. I've already tried making twig files like views\_view--people\_view.html.twig etc. But nothing actually seemed to work. I'm very confused about all this stuff and also whenever I need to use a machine\_name or so. Can someone help me?

# Answer
First, I recommend manipulating twig as the ultimate last resort. Drupal provides some core and third-party modules that allow you to manipulate how an entity is rendered:

* Layout Builder allows you to manipulate an entity's display with layouts.
    + This allows you to create layouts, and use layouts to position fields and blocks on the page.
* Drupal has a very predictable field structure (wrapper, label, value).
* The Fences module allows you to manipulate field markup, add classes, etc.
* Views, just like fields, also has a very predictable markup structure.
* Views also has a built-in way to change field markup, add classes.

I would exhaust those options first before resorting to twig, as those options allow you to manipulate the appearance of an entity without hardcoding everything into a twig file.

As for Views, it has *two* ways of rendering an entity. You either go the *fields* route where you render individual fields, or you surrender rendering to the entity where the the entity Displays are rendered instead of fields.

Drupal 8+ also has a bug where theme suggestions for various parts of the view are not printed in HTML comments. You can find these suggestions here. For convenience, here are some of the options:

```
views-view--foobar--page.html.twig
views-view--page.html.twig
views-view--foobar.html.twig
views-view.html.twig

views-view-unformatted--foobar--page.html.twig
views-view-unformatted--page.html.twig
views-view-unformatted--foobar.html.twig
views-view-unformatted.html.twig

views-view-fields--foobar--page.html.twig
views-view-fields--page.html.twig
views-view-fields--foobar.html.twig
views-view-fields.html.twig

```
> 0 votes

---
Tags: theming
---


# Question
Title: Drupal 9 core multilingual: cannot translate main navigation menu - button translate missing on menu items
I'm trying to catch multilingual features of Drupal 9 and have wamp64 local development server and clean Drupal 9.2.8 install.

I've enabled 4 multilingual core modules:

* Configuration Translation,
* Content Translation,
* Interface Translation,
* and Language.

Two languages enabled: en and ru.

I'm trying to translate Main Navigation Menu, but menu items don't have a "translate" button along with "edit" and "delete" at right side of menu links. So, no chance to translate menu items to RU language.

So, please help me to resolve this issue.

Thank you in advance.

# Answer
> 2 votes
You are really close from it. You enabled the right modules, now, just go to `/admin/config/regional/content-language` (or via admin menu: Configuration \>\> Regional and language \>\> Content language and translation) and check the box "Custom menu link".

In the set of fields that appear below, select which properties of your menu items you want to be translatable and then hit "Save configuration".

Go back to your menu. You now have the available "Translate" option.

---
Tags: i18n-l10n, 9
---


# Question
Title: How can I deploy user interface translation?
Strings that I translate at "User interface translation" /admin/config/regional/translate are not exportable by "Configuration management" /admin/config/development/configuration for me. Am I missing something?

I would like to automate this process with `hook_update_N` or `drush cim -y`.

What is a proper way to automatically deploy "User interface translation" in Drupal 8?

1. Should I do it in `hook_update_N()`?
2. Should I create some custom `mytranslations.po` file in the language folder?

I see there is `locale_translate_batch_import_files()` which might be used.

# Answer
You have to do this yourself. @rpayanm answered where you can do it manually, you will need to look at the code there, and for example implement drush commands that allow you to export and import it again. Automating that is then relatively easy, export, sync it to the other server, and import again.

Looks like a project that helps with that exists: Drush Language Commands.

You can put default translations in a module ,but those are only imported when you install that module. `hook_update_N()` is designed to only run once, so you would need to write a new function every time you want to do it (and you still need to export it first).
> 7 votes

# Answer
Helper function to add custom translations:

```
/**
 * Helper to manually add a single translation string.
 *
 * @param string $source_string
 *   Source string.
 * @param string $langcode
 *   The langcode.
 * @param string $translated_string
 *   Translated string.
 */
function MYMODULE_add_translation($source_string, $langcode, $translated_string) {
  // Find existing source string.
  $storage = \Drupal::service('locale.storage');
  $string = $storage->findString(['source' => $source_string]);
  if (is_null($string)) {
    $string = new SourceString();
    $string->setString($source_string);
    $string->setStorage($storage);
    $string->save();
  }
  // Create translation. If one already exists, it will be replaced.
  $translation = $storage->createTranslation([
    'lid' => $string->lid,
    'language' => $langcode,
    'translation' => $translated_string,
  ]);
  $translation->save();
}

```

Usage in an update hook:

```
/**
 * Add translations.
 */
function MYMODULE_update_8002() {
  MYMODULE_add_translation('Adjust', 'de', 'Anpassen');
}

```
> 10 votes

# Answer
You can export the translated strings used by your site A (admin/config/regional/translate/export) and then import them on the other site (admin/config/regional/translate/import).
> 5 votes

# Answer
For our project, we wrote a custom module with .po files in a subfolder. These are loaded by the Drupal 8 localization system using a few lines of code in the .info.yml.

```
'interface translation project': CUSTOM_MODULE
'interface translation server pattern': modules/custom/CUSTOM_MODULE/%project-%version.%language.po

```

See https://api.drupal.org/api/drupal/core%21modules%21locale%21locale.api.php/group/interface\_translation\_properties/8.2.x
> 3 votes

# Answer
It looks like it should also be possible to do this by writing a script to run commands from Drush locale sync, although I haven't tried that module myself.
> 2 votes

# Answer
A more simple option to deploy a few string translations would be to use the 'String overrides' feature available in Drupal 8.x and 9.x.

In short, it's possible to include string translations in your `settings.php` file (or `settings.local.php`).

This is the change record where it was introduced: https://www.drupal.org/node/2109883

And this is how it works:

```
/*
* String overrides:
*
* To override specific strings on your site with or without enabling the Locale
* module, add an entry to this list. This functionality allows you to change
* a small number of your site's default English language interface strings.
*
* Remove the leading hash signs to enable.
*
* The "en" part of the variable name, is dynamic and can be any langcode of
* any enabled language. (eg locale_custom_strings_de for german).
*/
 $settings['locale_custom_strings_en'][''] = array(
   'forum'      => 'Discussion board',
   '@count min' => '@count minutes',
 );

```
> 1 votes

---
Tags: 8, i18n-l10n, deployment
---


# Question
Title: Multi-site, multiple database and 1 shared database
I want to develop drupal multi-site with this structure:

* One shared codebase drupal 7 multi-site, each web site has own database.
* One master web site that has some tables shared.
* Each multi site instances read some tables from master's database, not own database. For example conntent types, fields, views, rules and related configirations read only master's database. So I can develop all sites on one place.

As a result each site must use same content types, views, rules but different contents. I am user 1 of all sites. Sub site editors has create content and user permisions only. I dont want to share users accross sites. So I cant use domain acceess. Is it possible that?

Thanks for your helps.

# Answer
> 0 votes
If your need is

> each site must use same content types, views, rules but different contents

Domain Access is simplest answer:

> The Domain Access project is a suite of modules that provide tools for running a group of affiliated sites from one Drupal installation and a single shared database. The module allows you to share users, content, and configurations across a group of sites such as:
>
> * example.com
> * one.example.com
> * two.example.com
> * my.example.com
> * thisexample.com \<-- can use any domain string
> * example.com:3000 \<-- treats non-standard ports as unique

Of course it uses one database, but end-user experience you need is covered.

# Answer
> 0 votes
Use Features module to store your content types, views, rules etc. in code as custom modules and enable those modules on each site in your multi-site install.

This way all sites have the same config but separate databases and you don't need a "master" database.

---
Tags: multi-sites, database
---


# Question
Title: How do I render a commerce promotion coupon code on the order details?
I want to show a coupon code used on an order details page, but cannot seem to render it on a templates. Here are some things I have tried so far...

```
{% for coupon in order_entity.coupons %}
  {{ coupon.target_id }}
  {{ coupon.code }}
  {{ drupal_entity('commerce_promotion_coupon', coupon.target_id) }}
  {{ drupal_field('code', 'commerce_promotion_coupon', coupon.target_id) }}
{% endfor %}

```

The only thing that works is {{ coupon.target\_id }} and it just prints out the id as a number. I thought I could use Twig Tweak to load the entity and get it that way, but that doesn't seem to work either.

Thanks!

# Answer
> 0 votes
How I solved it ... (requires Twig Tweak module)

```
{% set coupon_entity = drupal_entity('commerce_promotion_coupon', coupon.target_id) %}
{{ coupon_entity['#commerce_promotion_coupon'].getCode }}

```

---
Tags: theming, commerce
---


# Question
Title: Unable to upload files through RESTful services
I am trying to upload pdf files to webform submission using REST API.

Since the Core File Upload functionality did not seem applicable for webform submission, I applied the patch from `webform_rest` module which would allow uploading files for webform submissions.

When POSTing the file via `/webform_rest/{webform_id}/upload/{field_name}` with the necessary Content-Type and Content-Disposition, Cookie and X-CSRF-Token per documentation, the file entity response's filesize value is always zero and correspondingly the destination file is empty. The file size and extension are in accordance to the settings in webform's Document file field. The public, private and tmp directories are writable and file upload works fine when performed through the webform submission form.

I tried to check if this issue is specific to the webform\_rest resource by trying the File upload resource (`/file/upload/{entity_type_id}/{bundle}/{field_name}`) for a specific entity type with the respective file field and observed the same result of file being empty. To try and understand where the issue might be I looked into both the Rest resource code and tried checking the symfony `$request->files` parameter which appears to be empty in both cases.

Since the file upload functionality works fine within the site and related php configurations like file\_uploads, upload\_max\_filesize, post\_max\_size are already set I'm uncertain as to how to approach this problem further

Would request some clarity on how I could debug this further and get it to work.

# Answer
> 0 votes
Tried to check if the API behaved differently when hit through cURL instead of the Postman app which I had been relying on and it worked immediately. Realized it was an issue with either my workplace network preventing the file upload through postman or problem within the version of postman installed in my work computer.

---
Tags: webforms, files, 9
---


# Question
Title: Place field in "Url Alias" advanced group section (path-0)
I'm trying to place my node field to the Advanced group - URL alias section. I'm doing it in custom hook\_form\_BASE\_FORM\_ID\_alter(), where I'm trying to set custom #group like this:

```
$form['my_filed']['#group'] = 'path-0';

```

But "path-0" neither "path\_0", "path" works. But if I use something else e.g. "meta", "menu" ... then my field is displayed in right place. What's the trick to place it in "Url Alias"? Thanks

# Answer
It's not all that obvious unless you look at the code which processes the form, but you can use the `][` separator, which the general form API uses to denote a parent/child relationship in a string.

This works for me:

```
$form['field_foo']['#group'] = 'path][0';

```
> 1 votes

---
Tags: forms, hooks, 9
---


# Question
Title: Upgrading to Composer 2 blocked by Symfony dependecies
I have an existing Drupal 8.9.16 site which uses Composer 1 (and Commerce 2.24). I am trying to upgrade to using Composer 2 using this guide: https://www.drupal.org/docs/develop/using-composer/preparing-your-site-for-composer-2.

I have gotten through all the required steps up to the last step of dealing with drupal-scaffold (https://www.drupal.org/docs/develop/using-composer/using-drupals-composer-scaffold#s-migrating-composer-scaffold). The last step of that is to require drupal/core-recommended:^8.9. As I don't want to update core right now I am trying to run:

composer require drupal/core-recommended:8.9.16

but I am blocked by:

* Can only install one of: symfony/yaml\[v3.4.41, v3.4.47\].
* drupal/core-recommended 8.9.19 requires symfony/yaml v3.4.41 -\> satisfiable by symfony/yaml\[v3.4.41\].

As a guess, I try requiring symfony/yaml:3.4.41. This fixes this issue and then moves on to the next symfony plugin which generates a similar error. Started going through all of these but there are a lot of symphony plugins and this can't possibly be the right way to do this.

What am I missing here?

# Answer
As is usually the fix, deleting the vendor folder and composer.lock file and then running:

* composer require drupal/core-recommended:8.9.16 --update-with-dependencies seems to have fixed the problem.

Since I deleted the .lock file it effectively runs a composer update which updated a few of the contrib modules. Not what i wanted; but I could have locked them in where they were if i was that worried about it. Core and Commerce were fixed to the version I was using so this remain untouched.

After that i was able to selfupdate to composer 2.x.
> 2 votes

---
Tags: 8, composer
---


title: Uploading local files via composer

text:
# Question
Title: Uploading local files via composer
I'm using composer to manage a Drupal 9 instance. I'm brand new to composer and have no idea what i'm doing. That being said, I've successfully set it up and have used it to install modules and an admin theme. I just purchased a theme and realized that I don't know how how to upload it with composer. For modules and the admin theme I installed, I used composer require drupal/name-of-module(or theme) but this theme doesn't have a shortname and isn't on drupal.org (but rather on my local machine after downloading it). How do I go about uploading this theme with composer? I've looked through the composer documentation but can't find anything about this scenario.

# Answer
You might want to have a look at the documentation on drupal.org:

It's a lot to digest, but it goes into quite some detail on how to use composer and git to manage your site.

The gist of it is this:

**You use composer** to download code (modules, themes, libraries, ...) that is available somewhere on the internet (github, gitlab, npm, your companies private repositories, ...) and manage the dependencies between the different components that you download.

**You use git** to manage your project, that is to say your `composer.json` that defines how and where to get external components, but also your custom code, for example custom modules that you write but that you don't make publicly accessible somewhere, but also that theme that you have purchased. Git allows you to do version control for your project, so that you can safely make changes, go back to a known working state if you break something, and create tagged releases for fixed snapshots of your code.

Once you have all set and your site is running on your local machine as you expect it, the next question is how you get that onto a server, so that your site will become publicly available. This is what I would understand as "uploading" (and there are, as usual, multiple possible ways), but I think this is not what you meant.
> 2 votes

---
Tags: composer
---


# Question
Title: How do I resolve this installation error?
I am getting the following error while installing Drush with `composer require drush/drush`.

> Using version ^8.1 for drush/drush
> ./composer.json has been updated
> Loading composer repositories with package information
> Updating dependencies (including require-dev)
> Your requirements could not be resolved to an installable set of packages.
>
> Problem 1
> \- drush/drush 8.1.0 conflicts with drupal/drupal \[No version set (parsed as 1.0.0)\].
> \- drush/drush 8.1.1 conflicts with drupal/drupal \[No version set (parsed as 1.0.0)\].
> \- drush/drush 8.1.2 conflicts with drupal/drupal \[No version set (parsed as 1.0.0)\].
> \- drush/drush 8.1.3 conflicts with drupal/drupal \[No version set (parsed as 1.0.0)\].
> \- drush/drush 8.1.4 conflicts with drupal/drupal \[No version set (parsed as 1.0.0)\].
> \- drush/drush 8.1.5 conflicts with drupal/drupal \[No version set (parsed as 1.0.0)\].
> \- drush/drush 8.1.6 conflicts with drupal/drupal \[No version set (parsed as 1.0.0)\].
> \- drush/drush 8.1.7 conflicts with drupal/drupal \[No version set (parsed as 1.0.0)\].
> \- drush/drush 8.1.8 conflicts with drupal/drupal \[No version set (parsed as 1.0.0)\].
> \- drush/drush 8.1.9 conflicts with drupal/drupal \[No version set (parsed as 1.0.0)\].
> \- Conclusion: don't install drush/drush 8.1.12
> \- Conclusion: don't install drush/drush 8.1.11
> \- Conclusion: don't install drush/drush 8.1.10
> \- Conclusion: don't install drush/drush 8.x-dev
> \- Installation request for drupal/drupal \[No version set (parsed as 1.0.0)\] -\> satisfiable by drupal/drupal \[No version set (parsed as 1.0.0)\].
> \- Conclusion: remove phpdocumentor/reflection-docblock 3.1.1
> \- Installation request for drush/drush ^8.1 -\> satisfiable by drush/drush \[8.1.0, 8.1.1, 8.1.10, 8.1.11, 8.1.12, 8.1.2, 8.1.3, 8.1.4, 8.1.5, 8.1.6, 8.1.7, 8.1.8, 8.1.9, 8.8.x-dev, 8.x-dev\].
> \- Conclusion: don't install phpdocumentor/reflection-docblock 3.1.1
> \- drush/drush 8.8.x-dev requires phpdocumentor/reflection-docblock ^2.0 -\> satisfiable by phpdocumentor/reflection-docblock \[2.0.0, 2.0.0a1, 2.0.0a2, 2.0.0a3, 2.0.1, 2.0.2, 2.0.3, 2.0.4, 2.0.5\].
> \- Can only install one of: phpdocumentor/reflection-docblock \[2.0.0, 3.1.1\].
> \- Can only install one of: phpdocumentor/reflection-docblock \[2.0.0a1, 3.1.1\].
> \- Can only install one of: phpdocumentor/reflection-docblock \[2.0.0a2, 3.1.1\].
> \- Can only install one of: phpdocumentor/reflection-docblock \[2.0.0a3, 3.1.1\].
> \- Can only install one of: phpdocumentor/reflection-docblock \[2.0.1, 3.1.1\].
> \- Can only install one of: phpdocumentor/reflection-docblock \[2.0.2, 3.1.1\].
> \- Can only install one of: phpdocumentor/reflection-docblock \[2.0.3, 3.1.1\].
> \- Can only install one of: phpdocumentor/reflection-docblock \[2.0.4, 3.1.1\].
> \- Can only install one of: phpdocumentor/reflection-docblock \[2.0.5, 3.1.1\].
> \- Installation request for phpdocumentor/reflection-docblock (locked at 3.1.1) -\> satisfiable by phpdocumentor/reflection-docblock \[3.1.1\].
>
> Installation failed, reverting ./composer.json to its original content.

# Answer
> 2 votes
The fix was downgrading phpdocumentor/reflection-docbloc to 2.x with `composer require phpdocumentor/reflection-docblock:^2.0`.

> ./composer.json has been updated
> Loading composer repositories with package information
> Updating dependencies (including require-dev)
> Package operations: 1 install, 1 update, 0 removals
> \- Installing dflydev/markdown (v1.0.3): Downloading (100%)
> Drupal\Core\Composer\Composer::vendorTestCodeCleanup
> \- Updating phpdocumentor/reflection-docblock (3.1.1 =\> 2.0.0): Downloading (100%)
> Drupal\Core\Composer\Composer::vendorTestCodeCleanup
> Package dflydev/markdown is abandoned, you should avoid using it. Use michelf/php-markdown instead.
> Writing lock file
> Generating autoload files
> Drupal\Core\Composer\Composer::preAutoloadDump
> Drupal\Core\Composer\Composer::ensureHtaccess

Then install Drush with `composer require drush/drush`.

> Using version ^8.1 for drush/drush
> ./composer.json has been updated
> Loading composer repositories with package information
> Updating dependencies (including require-dev)
> Package operations: 12 installs, 0 updates, 0 removals

# Answer
> 4 votes
Had the same problem started from D8.4beta1.

Solved by switching to Drush 9 with:

```
composer require drush/drush:^9

```

# Answer
> 2 votes
I was able to reproduce the error, using the following commands:

```
composer create-project drupal/drupal 8 ^8.3
cd 8
composer update
composer require drush/drush

```

The last command gave the following output.

> Using version ^8.1 for drush/drush
> ./composer.json has been updated
> Loading composer repositories with package information
> Updating dependencies (including require-dev)
> Your requirements could not be resolved to an installable set of packages.
>
> Problem 1
> \- drush/drush 8.1.0 conflicts with drupal/drupal\[No version set (parsed as 1.0.0)\].
> \- drush/drush 8.1.1 conflicts with drupal/drupal\[No version set (parsed as 1.0.0)\].
> \- drush/drush 8.1.2 conflicts with drupal/drupal\[No version set (parsed as 1.0.0)\].
> \- drush/drush 8.1.3 conflicts with drupal/drupal\[No version set (parsed as 1.0.0)\].
> \- drush/drush 8.1.4 conflicts with drupal/drupal\[No version set (parsed as 1.0.0)\].
> \- drush/drush 8.1.5 conflicts with drupal/drupal\[No version set (parsed as 1.0.0)\].
> \- drush/drush 8.1.6 conflicts with drupal/drupal\[No version set (parsed as 1.0.0)\].
> \- drush/drush 8.1.7 conflicts with drupal/drupal\[No version set (parsed as 1.0.0)\].
> \- drush/drush 8.1.8 conflicts with drupal/drupal\[No version set (parsed as 1.0.0)\].
> \- drush/drush 8.1.9 conflicts with drupal/drupal\[No version set (parsed as 1.0.0)\].
> \- Conclusion: don't install drush/drush 8.1.12
> \- Conclusion: don't install drush/drush 8.1.11
> \- Conclusion: don't install drush/drush 8.1.10
> \- Conclusion: don't install drush/drush 8.x-dev
> \- Installation request for drupal/drupal No version set (parsed as 1.0.0) -\> satisfiable by drupal/drupal\[No version set (parsed as 1.0.0)\].
> \- Conclusion: remove phpdocumentor/reflection-docblock 3.2.0
> \- Installation request for drush/drush ^8.1 -\> satisfiable by drush/drush\[8.1.0, 8.1.1, 8.1.10, 8.1.11, 8.1.12, 8.1.2, 8.1.3, 8.1.4, 8.1.5, 8.1.6, 8.1.7, 8.1.8, 8.1.9, 8.8.x-dev, 8.x-dev\].
> \- Conclusion: don't install phpdocumentor/reflection-docblock 3.2.0
> \- drush/drush 8.8.x-dev requires phpdocumentor/reflection-docblock ^2.0 -\> satisfiable by phpdocumentor/reflection-docblock\[2.0.0, 2.0.0a1, 2.0.0a2, 2.0.0a3, 2.0.1, 2.0.2, 2.0.3, 2.0.4, 2.0.5\].
> \- Can only install one of: phpdocumentor/reflection-docblock\[2.0.0, 3.2.0\].
> \- Can only install one of: phpdocumentor/reflection-docblock\[2.0.0a1, 3.2.0\].
> \- Can only install one of: phpdocumentor/reflection-docblock\[2.0.0a2, 3.2.0\].
> \- Can only install one of: phpdocumentor/reflection-docblock\[2.0.0a3, 3.2.0\].
> \- Can only install one of: phpdocumentor/reflection-docblock\[2.0.1, 3.2.0\].
> \- Can only install one of: phpdocumentor/reflection-docblock\[2.0.2, 3.2.0\].
> \- Can only install one of: phpdocumentor/reflection-docblock\[2.0.3, 3.2.0\].
> \- Can only install one of: phpdocumentor/reflection-docblock\[2.0.4, 3.2.0\].
> \- Can only install one of: phpdocumentor/reflection-docblock\[2.0.5, 3.2.0\].
> \- Installation request for phpdocumentor/reflection-docblock (locked at 3.2.0) -\> satisfiable by phpdocumentor/reflection-docblock\[3.2.0\].
>
> Installation failed, reverting ./composer.json to its original content.

In fact, `composer update` output the following (among other lines):

> * Updating phpdocumentor/reflection-docblock (2.0.4 =\> 3.2.0): Downloading (100%)

I tried also using `composer require drush/drush dev-master` and/or `composer create-project drupal/drupal 8 8.4.*@dev` but all the combinations caused the same error messages.

I was able to install Drush 8.1 with Drupal 8.3 using the following commands.

```
composer create-project drupal/drupal 8 ^8.3
cd 8
composer require drush/drush
composer update

```

In this case, Composer doesn't install anymore phpdocumentor/reflection-docblock 3.2.0, but 2.0.5.

> * Updating phpdocumentor/reflection-docblock (2.0.4 =\> 2.0.5): Downloading (100%)

`drush status` outputs the following.

```
 Drupal version         :  8.3.5
 PHP executable         :  /usr/bin/php
 PHP configuration      :  /etc/php/7.1/cli/php.ini
 PHP OS                 :  Linux
 Drush script           :  /home/kiamlaluno/8/vendor/drush/drush/drush.php
 Drush version          :  8.1.12
 Drush temp directory   :  /tmp
 Drush configuration    :
 Drush alias files      :
 Drupal root            :  /home/kiamlaluno/8
 Drupal Settings File   :  MISSING

```

# Answer
> 0 votes
I think easy way is via

```
composer install
composer require drush/drush

```

# Answer
> 0 votes
Had similar issue with drush installed twince onto both /usr/lib/ and the composer webroot

# Answer
> 0 votes
Errors like that mean that the installing package requires other dependencies, so you can always use the -W flag to install the package with dependencies.

```
composer global require drush/drush:8.x -W

```

---
Tags: drush, composer
---


# Question
Title: Creating a custom module caused "The website encountered an unexpected error. Please try again later."
Drupal 9.2.7 on XAMPP 7.3.29 , 7.4.21 on Windows 10 Home.

I tried to create a custom module which allows global JavaScript and CSS (effective in all webpages in my website), by creating the directory `root/modules/globalrs` with the following files:

**globalrs.info.yml**

```
name: globalrs
type: module
core_version_requirement: ^8 || ^9
description: 'globalrs'
libraries:
  - globalrs/globalrs

```

**globalrs.module**

```
function globalrs_preprocess_page(&$variables) {
  $variables['#attached']['library'][] = 'globalrs/globalrs';
}

```

**globalrs.libraries.yml**

```
globalrs:
  js:
    behavior.js: {}
  css:
    theme:
      style.css: {}

```

**style.css**

```
* {
    background: red;
}

```

## My problem

My problem is that the website won't load, instead the following error appears:

> The website encountered an unexpected error. Please try again later.

Even if I delete the module directory and flush all caches (flushing all `cache_` tables as well as the `cachetags` table, and flushing the browser's cache, the website still has that error;
Since that error is generic, I don't know how to start to solve the problem.

### A bug as a possible reason

It may be that the problem started after I have added `$settings['rebuild_access'] = TRUE;` to the end of /sites/default/settings.php, saved the file and then navigated in my web browser to localhost/example.com/core/rebuild.php, where I got the following error:

> Fatal error: Uncaught PDOException: SQLSTATE\[HY000\] \[1044\] Access denied for user 'example.com'@'localhost' to database 'example.com' in

Edit (removing the rest of the error messages because this is caused by an unrelated error while restoring a backup):

> I believe that the problem happened sometime when I tried to restore a backup of the website to a new empty database with the same name which was registered as associated with the database user (or appeared to be such) but actually wasn't

## Update - solution

I paste this here after Clive deleted my answer:

I revoked all database-specific privileges that the *database user* had on the *database with the same name* and then **re-granted** these database-specific privileges1 to that user; I could then access the website.

# Answer
> 2 votes
**Before** you create a custom module set

* All messages, with backtrace information

in *admin/config/development/logging*. This option is available in Drupal core without any dev tools installed.

Then you get a more helpful error message if anything goes wrong.

With default

* None

the error message gets replaced by *"The website encountered an unexpected error. Please try again later."*. The only purpose of this message is to hide the real error in production environments.

If it's too late and you can't open the admin UI anymore you can still enable all error messages in settings.php:

```
$config['system.logging']['error_level'] = 'verbose';

```

Don't remove the module code, this makes things worse. If you can't go forward or backwards, you can't fix the error with the more helpful error message and you can't uninstall the module because it is broken, then rollback the entire site from a backup or snapshot you've made before you've created the module.

---
Tags: 9
---


# Question
Title: How to keep Contextual Filters (query) on Exposed Filter change
I have a view page that leverages Contextual Filters with query parameters. So when a user visits the view page, the URL is as such… `/search?location=san+francisco`. This works as expected.

Now there are 3 exposed filters for this same view. When the user selects an exposed filter, the above contextual query parameters are replaced with the exposed filter parameters, as such `/search?weather=cloudy` so the view output is incorrect.

Ideally, I want the URL to be `/search?location=san+francisco&weather=cloudy`.

How do I go about keeping the Contextual Filter query parameters on the Exposed Filter change? In other words, combining the two instead of the Exposed query replacing the Contextual query.

# Answer
> 1 votes
Found patches for both core and better exposed filters module that preserves the query parameter when exposed filter is initiated.

https://www.drupal.org/project/drupal/issues/2681953 https://www.drupal.org/project/better\_exposed\_filters/issues/3119947#comment-14289676

Apply the core patch first if using bef.

---
Tags: 8, views
---


# Question
Title: How can I bootstrap my site from an external script?
Community asked.. **Please clarify your specific problem...**

Fair comment. What I'd like help with is *how do I correct the script below so it works with D9*.

```
<?php

use Drupal\Core\DrupalKernel;

$autoloader = require_once 'autoload.php';

// This next line is the problem
$request = Request::createFromGlobals();

$kernel = DrupalKernel::createFromRequest($request, $autoloader, 'prod');

$kernel->boot();

require_once 'core/includes/database.inc';
require_once 'core/includes/schema.inc';

$em = $kernel->getContainer()->get('entity_type.manager');

$entity = $em->getStorage('node')->create(array(

    'type'        => 'article',
    'title'       => 'Druplicon test',

 ));

$entity->save();

?>

```

This is the same as the D8 script below which works - except I have:

* removed the use symphony line;
* replaced the deprecated function ( thanks leymannx )

The script fails as noted on the line
**$request = Request::createFromGlobals();** with messages

*chrome-error://chromewebdata/:1 Failed to load resource: the server responded with a status of 500 () VM10:7288 crbug/1173575, non-JS module files deprecated.*

Can someone point out what's wrong with this line in D9 (which I guess relates to the removal of the symphony use statement) and also if there are any other lines of code following which D9 won't like.

Thanks for any further help on this and apologies for the earlier confusion and for still being out of my depth with D9.

---

Original post...

This article provides D8 code to create an entity from an external script. I'm in the same boat as the person who asked this question - wanting to convert from D7's drupal\_bootstrap.

Although my requirement is D9, I thought I'd try and get a D8 script working using the above post. His application is with an entity. I'm wanting to create article entries.

Here is the code I took from the above link which is said to work..

```
<?php

use Drupal\Core\DrupalKernel;
use Symfony\Component\HttpFoundation\Request;

$autoloader = require_once 'autoload.php';

$request = Request::createFromGlobals();

$kernel = DrupalKernel::createFromRequest($request, $autoloader, 'prod');

$kernel->boot();

require_once 'core/includes/database.inc';
require_once 'core/includes/schema.inc';

$em = $kernel->getContainer()->get('entity.manager');

$entity = $em->getStorage('node')->create(array(

    'type'        => 'article',
    'title'       => 'Druplicon test',

 ));

$entity->save();

?>

```

This code runs and creates an entry in the *node\_field\_data* table but the article is **not listed as content** on the site.

I'm very much feeling my way with D8/D9 coding so please bear with me if I'm doing something silly!

Once I can get this to work, I then need to find out what changes are needed for D9 - so any help here would be good. For example the D8 code uses symphony but that's not part of D9 I believe.

Thanks for any help on this to get this to work. And to help me replace my D7 experience with D8/D9!

**Sorry...** This code does show up in the content - I was looking at a D9 site, not the test D8 I set up. Apologies!

But I'd still like help on what changes I need to make to this script to run under D9.

# Answer
Here is the code that allows entity creation in a D9 site from a remote script - run from the same domain as the D9 site but not from the D9 root directory.

```
<?php
//drupal root directory
chdir('/var/www/vhosts/example.org/httpdocs/dev3');

use Drupal\Core\DrupalKernel;
use Symfony\Component\HttpFoundation\Request;

$autoloader = require_once 'autoload.php';

$request = Request::createFromGlobals();

$kernel = DrupalKernel::createFromRequest($request, $autoloader, 'prod');

$kernel->boot();

require_once 'core/includes/schema.inc';

$em = $kernel->getContainer()->get('entity_type.manager');

$entity = $em->getStorage('node')->create([
  'type'        => 'article',
  'title'       => 'Druplicon test' . date("d/m/Y")." ". date("h:i:sa"),
]);

$entity->save();

?>

```

The clue to this code came from this article which explains the way Drupal loads a page. It says "look at index.php in the root, if you want to see how Drupal does it". About 6 lines of code!

Why didn't my earlier script, ported from D8, work? Here are some of the things I learned:

* the line **$request = Request::createFromGlobals();** which stopped the earlier script running works ok in this code;
* there is no file database.inc in the root directory on a D9 site;
* I changed the deprecated entity.manager to entity\_type\_manager as *leymannx* advised;
* D9 does seem to use Symphony - it appears in index.php in release 9.2.7. But it's a later version than D8;
* the external script should not be in the Drupal root - not even for testing - otherwise the site fires with a 404;
* If you want to Google for information on bootstrapping, don't use Bootstrap - otherwise all you see is info. on the theme!

Getting this working means I can replace D7 external scripts with D9. I take the point *kevin* makes about using the migrate module but I think bootstrapping a better solution for my use cases. E.g a user adds a record to a MySQL database in Microsoft Access under program control. The code then runs an external script to add selected fields to a Drupal entity. Immediately the Access user and the web user see the same up-to-date data.

Thanks to everyone who contributed on this. I hope this post clears up the messy way I started this question.
> 3 votes

---
Tags: 9, bootstrapping
---


title: Block Settings inside Form

text:
# Question
Title: Block Settings inside Form
Please I need help with my code. I have a form and a block created programmatically. The block embeds the form to show it on the frontend. The block also has some settings (form preffix text). I want to load the block settings inside my buildForm in my Form.php to get the preffix text and show it in the form markup field. But I can't seem to find a way to pass on the $block\_id to the buildForm() so it can load the block.

I have a scenario where there can be two of these blocks on the same page in which Drupal uniques the block by appending some ID with the block id. So for example my page has two of these blocks one would be like `feedbackblock` the other would be `feedbackblock_2` hence I cannot hardcode the block id to load it in my buildForm function.

I want it to dynamically pass on the block id to the form.

**build() from my Block.php:**

```
  public function build() {
    $block_id // get the block id of the current block instance
    $feedback_form = $this->formBuilder->getForm(FeedbackForm::class, $block_id);

    $build = [];
    $build['#theme'] = 'feedback_block';
    $build['feedback_block']['#markup'] = render($feedback_form);

    return $build;
  }

```

**buildForm from my FeedbackForm.php:**

```
  public function buildForm(array $form, FormStateInterface $form_state, string $block_id) {
      // Get the block id here.
  }

```

Is there any way to achieve this?

# Answer
> 2 votes
There is an abstaction layer between the storage of the block config and the block view building. Block configuration can be stored anywhere and doesn't necessarily have a machine name. You can however transfer the machine name to the block settings when you place a block in Block Layout:

```
use Drupal\block\BlockInterface;

/**
 * Implements hook_ENTITY_TYPE_presave() for block entities.
 */
function mymodule_block_presave(BlockInterface $block) {
  if ($block->isNew()) {
    $settings = $block->get('settings');
    $settings['block_id'] = $block->get('id');
    $block->set('settings', $settings);
  }
}

```

Then you can get the machine name in build():

```
  public function build() {
    // get the block id of the current block instance
    $block_id = !empty($this->configuration['block_id']) ? $this->configuration['block_id'] : '';

```

---

As a side note. I don't think the rest of the code in the question does work. You need to add the unique ID to the form instance before you call formBuilder-\>getForm() and then use it to build a unique form ID. After that buildForm() can get the ID from the class property. See Using the same form more than once per page with AJAX callbacks

---
Tags: forms, blocks, 9
---


# Question
Title: How to create a taxonomy term from a webform
New to Webform. What I'm trying to do is build a somewhat simple site content-collecting tool using Webform. So users would 'collect' nodes by submitting forms on them. This appears to be easy to do. However, I need them to be able to group their nodes/form submissions into sets I'm calling 'folders.'

I could do this a couple of ways:

* a content type of Folder + an entity reference element on the webform to allow selection of existing "folder" items.
* a vocabulary of Folder + entity ref element on the webform to select terms

But users also need to be able to create new folders. That's where I'm stuck. How can I make the form/form-element allow users to create a new folder?

I see another way: what if instead of entity, they just have a form element of Folder, that they add items to? But this needs to be user-specific, so the list field element would would need to accumulate items (Folders) per user.

So, how would I do that? Is there a better way?

(Thought about Flag module first, but then users would need the ability to create new flags but somehow not have access to the whole flag configuration UI.)

# Answer
> 2 votes
It appears that three modules can work together in Drupal 8/9 to do the job I've described.

* Flag: to give users ability to mark content, with an entity ref field for the category. (Per Patrick Kenny above: thanks Patrick!)
* Webform Content Creator: to create term entities from webform submissions: this is so users can create categories on the fly without navigating to a node create page then returning to the node they wanted to collect/flag.
* Private Taxonomy Terms: to limit term edit access to the creator of the term

Views plays a key role also, because I'm mostly controlling access to collected content via Views and filters rather than the permissions system. This isn't really "access control" per se, but should be private enough for this project. The only permission-based control we need is to grant role(s) the ability to view the term but only grant ability to edit the term to its creator.

This approach might seem overly heavy, since Webform already creates entities. But, as far as I can tell, there isn't a way to set up "edit own submissions" permission on a webform and also grant "view any submission" on that form's submissions. But maybe I'm wrong about that?

Edit: I am wrong about that! ... so will have to see if the necessary Views filters can work on webform submissions. I'm going to leave this one marked as the solution since it answer the original question about creating taxonomy terms.

# Answer
> 0 votes
You want users to be able to "collect" content and then you want to organize those collections by category. That sounds a lot closer to Flag module than Webform.

> then users would need the ability to create new flags but somehow not have access to the whole flag configuration UI.

Users do not need the ability to create new flags.

Flags are entities, so they can have fields added to them. So you create one flag, `Collect content`, and then you add an entity reference field, `category`, which is a taxonomy term reference to a taxonomy term vocabulary, **Private tags** or something like that.

**Private tags** has custom permissions so that users can only see terms they have created. Also, you can make these taxonomy terms unique per user, as it's a big UX fail to let users have multiple categories with the exact same name.

Flags also has basic Views support, although it can be tricky to use and might require some customization.

---
Tags: webforms, flags
---


# Question
Title: Difference between a front-end theme and an administrative theme?
I am teaching myself Drupal 9 and I see that the **Claro** theme is defined as a "Drupal **administration theme**" while **Olivero** is defined as a "Drupal **front-end theme**." Are these complementary themes? I'm not sure about whether I should install both - to have both a front-end and an administration theme or whether I need only one or the other. Any help you might offer in understanding the difference between a "front-end theme" and an "administration theme" would be appreciated.

# Answer
In the early days, Drupal had a single theme, which was used for both front-end presentation as well as backend content and configuration editing.

Nowadays, there is a rather clear separation between frontend and backend parts of Drupal, and using an admin theme allows to provide a clear and, ideally, easy configuration and editing space for users with backend access. So especially for more complex sites, using different themes for frontend and backend makes it possible to have a fancy frontend that caters to the needs of the (public) users, while also having a functional and optimised backend experience for administrators, editors, or whatever functional role your site might provide.

Whether you need that separation is purely up to you to decide. I would not use a single theme anymore on any of the projects I work on. There are just too many advantages from my point of view.

You might just want to install both, and play a bit around with it, then deactivating the backend theme and see the difference.
> 2 votes

---
Tags: theming
---


# Question
Title: logging working on local site but not remote site
I recently migrated from Drupal 8 to 9. Works ok on my local (MAMP on Mac), but not on the remote (AWS Lightsail). Local has PHP 7.4.12, Remote has PHP 7.4.2.

I put the entire codebase in git, and pulled it to my remote server. I created settings.php for the remote host, set trusted\_host\_patterns, sites.php, .htaccess. I had a similar setup for Drupal 8 on the remote, which worked flawlessly.

Here's what I see in my apache error log when I try to hit the home page:

1. AH01071: Got error `'PHP message: Drupal\\Core\\Database\\DatabaseAccessDeniedException: SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost'`

I did set the correct mysql user/pwd in settings.php and verified it was reading it by changing the user, and could see the new user name in the errors.

2. AH01071: Got error `'PHP message: Error: Interface 'Psr\\Log\\LoggerInterface' not found in /home/bitnami/repo/www/web/core/modules/dblog/src/Logger/DbLog.php on line 16`

I do have `"psr/log": "^1.1"` in my composer.json.

What I'm not getting is why things work on my local, but not my remote.

# Answer
> 1 votes
Found the problems - ever want to kick yourself for overlooking the obvious - the reason it wasn't finding psr/log is that when I restored it from git, I didn't realize it was a submodule. After cloning the repo, I had to: Issue a git submodule init command. Issue a git submodule update command.

And the login error I was having was due to a network error on my end, it wasn't pointing to the correct server.

Glad I got this solved, and great appreciate the suggestions.

---
Tags: installation
---


# Question
Title: "Drupal already installed" Message on Restored site
We had an issue on a Drupal 8.8.2 site, had to restore DB, Core and Vendor, now anyone visiting the site gets the site as normal, but if admin logs in I receive:

Drupal 8.8.2 Drupal already installed \- To start over, you must empty your existing database and copy default.settings.php over settings.php. \- To upgrade an existing installation, proceed to the update script. \- View your existing site.

Of note: Rather then restore over existing db I created a db2, restored the DB to it and pointed the settings to it (not sure if that is the issue)

I can't figure out how to stop that page from loading. I don't want to start over, running the update script does nothing but bring me back to the same page. View your existing site does take me to site but can't edit anything (looks like it just logs me out).

# Answer
> 2 votes
Seeing the install page on an already installed Drupal site usually is a sign of problems with your database connection before the request has been processed by PHP.

This may have a wide range of causes, most likely related to your database server configuration.

The first thing to check is your database logs, which may give a hint on how to solve your issue.

We often experienced a similar behavior on sites that heavily use the database. E.g. sending big queries when rebuilding page caches on complex pages. The solution there was to ensure a high enough `max_allowed_packet` setting. See here for more details on how to do that.

# Answer
> -4 votes
Open you XAMPP server follow the following steps MySQL\>Config\>my.ini It will opena notepad file serach for *max\_allowed\_packet* and then increase the size as per your needs

---
Tags: database, installation
---


# Question
Title: How to pass argument to php file using a drush command?
I've small php script in my public folder called sample.php. I run this file using drush command **drush scr sample.php**.

I want to know how to pass argument to php file using drush command and how to get arguments in php file?

# Answer
This is explained quite nicely in `drush topic scripts`.

Your script should start with:

```
#!/usr/bin/env drush
<?php

```

Then, you may call your script directly. For example, if you have saved your script in a file called `myscript`, then you would call it via:

```
$ myscript a b --flag=bar

```

Drush provides a method called `drush_shift` that allows you to access you one at a time:

```
$first = drush_shift();
$second = drush_shift();

```

In the above example, `$first` will be `a` and `$second` will be `b`. You may access your options via `drush_get_option()` as usual.

```
$flag = drush_get_option('flag');
$other = drush_get_option('other', 'default');

```

In the above example, `$flag` is `bar` and `other` is \`$default'.

Note that you can use `$argv` as suggested in the other answer, but if you do this, your arguments and options will be mixed together, and you will need to parse them yourself. Using `drush_shift()` and `drush_get_option();` is more convenient.
> 14 votes

# Answer
On Drush 10, I managed to work with:

```
<?php
$first = $extra[0];
$second = $extra[1];

```

Calling script with

```
./vendor/bin/drush php:script scripts/my-script.php -- firstarg secondarg

```
> 3 votes

# Answer
Posible Solucion:

```
$_SERVER['argv'][3]

```

Comand:

```
drush scr 'testScript.php' field

```

Now, $\_SERVER\['argv'\]\[3\] = **field**

Enjoy!
> 2 votes

# Answer
In php command line you can use pass arguments to your script and inside your script grab it by using $argv variable:

check this out: http://php.net/manual/en/reserved.variables.argv.php
> 0 votes

# Answer
You can use an environment variable:

```
MY_FLAG=value drush do_something

```

In php you can then retrieve this variable:

```
echo $_SERVER['MY_FLAG'];

```
> 0 votes

---
Tags: drush
---


title: getCommentedEntity returns null

text:
# Question
Title: getCommentedEntity returns null
I have a comments page set up and when I devel the page for a specific comment I see the getcommentedentity method.

I am trying to get the commented entity details using the below code in my VBO action file:

```
public function execute(ContentEntityInterface $entity = NULL) {
    $comment = $entity->get('comment_body')->getValue();
    $commentid = $entity->get('cid')->getValue();
    $var = $commentid->getCommentedEntity;
    dpm($var);
}

```

But I see error for this method. Not sure where it's wrong. Can someone tell me where the mistake is?

# Answer
> 2 votes
Assuming `$entity` is a comment entity as shown in the screenshot, use:

```
$commented_entity = $entity->getCommentedEntity();

```

---
Tags: 8, comments
---