# Question
Title: Attempt to create a field body that does not exist on entity type node
I am getting the following error:

> Drupal\Core\Field\FieldException: Attempt to create a field body that does not exist on entity type node. in Drupal\field\Entity\FieldConfig-\>getFieldStorageDefinition() (line 286 of core/modules/field/src/Entity/FieldConfig.php).

Context is that I recently switched from one branch to another and did some config imports.

My guess is that this is related to a field.storage issue? What precisely would be causing this error? I'd provide more information about my content types, but I really don't know at this point where it can be narrowed down to.

I'm not finding any real sources on this particular error.

# Answer
You attempted to create a field using configuration without creating the field storage configuration.

In the field configuration YAML you can see a `field_storage` property. That is the id of the field storage configuration that needs to also be imported.
> 13 votes

# Answer
To add to @Eyal's root cause answer, I can offer a practical solution to solve the issue.

I had this issue when trying to import config when using

```
drush cim

```

My solution assumes the use of git for the Drupal source and that the config is in folder `config/sync` relative to the root of the git source tree (and also, but not really relevant here, is that the site code is in `web/` )

I got a similar error as the original poster/questioner.

With all my changes so far I wanted `git add`ed and `git commit`ted by me, I did a:

```
drush cex

```

to export the config out of the database. Now - this isn't the config I want to use of course. The config I want to use is in code and I want to import it into the database.

But what drush cex does in this situation is export as code the thing that the import error was "complaining" about being missing. So this means I can make this thing part of the config I'm going to import so that the error no longer occurs.

But of course, doing the `drush cex`, other things will have been exported as well which I don't need or want and some of them would have overwritten / changed my config in code that I want to import. That's not a problem, because I can either:

* Delete this surplus config if it is a new file or
* revert to what was in git - the config I DO want - by git checkout of the changed file - `git checkout config-file`

Then once I've removed and/or reverted config files and changes I don't need, I can rerun `drush cim` \- and - success. Hope this helps you.

Here's my example in action:

I tried to import - but it failed:

```
drush cim

  The import failed due to the following reasons:
  Unexpected error during import with operation delete for taxonomy.vocabulary.tags: Attempt to create a field body that does not exist on entity type node.
  Unexpected error during import with operation delete for node.type.page: Attempt to create a field body that does not exist on entity type node.
  Unexpected error during import with operation delete for node.type.article: Attempt to create a field body that does not exist on entity type node.
  Unexpected error during import with operation delete for contact.form.personal: Attempt to create a field body that does not exist on entity type node.
  Unexpected error during import with operation delete for contact.form.feedback: Attempt to create a field body that does not exist on entity type node.
  Unexpected error during import with operation delete for comment.type.comment: Attempt to create a field body that does not exist on entity type node.
  Unexpected error during import with operation delete for block_content.type.basic: Attempt to create a field body that does not exist on entity type node.
  Unexpected error during import with operation delete for field.field.node.page.body: Attempt to create a field body that does not exist on entity type node.

```

So (with everything in git committed, including the config I want to evenrually import), I exported from the database:

```
ddev drush cex
 [notice] Differences of the active config to the export directory:
+------------+--------------------------------------------+-----------+
| Collection | Config                                     | Operation |
+------------+--------------------------------------------+-----------+
|            | field.field.node.page.body                 | Create    |
|            | core.entity_form_display.node.page.default | Update    |
|            | search.settings                            | Update    |
|            | core.entity_view_display.node.page.teaser  | Update    |
|            | core.entity_view_display.node.page.full    | Update    |
|            | core.entity_view_display.node.page.default | Update    |
+------------+--------------------------------------------+-----------+

```

So on doing a

```
git status

```

I got:

```
On branch develop
Your branch is up-to-date with 'origin/develop'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   .ddev/.gitignore
    modified:   .ddev/config.yaml
    modified:   composer.json
    modified:   composer.lock
    modified:   config/sync/core.entity_form_display.node.page.default.yml
    modified:   config/sync/core.entity_view_display.node.page.default.yml
    modified:   config/sync/core.entity_view_display.node.page.full.yml
    modified:   config/sync/core.entity_view_display.node.page.teaser.yml
    modified:   config/sync/search.settings.yml
    modified:   config/sync/system.site.yml

Untracked files:
  (use "git add <file>..." to include in what will be committed)
    config/sync/field.field.node.page.body.yml

```

So I could see that the missing field body file is in the newly created file, which is untracked. I don't need the modified files, so I can reset them to what is in git - the config I will want to import, by doing a git checkout on them:

```
git checkout config/sync/core.entity_form_display.node.page.default.yml
git checkout config/sync/core.entity_view_display.node.page.default.yml
git checkout config/sync/core.entity_view_display.node.page.full.yml
git checkout config/sync/core.entity_view_display.node.page.teaser.yml
git checkout config/sync/search.settings.yml

```

Then doing a

```
git status

```

just showed the new file (which is what I want to be part of my import to fix the missing body field issue):

```
Untracked files:
  (use "git add <file>..." to include in what will be committed)
    config/sync/field.field.node.page.body.yml

```

So I then did my import of my config:

```
ddev drush cim
+------------+--------------------------------------------+-----------+
| Collection | Config                                     | Operation |
+------------+--------------------------------------------+-----------+
|            | core.entity_form_display.node.page.default | Update    |
|            | search.settings                            | Update    |
|            | core.entity_view_display.node.page.teaser  | Update    |
|            | core.entity_view_display.node.page.full    | Update    |
|            | core.entity_view_display.node.page.default | Update    |
+------------+--------------------------------------------+-----------+

 Import the listed configuration changes? (yes/no) [yes]:
 > yes

 [notice] Synchronized configuration: update core.entity_form_display.node.page.default.
 [notice] Synchronized configuration: update search.settings.
 [notice] Synchronized configuration: update core.entity_view_display.node.page.teaser.
 [notice] Synchronized configuration: update core.entity_view_display.node.page.full.
 [notice] Synchronized configuration: update core.entity_view_display.node.page.default.
 [notice] Finalizing configuration synchronization.
 [success] The configuration was imported successfully.

```

With my config imported I can then go about removing the body field - because I didn't want it but needed to recreate it as described to get my configure import to go through.
> 2 votes

---
Tags: nodes, 8, entities, configuration
---


# Question
Title: Specifying display of a new Paragraph type with images using HTML/twig?
I created "figure" Paragraphs type, which **contains an image field** and a caption field. How **(from start to finish)** do I specify in HTML/twig how to render this new Paragraphs type?

As an example, how would I specify that the output would generate following code?

```
<figure>
  <img src="image">
  <figcaption>caption</figcaption>
</figure>

```

# Answer
> 1 votes
In Drupal, the specifying the generation of HTML from Paragraph types (as well as other types in Drupal) is done via the misnomer "theming."

* First create a sub-theme.
* Next, copy the `/modules/contrib/paragraphs/templates/paragraph.html.twig` file into your sub-theme's templates folder and name it `paragraph--figure--default.html.twig`.
* Add the following code below the `set classes` closing brace `%}` which specifies the parameters for the image you'd like to display.

```
{%
  set imagestyle = {
    '#theme':      'image_style',
    '#style_name': 'large',
    '#uri':        content.field_image['#items'].entity.uri.value,
    '#alt':        content.field_image['#items'].entity.alt,
    '#attributes': { class: 'myimage' },
  }
%}

```
* Last, replace `{{content}}` with the code below:

```
<figure>
    {{ imagestyle }}
    <figcaption>{{ content.field_caption }}</figcaption>
</figure>

```

Note: Using `{{ content.field_image }}` directly inside `<figure>` instead of specifying a structure with theme `image_style` **will not work**.

---
Tags: theming, paragraphs
---


# Question
Title: Change sort order of SOURCE STRING list at User interface translation page to alphabetical instead of date created
At the **User interface translation** page (`/admin/config/regional/translate`) the SOURCE STRING list seems to be ordered by creation date/time (it is for strings I add). Is there a "good" (non-hackish) way to change the order to alphabetical? I haven't found anything in the interface.

For those who wonder why I want this, I use interface translation in an unconventional way. Instead of putting literals like `t("Choose your options")` in my code, I put in a key like t('rsc-string-choose-options') \[rsc is the name of my custom module\]. Then as the translation, I put in "Choose your options". This allows me to use "keys" for all strings (literals, messages, titles, email body text, etc.). It's easy to look up my keys because they all begin with 'rsc-' followed by 'string', 'message', 'email', etc. depending on usage. Doing this provide a nice interface for editors to go in and change the text of the strings, since they can look them up either by translation or by key. I also wrote a nice utility that allows me to add, remove, rename, and test keys (i.e. translation strings). It's working very well, but it would make review much easier if the source strings were alphabetical.

# Answer
> 2 votes
It depends on what you want to call "good" & "non-hackish".

If you're looking for a simple configuration change, then no; there's no configuration change that you can make to modify the translation strings order.

If non-hackish includes using Drupal APIs to override routes & services in a custom module, then yes.

You can use a custom module to override the `locale.translate_page` route with your own custom controller & form class that will do the same work of `TranslateEditForm::buildForm()`, but modify the behavior of `::translateFilterLoadStrings()` so it produces a different ordered list of translation strings.

The string order is the result of a method in the `locale.storage` service that performs the dynamic query (see `StringDatabaseStorage::dbStringSelect()` where the query is built). You'll probably have to override that service in some manner to provide the same structured query object, but with an `orderBy` method added to execute the same query but with the sorted order you're looking for.

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


# Question
Title: What is the best practice for writing a link to the screen through t()?
In Drupal 7, one could do the following one line::

```
t('Visit !mylink', ['!mylink' => l('my website', 'http://example.com')]);

```

But that no longer works in Drupal 8 or 9 . So far, I've tried this:

First I create a link, Drupal 8 style:

```
$mylink = Link::fromTextAndUrl('my website', Url::fromUri('http://example.com'));

```

Then try to create a string that can be printed. I've tried `toString()`:

```
t('Visit @mylink', ['@mylink' => $mylink->toString()]);

```

However, we're not *supposed* to do this. The API docs says:

> Do not use this method to render a link in an HTML context. In an HTML context, self::toRenderable() should be used so that render cache information is maintained.

So I try to use `toRenderable()`:

```
t('Visit @mylink', ['@mylink' => render($mylink->toRenderable()]);

```

But PHP 7.2 doesn't like it. The call to `t()` produces the following Notice:

> Notice: Only variables should be passed by reference ...

Fair enough - but how is this done?

I could not find how to do this described in any of the obvious docs, such as:

So my question is:
What is the best practice for writing a link to the screen in Drupal 8?

(Environment: Ubuntu 20.04 LTS, Drupal 8.8.6 (core + devel), procedural code - e.g. `hook_help()`).

# Answer
For a link enclosed in translatable text, Drupal core suggests to use `t()` and embed the HTML anchor tag directly in the translated string. In `LinkGeneratorInterface::generate()`, the example code for this case is the following.

```
$text = t('Visit the <a href=":url">content types</a> page', array(
  ':url' => Url::fromRoute('entity.node_type.collection')->toString(),
));

```

Searching for *:url* in the Drupal core code finds code like the following.

### `BlockContentController::add()`

```
if (count($types) === 0) {
  return [
    '#markup' => $this
      ->t('You have not created any block types yet. Go to the <a href=":url">block type creation page</a> to add a new block type.', [
      ':url' => Url::fromRoute('block_content.type_add')->toString(),
    ]),
  ];
}

```

### `ListingEmpty::render()`

```
  $element = [
    '#markup' => $this->t('Add a <a href=":url">custom block</a>.', [
      ':url' => Url::fromRoute('block_content.add_page')->toString(),
    ]),
    '#access' => $access_result->isAllowed(),
    '#cache' => [
      'contexts' => $access_result->getCacheContexts(),
      'tags' => $access_result->getCacheTags(),
      'max-age' => $access_result->getCacheMaxAge(),
    ],
  ];

```

Alternatively, Drupal core uses the following code.

### `block_help()`

```
$themes = \Drupal::service('theme_handler')->listInfo();
$output = '<p>' . t('Block placement is specific to each theme on your site. Changes will not be saved until you click <em>Save blocks</em> at the bottom of the page.') . '</p>';
$output .= '<p>' . Link::fromTextAndUrl(t('Demonstrate block regions (@theme)', [
  '@theme' => $themes[$demo_theme]->info['name'],
]), Url::fromRoute('block.admin_demo', ['theme' => $demo_theme]))->toString() . '</p>';

```

### `template_preprocess_forums()`

```
    if ($variables['tid'] != $topic->forum_tid) {
      $variables['topics'][$id]->moved = TRUE;
      $variables['topics'][$id]->title = $topic->getTitle();
      $variables['topics'][$id]->message = Link::fromTextAndUrl(t('This topic has been moved'), Url::fromRoute('forum.page', ['taxonomy_term' => $topic->forum_tid]))->toString();
    }

```
> 2 votes

# Answer
It will easy if you convert link to url and use translate like this.

```
$url = Url::fromUri('http://example.com')->toString();
t('Visit <a href=":href">link</a>', array(':href' => $url));

```

Example drupal core use translation with link.

```
$requirements['online'] = array(
      'title' => t('Internet'),
      'value' => t('The translation server is offline.'),
      'severity' => REQUIREMENT_ERROR,
      'description' => t('The installer requires to contact the translation server to download a translation file. Check your internet connection and verify that your website can reach the translation server at <a href=":server_url">@server_url</a>.', array(
        ':server_url' => $server_url,
        '@server_url' => $server_url,
      )),
    );

```
> 1 votes

---
Tags: 8, uri
---


# Question
Title: What is correct way to make custom slider module? slide update problems
I have a custom slider module but the problem is if I make a new slide, it won't appear before drupal cache is cleared. So how can I renew my slides in the module so cache clear isn't needed.

My Code: .module file

```
function my_module_theme() {
   return array('slider' =>
           array(
            'variables' => array(
                '#attached' => array(
                    'library' => array(
                        'my_module/assets',
                    ),
                ),
              'slides' => my_module_get_slides(),
            ),
        )
    );
}

```

Plugin\Block\FlexSlider.php file

```
class FlexSlider extends BlockBase {
  /**
   * {@inheritdoc}
   */
  public function build() {
     return array(
            '#theme' => 'slider'
        );
  }
}

```

# Answer
> 1 votes
That code is wrong, as the *variables* key should not give default values that dynamically change. `hook_theme()` is not invoked every time a theme hook is necessary, but only then the theme hook registry needs to be re-built. The code invoking `hook_theme()` is the following one, in `Registry::build()`.

```
  if ($cached = $this->cache->get('theme_registry:build:modules')) {
    $cache = $cached->data;
  }
  else {
    foreach ($this->moduleHandler->getImplementations('theme') as $module) {
      $this->processExtension($cache, $module, 'module', $module, $this->getPath($module));
    }

    // Only cache this registry if all modules are loaded.
    if ($this->moduleHandler->isLoaded()) {
      $this->cache->set("theme_registry:build:modules", $cache, Cache::PERMANENT, [
        'theme_registry',
      ]);
    }
  }

```

That explains why clearing the cache the code works.

Code that would work is similar to the following one.

```
function my_module_theme() {
  return array('slider' => array(
    'variables' => array(
      'slides' => NULL,
    ),
  ));
}

class FlexSlider extends BlockBase {
  /**
   * {@inheritdoc}
   */
  public function build() {
    return array(
      '#theme' => 'slider',
      '#slides' => my_module_get_slides(),
      '#attached' => array(
        'library' => array(
          'my_module/assets',
        ),
      ),
    );
  }
}

```

Depending on what returned from `my_module_get_slides`, `build()` could also need to set cache keys, cache contexts, or cache tags to make the output be cached, and invalidate the cache when necessary. See Render API overview for more details on how those values are used for rendered elements.

---
Tags: views, blocks
---


# Question
Title: Having required (*) show up on the component itself and not the label
I'm creating a webform select options component and I want to hide the label.

Because this is a required, it needs to display with the red asterisk that the field is required.

However, the asterisk is displayed against the label header and when you hide the label, it doesn't get displayed in the option itself.

Is there any way around this?

# Answer
Have you tried Form Placeholder? It will hide the label and add the asterisk on the select field.
> 1 votes

---
Tags: 7, webforms
---


title: Views Grouping field position

text:
# Question
Title: Views Grouping field position
I have a view and i use a date field for grouping. The position of the grouping field is at the top of the view row. Is it possible to position the grouping field at the bottom of the view row?

# Answer
With a view template file it was possible to place the grouping field at the bottom of the View.
> 0 votes

---
Tags: views
---


# Question
Title: Creating a view which lists all taxnomy terms and the number they appear in a content type?
So i have a taxonomy called `Product Warnings`, and it has around 10 terms. This taxonomy is referenced in several content types (Small products, Large products, etc), and can be selected multiple times (so a user can select in the content type 1 or up to all 10 terms from the Taxonomy).

I want to create a view which lists all terms from the given taxonomy (that's the easy part), and also count the number of times each terms is referenced in a specific content type (i.e. Small products)

So it would look like:

```
Eye damage: 44
Skin irritation: 13
Hair lose: 1
.
.
.

```

Now, this is fairly easy to do with a `db_query` and custom code, but the trick is to do it in a view (if it's possible)

# Answer
> 1 votes
Found the answer i was looking for, and that is to turn on Field Aggregation from the 3rd panel in the view.

# Answer
> 0 votes
I am not sure if it is possible to get that in a view but I know you can make a view to show content of all types, display only fields - taxonomy terms. Then, you should be able to use aggregation and count each terms occurence. Might not be the best solution tho as this one can drastically decrease the performance of that view since it counts each node.

# Answer
> -1 votes
I think you need to enable the aggregation in the view. the video here explains the same issue but in Drupal 7, but it's okay, it is the same for Drupal 8

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


# Question
Title: Naming convention for field type templates?
It seems that the naming convention for field *types* is undocumented. Looking at the classy theme shows a seemingly arbitrary convention. For example, the Text (formatted, long, with summary) type as displayed in the UI is apparently named `field--text-with-summary.html.twig` as a template file.

What are the naming conventions for field types and how could I have determined them myself?

# Answer
The naming convention for field templates is documented here, Twig Template naming conventions

> * field--node--\[field-name\]--\[content-type\].html.twig
> * field--node--\[field-name\].html.twig
> * field--node--\[content-type\].html.twig
> * field--\[field-name\].html.twig
> * field--\[field-type\].html.twig field.html.twig

But `field--text-with-summary.html.twig` is one of those that is harder/trickier to figure out from just looking at the Field Type.

---

To make Drupal life easy for this, you can enable Twig Debug. See Locating Template Files with Debugging

Now when you inspect element with browser, you can see which template file is being used (the one with the "x") and what other available template file names (the ones with "\*") you could use.
> 5 votes

---
Tags: theming
---


# Question
Title: separate the page title from page content
I am using {{ page.content }} to print all my page content. It is printing my all content but I want to remove title from this content and print it separately in different div structure (without using page.content). Currently its taking drupal default structure. Is it possible?

# Answer
> 2 votes
as @Hodba Khalaf mentioned in comment **Page title is a block** go to ***admin/structure/block*** a block called **Page title** added by core

But you can render page content without specific field in twig by using `without filter` for example you can render page content without page title try something like:

```
    {{ page.content|without('bartik_page_title') }}

```

**Note :** in the example above page title block element is `bartik_page_title` because i use bartik theme so it could be different in your case, dump the **page.content** to get the key of your title page.

---
Tags: theming, nodes
---


title: Layouts using the grid system

text:
# Question
Title: Layouts using the grid system
How can I lay out blocks or paragraphs using Bootstrap's grid system? I found this seven-year-old answer and am hoping things have evolved since then, and if so would like to know how.

My best stab at cobbling together something at this point is to use Paragraphs for the content and use the Block Class module to assign the desired Bootstrap class to each paragraph type. Is there a more obvious and cleaner solution to the problem in Drupal 8?

# Answer
The Paragraphs Grid module provides this functionality.

> With Paragraphs Grid, you can display multiple paragraph entities in a grid. **Supports Out-Of-The-Box Bootstrap 3.0 and 4.0** and CSS grid from MDC (Material Design).

---
> 2 votes

# Answer
paragraphs are generated under the block system if you create under content type, and for the bootstrap to happens you have to add in your css skills into it and as for ready solutions, you can use https://www.drupal.org/project/ds and https://www.drupal.org/project/bootstrap\_layouts

this should be your good starting point :)
> 0 votes

---
Tags: 8, bootstrap-theme
---


# Question
Title: Entity Reference Custom Entity not visible
I made the following module with a custom entity in it.

This is all working fine, but now i want to make a entity reference field in some content type to this custom entity.

For this i made the ConfigurationSelection.php file which looks like this :

```
<?php

namespace Drupal\sg_configuration_rule\Plugin\EntityReferenceSelection;

use Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection;

/**
 * Provides specific access control for the comment entity type.
 *
 * @EntityReferenceSelection(
 *   id = "default:sg_configuration_selection",
 *   label = @Translation("Configuration Selections selection"),
 *   entity_types = {"configuration_rule"},
 *   group = "default",
 *   weight = 1
 * )
 */
class ConfigurationSelection extends DefaultSelection {

  /**
   * {@inheritdoc}
   */
  protected function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
    $query = parent::buildEntityQuery($match, $match_operator);

    return $query;
  }

  /**
   * {@inheritdoc}
   */
  public function createNewEntity($entity_type_id, $bundle, $label, $uid) {
    $rule = parent::createNewEntity($entity_type_id, $bundle, $label, $uid);

    return $rule;
  }

  /**
   * {@inheritdoc}
   */
  public function validateReferenceableNewEntities(array $entities) {
    $entities = parent::validateReferenceableNewEntities($entities);

    return $entities;
  }

}

```

This custom entity is not found when want to select it when adding a reference field:

My entity itself looks like this:

```
<?php

namespace Drupal\sg_configuration_rule\Entity;

use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Entity\EntityChangedTrait;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\user\UserInterface;

/**
 * Defines the Configuration rule entity.
 *
 * @ingroup sg_configuration_rule
 *
 * @ContentEntityType(
 *   id = "configuration_rule",
 *   label = @Translation("Configuration rule"),
 *   handlers = {
 *     "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
 *     "list_builder" = "Drupal\sg_configuration_rule\ConfigurationRuleListBuilder",
 *     "views_data" = "Drupal\sg_configuration_rule\Entity\ConfigurationRuleViewsData",
 *
 *     "form" = {
 *       "default" = "Drupal\sg_configuration_rule\Form\ConfigurationRuleForm",
 *       "add" = "Drupal\sg_configuration_rule\Form\ConfigurationRuleForm",
 *       "edit" = "Drupal\sg_configuration_rule\Form\ConfigurationRuleForm",
 *       "delete" = "Drupal\sg_configuration_rule\Form\ConfigurationRuleDeleteForm",
 *     },
 *     "access" = "Drupal\sg_configuration_rule\ConfigurationRuleAccessControlHandler",
 *     "route_provider" = {
 *       "html" = "Drupal\sg_configuration_rule\ConfigurationRuleHtmlRouteProvider",
 *     },
 *   },
 *   base_table = "configuration_rule",
 *   admin_permission = "administer configuration rule entities",
 *   entity_keys = {
 *     "id" = "id",
 *     "label" = "name",
 *     "uuid" = "uuid",
 *     "uid" = "user_id",
 *     "langcode" = "langcode",
 *     "status" = "status",
 *   },
 *   links = {
 *     "canonical" = "/admin/stargazer/configuration_rule/{configuration_rule}",
 *     "add-form" = "/admin/stargazer/configuration_rule/add",
 *     "edit-form" = "/admin/stargazer/configuration_rule/{configuration_rule}/edit",
 *     "delete-form" = "/admin/stargazer/configuration_rule/{configuration_rule}/delete",
 *     "collection" = "/admin/stargazer/configuration_rule",
 *   },
 *   field_ui_base_route = "configuration_rule.settings"
 * )
 */
class ConfigurationRule extends ContentEntityBase implements ConfigurationRuleInterface {

  use EntityChangedTrait;

  /**
   * {@inheritdoc}
   */
  public static function preCreate(EntityStorageInterface $storage_controller, array &$values) {
    parent::preCreate($storage_controller, $values);
    $values += [
      'user_id' => \Drupal::currentUser()->id(),
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getName() {
    return $this->get('name')->value;
  }

  /**
   * {@inheritdoc}
   */
  public function setName($name) {
    $this->set('name', $name);
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function getCreatedTime() {
    return $this->get('created')->value;
  }

  /**
   * {@inheritdoc}
   */
  public function setCreatedTime($timestamp) {
    $this->set('created', $timestamp);
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function getOwner() {
    return $this->get('user_id')->entity;
  }

  /**
   * {@inheritdoc}
   */
  public function getOwnerId() {
    return $this->get('user_id')->target_id;
  }

  /**
   * {@inheritdoc}
   */
  public function setOwnerId($uid) {
    $this->set('user_id', $uid);
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function setOwner(UserInterface $account) {
    $this->set('user_id', $account->id());
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function isPublished() {
    return (bool) $this->getEntityKey('status');
  }

  /**
   * {@inheritdoc}
   */
  public function setPublished($published) {
    $this->set('status', $published ? TRUE : FALSE);
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function getPluginType() {
    $baseApiPluginManager = \Drupal::service('plugin.manager.base_api_plugin');
    return $baseApiPluginManager->createInstance($this->get('plugin_type')->value);
  }

  /**
   * {@inheritdoc}
   */
  public function setPluginType($plugin_type) {
    $this->set('plugin_type', $plugin_type);
    return $this;
  }

  /**
   * Get the server node.
   *
   * @return \Drupal\node\Entity\Node
   *   The server node as object.
   */
  public function getServerNode() {
    return $this->get('server_node')->first()->entity;
  }

  /**
   * {@inheritdoc}
   */
  public function setServerNode($server_node_id) {
    $this->set('server_node', $server_node_id);
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function getConfig() {
    return $this->get('configuration')->first()->getValue();
  }

  /**
   * {@inheritdoc}
   */
  public function setConfig($config) {
    $this->set('configuration', $config);
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function getHash() {
    return $this->get('hash')->value;
  }

  /**
   * {@inheritdoc}
   */
  public function setHash($hash) {
    $this->set('hash', $hash);
    return $this;
  }

  /**
   * {@inheritdoc}
   *
   * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
   */
  public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
    $fields = parent::baseFieldDefinitions($entity_type);

    $fields['user_id'] = BaseFieldDefinition::create('entity_reference')
      ->setLabel(t('Authored by'))
      ->setDescription(t('The user ID of author of the Configuration rule entity.'))
      ->setRevisionable(TRUE)
      ->setSetting('target_type', 'user')
      ->setSetting('handler', 'default')
      ->setTranslatable(TRUE)
      ->setDisplayOptions('view', [
        'label' => 'hidden',
        'type' => 'author',
        'weight' => 0,
      ])
      ->setDisplayOptions('form', [
        'type' => 'entity_reference_autocomplete',
        'weight' => 5,
        'settings' => [
          'match_operator' => 'CONTAINS',
          'size' => '60',
          'autocomplete_type' => 'tags',
          'placeholder' => '',
        ],
      ])
      ->setDisplayConfigurable('form', TRUE)
      ->setDisplayConfigurable('view', TRUE);

    $fields['name'] = BaseFieldDefinition::create('string')
      ->setLabel(t('Name'))
      ->setDescription(t('The name of the Configuration rule entity.'))
      ->setSettings([
        'max_length' => 50,
        'text_processing' => 0,
      ])
      ->setDefaultValue('')
      ->setDisplayOptions('view', [
        'label' => 'above',
        'type' => 'string',
        'weight' => -4,
      ])
      ->setDisplayOptions('form', [
        'type' => 'string_textfield',
        'weight' => -4,
      ])
      ->setDisplayConfigurable('form', TRUE)
      ->setDisplayConfigurable('view', TRUE)
      ->setRequired(TRUE);

    $fields['plugin_type'] = BaseFieldDefinition::create('string')
      ->setLabel(t('Plugin'))
      ->setDescription(t('The plugin type of the Configuration rule entity.'))
      ->setSettings([
        'max_length' => 255,
        'text_processing' => 0,
      ])
      ->setDefaultValue('')
      ->setDisplayOptions('view', [
        'label' => 'above',
        'type' => 'string',
        'weight' => -4,
      ])
      ->setDisplayOptions('form', [
        'type' => 'string_textfield',
        'weight' => -4,
      ])
      ->setDisplayConfigurable('form', TRUE)
      ->setDisplayConfigurable('view', TRUE)
      ->setRequired(TRUE);

    $fields['server_node'] = BaseFieldDefinition::create('entity_reference')
      ->setLabel(t('Server node'))
      ->setDescription(t('The server node linked to the Configuration rule entity.'))
      ->setSetting('target_type', 'node')
      ->setSetting('handler', 'default')
      ->setDisplayOptions('view', [
        'label' => 'hidden',
        'type' => 'node',
        'weight' => -4,
      ])
      ->setDisplayOptions('form', [
        'type' => 'options_select',
        'weight' => 5,
        'settings' => [
          'match_operator' => 'CONTAINS',
          'size' => '60',
          'autocomplete_type' => 'tags',
          'placeholder' => '',
        ],
      ])
      ->setDisplayConfigurable('form', TRUE)
      ->setDisplayConfigurable('view', TRUE)
      ->setRequired(TRUE);

    $fields['configuration'] = BaseFieldDefinition::create('map')
      ->setLabel(t('Configuration'))
      ->setDescription(t('The custom configuration of the Configuration rule entity.'))
      ->setDisplayConfigurable('form', FALSE)
      ->setDisplayConfigurable('view', FALSE)
      ->setRequired(FALSE);

    $intervals = [
      60,
      900,
      1800,
      3600,
      7200,
      10800,
      21600,
      32400,
      43200,
      64800,
      86400,
      172800,
      259200,
    ];
    $period = array_map([
      \Drupal::service('date.formatter'),
      'formatInterval',
    ], array_combine($intervals, $intervals));
    $period[0] = t('Never');

    $fields['cron_settings'] = BaseFieldDefinition::create('list_integer')
      ->setLabel(t('Run every'))
      ->setDescription(t('The length of time between each cron run for this single job.'))
      ->setDefaultValue(3600)
      ->setSetting('unsigned', TRUE)
      ->setRequired(TRUE)
      ->setSetting('allowed_values', $period)
      ->setDisplayOptions('form', [
        'type' => 'options_select',
        'weight' => 80,
      ])
      ->setDisplayConfigurable('form', TRUE);

    $fields['status'] = BaseFieldDefinition::create('boolean')
      ->setLabel(t('Publishing status'))
      ->setDescription(t('An indication whether the Configuration rule is active.'))
      ->setDefaultValue(TRUE)
      ->setDisplayOptions('form', [
        'type' => 'boolean_checkbox',
        'weight' => 99,
      ]);

    $fields['hash'] = BaseFieldDefinition::create('string')
      ->setLabel(t('Identification hash'))
      ->setDescription(t('The unique has of the Configuration rule entity.'))
      ->setSettings([
        'max_length' => 255,
        'text_processing' => 0,
      ])
      ->setDefaultValue('');

    $fields['created'] = BaseFieldDefinition::create('created')
      ->setLabel(t('Created'))
      ->setDescription(t('The time that the entity was created.'));

    $fields['changed'] = BaseFieldDefinition::create('changed')
      ->setLabel(t('Changed'))
      ->setDescription(t('The time that the entity was last edited.'));

    return $fields;
  }

}

```

# Answer
> 3 votes
As seen in Drupal\Core\Entity\EntityType

/\** * Indicates whether this entity type is commonly used as a reference target. * * This is used by the Entity reference field to promote an entity type in the * add new field select list in Field UI. * * @var bool \*/ protected $common\_reference\_target = FALSE;

Once you add **common\_reference\_target = TRUE** in your custom entity annotation you should be able to see your custom Entity under Entity Reference field

---
Tags: 8, plugins
---


# Question
Title: Looping through an array using Migrate Plus
I'm trying to loop through an array (called "Attributes") in a JSON migration source, but I can't figure out how to do it. Here's a shortened sample of my data source:

```
[
  {
    "Id": "ST00000002",
    "Title": "Fast & Furious 9",
    "Attributes": [
      "0000000013",
      "0000000015"
    ]
  }
]

```

My ultimate goal is to check certain checkbox/boolean fields based on those attribute values, but I can't figure out how to handle each of the attributes individually.

Things I have tried so far:

* Using `single_value` and `multiple_values`
* Using the custom `Deepen` process plugin (as seen on this issue)
* Using `sub_process`
* Using the `static_map` plugin (to do something like this:

```
map:
    '0000000015': 1
default_value: 0

```
* Using `skip_on_value` with `not_equals: true`
* Using countless combinations of the above functions

I feel like this can't possibly be as difficult as I'm making it, so I hope someone can help me out. Thank you so much.

# Answer
Thank you so much. I got it to work by creating a custom process plugin using "in\_array", as suggested. If anyone's interested, here's the plugin I created:

```
namespace Drupal\migrate_veezi\Plugin\migrate\process;

use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\MigrateException;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\Row;

/**
 * Check if value exists in array
 *
 * @MigrateProcessPlugin(
 *   id = "in_array"
 * )
 *
 * To check if value is in array, use the following:
 *
 * @code
 * field_text:
 *   plugin: in_array
 *   source: array
 *   search: 'string'
 * @endcode
 *
 */

class InArray extends ProcessPluginBase {

  /**
   * {@inheritdoc}
   */
  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {

    $search = $this->configuration['search'];

    if ($search) {
      if (is_array($value) || $value instanceof \Traversable) {
        return in_array($search, $value);
      }
      else {
        throw new MigrateException(sprintf('%s is not traversable', var_export($value, TRUE)));
      }
    }
    else {
      throw new MigrateException(sprintf('search value is not set'));
    }
  }

}

```

And then I used it like this:

```
field_closed_caption:
    -
      plugin: single_value
      source: attributes
    -
      plugin: in_array
      search: '0000000007'

```
> 0 votes

---
Tags: migrations, 8
---


# Question
Title: How to save files to a private directory?
I am writing a custom module in which data is written to a file and the file is stored in a private directory folder.

In order to do so I have created a private directory and assigned required permissions to it(can confirm it is writable, tested it by creating a new content type from UI and added a file upload filed and able to save uploaded file to that directory). But my problem is I can't save the file to that directory programmatically.

I get an error stating :

> The data could not be saved because the destination /var/www/html/sites/sitename/files/private/file.json is invalid. This may be caused by improper use of file\_save\_data() or a missing stream wrapper.

My private directory is located in files directory as a subdirectory and named as private, I have configured it in settings.php and can view it in `https://example.com/admin/config/media/file-system` of course cleared the cache after configuring the private directory in settings.php.

I can save file into public directory using the following code:

```
    $output = Json::encode($data);

    $directory = file_default_scheme() . '://userslist';

    file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);

    $fileLocation = $directory.'/'.JSON_FILENAME;

    $file = file_save_data($output, $fileLocation, FILE_EXISTS_REPLACE);

```

But I can't save in subfolder in public directory using the following code :

```
    $directory = \Drupal::service('file_system')->realpath("public://userslist");

```

Same is the case with private directory :

```
    $directory = \Drupal::service('file_system')->realpath("private://");

```

I can even save data using the following code :

```
    $directory = file_default_scheme() . '://private';

```

as the private directory is present as a subdirectory in public directory hence assigned manually public directory path above.

But can't save using the **`realpath`** which obtains the private or public file directory path dynamically.

Can anyone help me out to solve the issue?

I tried the functionality in two different system environments one is Linux and other is windows and I get the same error as above.

Thanks.

**Edit 1 :** I hade made some trail and errors and got the following results but still cant find a correct way to save the file to private directory.

```
    // My private file configuration in settings.php
    $settings['file_private_path'] = 'sites/sitename/files/private';

    $directory = file_default_scheme() . '://userslist';
    dpm($directory); // public://userslist
    // File is writable to the directory and can be accessed through browser.

    $directory = PrivateStream::basePath(). '://userslist'; ;
    dpm($directory); // sites/sitename/files/private://userslist

    $directory = PrivateStream::basePath(). '/userslist'; ;
    dpm($directory); // sites/sitename/files/private/userslist

    $directory = drupal_realpath('public://userslist');
    dpm($directory);  // /var/www/html/sites/sitename/files/userslist

    $directory = \Drupal::service('stream_wrapper_manager')->getViaUri('private://userslist')->getUri();
    dpm($directory); // private://userslist

    // File is writable to the directory and can't be accessed through browser.
    // normally a file which is present in private directory and accessed through browser will have the following url pattern

    // https://example.com/sitename/default/files/private/userslist/file.json
    // but it has the following pattern.
    // https://example.com/sitename/system/files/userslist/file.json

    $directory = \Drupal::service('file_system')->realpath(file_default_scheme().'://userslist');
    dpm($directory); // /var/www/html/sites/sitename/files/userslist

    $directory = \Drupal::service('file_system')->realpath("private://userslist") ;
    dpm($directory); // /var/www/html/sites/sitename/files/private/userslist

    $directory = \Drupal::service('file_system')->realpath("public://userslist");
    dpm($directory); // /var/www/html/sites/sitename/files/userslist

    $directory = file_default_scheme() . '://private/userslist';
    dpm($directory); //public://private/userslist

```

# Answer
Your code is almost there, you don't need `realpath` really. Constructing the `$directory` variable as a stream wrapper URI (i.e. `private://SOME_PATH`) is the standard way.

You get that error from `file_valid_uri()` \- which is called by `file_save_data()` \- and expects a Stream Wrapper `$destination` parameter (no absolute/relative paths).

In general, I would suggest you keep away from absolute/relative file paths and use stream wrappers URI syntax, the functions you are using support and/or expect them.

The following code will allow you to use the private filesystem:

```
use Drupal\Core\StreamWrapper\PrivateStream;
...
...
$file_save_path_stream_directory =  'private://userslist';
...
...
file_prepare_directory($file_save_path_stream_directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);

$fileLocation = $file_save_path_stream_directory . '/' . JSON_FILENAME;

$file = file_save_data($output, $fileLocation, FILE_EXISTS_REPLACE);

```

Good luck!

P.S.: Do read this Change Record (https://www.drupal.org/node/2392959), holds important relative information.
> 3 votes

# Answer
While this is an old question I would like to point out that this is now deprecated. We should use `\Drupal::service('file_system')` now instead.

As `file_prepare_directory` now states:

```
function file_prepare_directory(&$directory, $options = FileSystemInterface::MODIFY_PERMISSIONS) {
  @trigger_error('file_prepare_directory() is deprecated in Drupal 8.7.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\File\FileSystemInterface::prepareDirectory(). See https://www.drupal.org/node/3006851.', E_USER_DEPRECATED);
  return \Drupal::service('file_system')->prepareDirectory($directory, $options);
}

```

Please see https://www.drupal.org/node/3006851 for more information.
> 7 votes

# Answer
I agree with @Stefanos Petrakis you don't need realpath because,`file_valid_uri()`will do the notice, but `$directory = PrivateStream::basePath() . '://userslist';` will gives you the path of private file it's not a valid uri either.

Try the following.

```
  $directory = \Drupal::service('stream_wrapper_manager')->getViaUri('private://userslist')->getUri();
  file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);
  $fileLocation = $directory . '/' . JSON_FILENAME;
  $file = file_save_data($output, $fileLocation, FILE_EXISTS_REPLACE);

```
> 1 votes

---
Tags: 8, files
---


# Question
Title: How to alter views exposed form and add ajax to filters
I have a views with 2 exposed filters - both taxonomy reference, select. I want to limit options in second filter based on user selection from the first. Tested with enabled/disabled ajax in views - no difference. Tested with exposed form in block - no difference.

Error message replace target filter: **"An unrecoverable error occurred. The uploaded file likely exceeded the maximum file size (60 MB) that this server supports."**

Using standard form alteration and ajax in form exposed filters, the filtering produce error. This work fine in custom form, but not in views exposed filter.

```
<?php

use Drupal\Core\Form\FormStateInterface;

function mymodule_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ($form_id == 'views_exposed_form') {
    if ($form['#id'] == 'views-exposed-form-articles-page-1') {
      //kint($form);
      //kint($form_state);
      //
      $form['field_tags2_target_id']['#prefix'] = '<div id="tags2-replace">';
      $form['field_tags2_target_id']['#suffix'] = '</div>';

      $form['field_tags_target_id']['#ajax'] = [
        'callback' => 'tags_ajax_callback',
        'wrapper' => 'tags2-replace'
      ];
    }
  }
}

function tags_ajax_callback($form, FormStateInterface $form_state) {
  // remove test2 1 (tid 3) from Tags2 options
  unset($form['field_tags2_target_id']['#options'][3]);

  $response = new AjaxResponse();
  $response->addCommand(new ReplaceCommand(
    '#tags2-replace',
    $form['field_tags2_target_id']
  ));
  return $response;

  //return $form['field_tags2_target_id'];
}

```

How to make this work?

# Answer
It is related to Ajax attached to Views exposed filter form does not trigger callbacks where 2842525-56.patch is the patch provided for that issue on August first, 2019; further patches have been provided for other Drupal releases.
> 1 votes

# Answer
If you don't want to patch the core you can create an `EventSubscriber` that attaches the view filter to the ajax command. After adding this your can use `hook_form_alter` to alter the filter. The subscriber looks like this.

file: `yourmodule.services.yml`

```
services:
  yourmodule.ajax_respose_subscriber:
    class: Drupal\yourmodule\EventSubscriber\AjaxResponseSubscriber
    tags:
      - {name: event_subscriber}

```

file: `src/EventSubscriber/AjaxResponseSubscriber.php`

```
<?php

namespace Drupal\yourmodule\EventSubscriber;

use Drupal\views\Ajax\ViewAjaxResponse;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Drupal\Core\Ajax\ReplaceCommand;

/**
 * Response subscriber to handle AJAX responses.
 */
class AjaxResponseSubscriber implements EventSubscriberInterface {

  /**
   * Renders the ajax commands right before preparing the result.
   *
   * @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
   *   The response event, which contains the possible AjaxResponse object.
   */
  public function onResponse(FilterResponseEvent $event) {
    $response = $event->getResponse();

    // Only alter views ajax responses.
    if (!($response instanceof ViewAjaxResponse)) {
      return;
    }
    $view = $response->getView();

    // Only alter commands if view is ours.
    if ($view->storage->id() != 'yourviewname') {
      return;
    }

    // Alter commands.
    $display_handler = $view->display_handler;
    if ($display_handler->ajaxEnabled() && $display_handler->usesExposedFormInBlock()) {
      $form = $display_handler->viewExposedFormBlocks();
      $rendered_form = \Drupal::service('renderer')->renderRoot($form);
      $response->addCommand(new ReplaceCommand("#{$form['#id']}", $rendered_form));
    }

  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    return [KernelEvents::RESPONSE => [['onResponse']]];
  }

}

```

Sources:  &
> 0 votes

---
Tags: 8, ajax, views, forms
---


# Question
Title: How to alter the POS order item table header and columns
Using Drupal 8/Commerce 2 and the Commerce Point of Sale (POS) module, the autocomplete form to search and add a product to an order shows this table header.

> As indicated by @JayPan below, here is the code that outputs the header and the order item https://git.drupalcode.org/project/commerce\_pos/-/blob/8.x-2.x/src/Plugin/Field/FieldWidget/PosOrderItemWidget.php#L285

My requirement is to remove the Return and Quantity columns and add custom ones based on custom fields set in the Default item type POS uses. Thank you.

# Answer
> 1 votes
Looking through the code, the table is generated as part of the form element for a field widget in `Drupal\commerce_pos\Plugin\Field\FieldWidget\PosOrderItemWidget`.

You will need to create a class that extends this class:

```
namespace Drupal\example\Plugin\Field\FieldWidget;

use Drupal\commerce_pos\Plugin\Field\FieldWidget\PosOrderItemWidget;

class ExamplePosOrderItemWidget extends PosOrderItemWidget {
  // Class methods go here.
}

```

You will then need to override the `formElement()` method (https://git.drupalcode.org/project/commerce\_pos/-/blob/8.x-2.x/src/Plugin/Field/FieldWidget/PosOrderItemWidget.php#L223)

`formElement()` generates the header for the table. You can call the parent, then alter the form object

```
/**
 * {@inheritdoc}
 */
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
  $element = parent::formElement($items, $element, $form, $form_state);
  // $element['order_items'] contains the table.
  // Make your alterations to $element['order_items']['header']
  // and $element['order_items']['rows'].
}

```

Note that `$element['order_items']` will contain the fully generated table. You should can remove any header items and column items you want, and add any new ones. However, you may want to also consider overriding `orderItemForm()` (https://git.drupalcode.org/project/commerce\_pos/-/blob/8.x-2.x/src/Plugin/Field/FieldWidget/PosOrderItemWidget.php#L321). This method generates the form elements for each table row. You could rewrite the implementation to not generate the elements you don't want, and to generate the elements you do. Then in your `formElement()` override, you will only need to alter the header of the table, as the rows will already be built with the elements you need.

After you have overridden the class, you need to implement it. There are two ways to do this, depending on your requirements.

If you want this table change to be across all field widgets of this type anytime this widget is ever used, you can use hook\_field\_widget\_info\_alter():

```
hook_field_widget_info_alter(array &$definitions) {
  $definitions['pos_order_item_widget']['class'] = 'Drupal\example\Plugin\Field\FieldWidget\ExamplePosOrderItemWidget';
}

```

You will then clear the cache, and now anywhere that the widget is implemented in the system, now or in the future, your override will be used instead of the original class.

If you want to be able to apply this change to specific fields, and still have the original implementation available, you can use your override class to create a new widget type by adding the widget annotation as the comments for your class:

```
/**
 * Plugin implementation of the 'example_pos_order_item_widget' widget.
 *
 * @FieldWidget(
 *   id = "example_pos_order_item_widget",
 *   label = @Translation("Example Pos order item widget"),
 *   field_types = {
 *     "entity_reference"
 *   },
 *   multiple_values = true
 * )
 */
class ExamplePosOrderItemWidget extends PosOrderItemWidget {

```

Now the system will have a new widget type available, `Example Pos order item widget`. You can go to the field implementation(s) you want to change, and select this widget.

---
Tags: 8, commerce
---


# Question
Title: How can I add classes to the rendered "body" field on a content type?
Preface: I don't often work with Drupal, so I may not be using the correct terminology or fully understand the stack. Please bear with me, I'll do my best to be as clear as possible.

I want to filter the rendered output of the primary "Body" field on a "Basic Page" (or "Article," any content type really) to add some classes to various elements. This would be the field labeled "Body" at `/node/add/page`. I'd like to achieve this using `DOMDocument` in my `.theme` file, but I'm having trouble figuring out what the correct "hook" is to tie in to.

So ultimately the goal would be a function something like the following (which is partially psuedo code):

```
function my_theme_body_alter(&$content) {
    $DOM = new DOMDocument();

    $DOM->loadHTML(mb_convert_encoding($content, "HTML-ENTITIES", "UTF-8"), LIBXML_HTML_NODEFDTD);

    $anchors = $DOM->getElementsByTagName("a");

    foreach ($anchors as $anchor) {
        $existing_classes = $anchor->getAttribute("class") ? $anchor->getAttribute("class") : "";

        $anchor->setAttribute("class", "button {$existing_classes}");
    }

    $content = $DOM->saveHTML($content);

    return $content;
}

```

To be absolutely clear, I want to modify the output (on the front end) of this field:

What is the name of the hook I'm looking for, or how can I locate it myself?

# Answer
> note:I have tested it in my machine and it works 100%

1. the `Hook_preprocess_node` is gonna be executed before the rendering of any node of any content-type, you have to apply your logic here but be sure to apply it only of the body field exist otherwise you'll get an error if some content type doesn't have this field, then inject the updated dom into the node.html.twig template using the $varaibles that has been passed by ref to the current hook:

```
<?php
/**
* Implements  hook_preprocess_hook
*/
function test_preprocess_node(&$variables){
 // 1. Getting the current node.
 $node = $variables['node'];

 //2. Apply this logic to all nodes that have a body field
 if( $node->hasField('body')){

   //3.Get the body field
    $body = $node->body->value;

    //4.Apply som logic on the body field
     $body = updateBodyDom($body);

   //5.injecting the result into the node template (ex: node.html.twig)
   $variables['body'] =  $body ;
 }

}

function updateBodyDom($body){
 $DOM = new DOMDocument();

 $DOM->loadHTML(mb_convert_encoding($body, "HTML-ENTITIES", "UTF-8"), LIBXML_HTML_NODEFDTD);

 $anchors = $DOM->getElementsByTagName("a");

 foreach ($anchors as $anchor) {
   $existing_classes = $anchor->getAttribute("class") ? $anchor->getAttribute("class") : "";
   $anchor->setAttribute("class", "button {$existing_classes}");

   //kint($anchor-> getAttribute('class')); die();
 }

 $content = $DOM->saveHTML( );
 return   $content;
}

```
2. in your templates folder create node.html.twig, to render the injected body :

```
{{ body }}

```
> 0 votes

---
Tags: 8, hooks
---


# Question
Title: How do I create a HTML link from an internal path using the core Link class?
I miss the deprecated `l()` *a lot*. I am trying to construct the Drupal 8 equivalent of:

```
l(t('mylink'), 'admin/structure/types');

```

This call generates this HTML:

```
'<a href="/admin/structure/types">mylink</a>'

```

I want to know how to produce the same HTML (i.e. a string) using the **Link** class.

Please understand that I am not looking asking how to *render* the link. I need the string for other purposes than rendering. I fully aware of that usually, one wants to *render* the link. If that is what you want to do, you should look at the accepted answer to this question: How do I create a link?.

I am trying to generate an HTML link to`'admin/structure/types'`. But will appreciate an answer that explains how to do this for *any* valid internal path.

I've looked at a lot of examples, a most of the them end up saying one should use `Link::fromTextAndUrl` in some construct like this - *without* explaining how to get $routename from the path.:

```
Link::fromTextAndUrl(t('mylink'), Url::fromRoute($routeName));

```

However, by searching (as suggested by Jaypan) I was able to determine that the routename for this path was `'entity.node_type.collection'`. This works as one would expect:

```
  $url = Url::fromRoute('entity.node_type.collection');
  $url_string = $url->toString();

```

I.e.: `$url_string` is now `'admin/structure/types'`.

So I proceed to build a link object

```
$link = Link::fromTextAndUrl(t('mylink'), Url::fromRoute('entity.node_type.collection'));

```

Now: How to get an HTML string?

No Sssweat suggests:

```
$url = Url::fromRoute('book.admin');
$link_thingy = Link::fromTextAndUrl(t('mylink'), $url)->toString();

```

This step just make `$link_thingy` into an object. Close, but no cigar.

In an updated version of his answer, Jaypan says that *treating* this object like a string - example:

```
 print Link::fromTextAndUrl(t('mylink'), Url::fromRoute('user.login'))->toString();

```

outputs the HTML string. This works. This means you will have the HTML string when you *use* it in a context one would use a string. Therefore, I've accepted Jaypan's answer.

I've also tried out the kiamlaluno's answer, i.e.:

```
 $link_thingy = $link->toRenderable();

```

This produces a (huge) render array, not a string. A render array, however, is a very useful thing (see comments for why this is so), but it is *not* accepted as answer to *this* question because the question was: How to get an HTML string?

Environment: Clean install of Drupal 8.8.6 (core + devel). Ubuntu 20.04 LTS.

# Answer
Getting the route can be tricky. Sometimes I'll just do a code search for the path.

Routes are defined in `[MODULE].routing.yml` files. You can often look for a route you need if you can guess the module that supplies it. For example, the user login page is provided by the user module, so I look in `user.routing.yml`, in which I find this for the user login route:

```
user.login:
  path: '/user/login'
  defaults:
    _form: '\Drupal\user\Form\UserLoginForm'
    _title: 'Log in'
  requirements:
    _user_is_logged_in: 'FALSE'
  options:
    _maintenance_access: TRUE

```

The route name here is `user.login`. Now, that route name can be used to do the following:

```
$url = Url::fromRoute('user.login');
// Build a link:
$link = Link::fromTextAndUrl(t('Log In'), $url);
// Get the link string:
$link_string = $link->toString();

```

Note that `$link->toString()` returns an object of type `Drupal\Core\GeneratedLink`. This class has the magic method GeneratedLink::\__toString(). This magic method is invoked when the object is treated like a string. That means you can treat the result of `$link->toString()` as if it were a string, even though it's an object. So in context where you can print values, this will work:

```
print Link::fromTextAndUrl(t('mylink'), Url::fromRoute('user.login'))->toString();

```
> 3 votes

# Answer
`Link` is the correct class to use in those cases. Drupal core itself uses it to get a link to shown in a page or a form, for example in `ImageFormatter::settingsForm()`.

```
  $description_link = Link::fromTextAndUrl($this->t('Configure Image Styles'), Url::fromRoute('entity.image_style.collection'));
  $element['image_style'] = [
    '#title' => t('Image style'),
    '#type' => 'select',
    '#default_value' => $this->getSetting('image_style'),
    '#empty_option' => t('None (original image)'),
    '#options' => $image_styles,
    '#description' => $description_link->toRenderable() + [
      '#access' => $this->currentUser->hasPermission('administer image styles'),
    ],
  ];

```

`Link::toRenderable()` returns a render array representing the object.

As for getting the Url object passed as second argument to that method. `Url::fromRoute()` is normally the used method. Otherwise, there are other methods that can be helpful, such as:

* `Url::fromUserInput()` when the relative path is entered by a user and the path can exist or not
* `Url::fromEntityUri()` when the URI is for an entity, for example entity:node/1
* `Url::fromInternalUri()` for a generic internal URL given, for example internal:/node/add (the page to create a new node) or internal:/ (the front page)
> 4 votes

# Answer
Nothing new here than what the other answers provide. Maybe laying it out like this will make it clearer.

**Drupal 7:**

```
// Internal path.
$internal_link = l(t('Book admin'), 'admin/structure/book');

// External Uri.
$external_link = l(t('External link'), 'http://www.example.com/', array('external' => TRUE));

```

**Drupal 8 (deprecated):**

```
// Internal path (defined by a route in Drupal 8).
use Drupal\Core\Url;
$url = Url::fromRoute('book.admin');
$internal_link = \Drupal::l(t('Book admin'), $url);

// External Uri.
use Drupal\Core\Url;
$url = Url::fromUri('http://www.example.com/');
$external_link = \Drupal::l(t('External link'), $url);

```

\Drupal::l has also been deprecated (as of Drupal 8.0.0). Use \Drupal\Core\Link instead.

**Drupal 8 & 9:**

```
use Drupal\Core\Link;
use Drupal\Core\Url;
$url = Url::fromRoute('book.admin');
$internal_link = Link::fromTextAndUrl(t('Book admin'), $url)->toString();

```

<sub>Source: Change record l() and url() are removed in favor of a routing based URL generation API </sub>
> 1 votes

# Answer
Answering the part added later to the question:

> Please understand that I am not looking asking how to render the link. I need the string for other purposes than rendering. I fully aware of that usually, one wants to render the link.

URL and Link objects are first of all data objects and you can create and put data in them at any point while building content. But when rendered, which includes applying the method toString(), they produce not only the HTML string but also cache and attachments metadata. Normally this metadata bubbles up when executed in a render context in theming hooks and templates. Not when rendered too early, then the metadata gets lost or causes errors. For example TrustedResponseRedirect failing - how to prevent cache metadata?.

A safe way to render non page content, for example for mails, is the method renderPlain(). See https://drupal.stackexchange.com/a/245353/47547, which you can use for all render elements, not only for links.
> 1 votes

---
Tags: 8
---


# Question
Title: Output node reference field data in page.html.twig
I have a homepage node-type in which I have an entity-reference field holding 3 references to 3 separate custom blocks.

The theme I'm working on requires that my 3 element reference field needs to be output in page.html.twig. I have overridden page.html.twig and I can see changes I have introduced once my caches are cleared.

My research led me to implementing a custom module to preprocess my homepage ouput and include the data I want printed from *page--front.html.twig*, code below:

```
function mymodule_preprocess_page(&$variables, $hook) {
    // $url_obj = Url::fromRoute('<front>');
    die('tested');
    dsm($variables);
    drupal_set_message('testing');
}

```

My problem is my preprocess function is not triggered. The module is enabled, and calling *die()* outside a function does "kill" the site, so the module file is recognized.

I would appreciate any help.

# Answer
> 0 votes
Module names are all lowercase or underscore. Your preprocess function name must start *exactly* with the same name as your module/theme. Never uppercase.

```
function mymodule_preprocess_page(&$variables) {
  ...
}

```

And there is no `$hook` parameter in this case, the `_page` function name suffix already declares this function as a specific hook only for the page hook type.

---
Tags: 8, theming, hooks
---


title: Selector bulk action missing

text:
# Question
Title: Selector bulk action missing
In the media library, I should see a dropdown selector that allows me to delete bulk items. Is there a way to turn this off and on? I've inherited this site and I'm not sure if the original owner has turned this option off somewhere.

Here is the code that should appear:

```
<div data-drupal-selector="edit-header" id="edit-header" class="js-form-wrapper form-wrapper"><div data-drupal-selector="edit-media-bulk-form" id="edit-media-bulk-form--2" class="js-form-wrapper form-wrapper"><div class="js-form-item form-item js-form-type-select form-type-select js-form-item-action form-item-action">
        <label for="edit-action">Action</label>
        <select data-drupal-selector="edit-action" id="edit-action" name="action" class="form-select">
          <option value="media_delete_action">Delete media</option>
          <option value="media_publish_action">Publish media</option>
          <option value="media_save_action">Save media</option>
          <option value="media_unpublish_action">Unpublish media</option>
       </select>
</div>

<div data-drupal-selector="edit-actions" class="form-actions js-form-wrapper form-wrapper" id="edit-actions--2">

  <input data-drupal-selector="edit-submit" type="submit"
      id="edit-submit--2" name="op"
      value="Apply to selected items"
      class="button js-form-submit form-submit" />
</div>

```

# Answer
I've finally found a solution.

I needed to go to Views/Media and add Bulk update to the Fields, but it was missing. Once I realised that I needed to restore it I found this drush command.

```
* drush cim --yes --partial --source=core/modules/media/config/optional && cr

```

Which updates the following:

```
+------------+--------------------------------------+-----------+
| Collection | Config                               | Operation |
+------------+--------------------------------------+-----------+
|            | system.action.media_delete_action    | Create    |
|            | system.action.media_publish_action   | Create    |
|            | system.action.media_save_action      | Create    |
|            | system.action.media_unpublish_action | Create    |
|            | views.view.media                     | Update    |
+------------+--------------------------------------+-----------+

```

Then clear cache and Bulk update has now been restored to the Fields section.
> 0 votes

---
Tags: media
---


title: Media Module: How to enable SVG files

text:
# Question
Title: Media Module: How to enable SVG files
I can currently upload with an Image field for SVG. I am using the SVG image module.

I just installed the Media module so I can use the Media library functionality. However when I add a new Image using Add Media. I am getting the error message I was having problems with before.

* Only files with the following extensions are allowed: png gif jpg jpeg.

Not sure where to resolve this. Please advise thanks.

# Answer
> 4 votes
You can use SVG Image Field module with Drupal 8 and the new core Media module.

1. Enable Media module and the experimental Media Library module both of which are found in Drupal \>=8.7 core.
2. Download and enable SVG Image Field and apply to it the patch from Issue #3053011.
3. Go to /admin/structure/media and click the "Add Media Type" button.
4. For the *Media Type Name* specify 'SVG'.
5. For the *Media source* select SVG from the dropdown.
6. In the *field mappings* map Name to Name (the only option in the dropdown).
7. Click save. Then proceed to configure the Form Display and the Display for the Default and Media Library view mode at /admin/structure/media/manage/svg/form-display and /admin/structure/media/manage/svg/display respectively. You'll most likely want to just enable the "SVG" field, and disable the rest of the fields. The default display you can choose to use an inline SVG option.
8. Add a Media reference (Entity reference) field to your node types and configure it to allow the SVG bundle type. Optionally, enable other bundle types as well, like Image if you want to allow both images and SVGs in the same slot).
9. Go create a node, and click the "Add media" link.
10. Notice that the Media Library loads with a vertical tab for each kind of media type bundle you enabled in step 7 on your node configuration screen.

If you're still on the fence about how to choose the right SVG media module from Drupal 8 contrib, you may find my comparison of the 3 modules helpful to guide your decision making:

https://drupal.stackexchange.com/a/280837/3167

# Answer
> 4 votes
Update regarding this issue: As of today, SVG Image module works perfectly with Media Library functionality as well.

# Answer
> 1 votes
There has been some discussion of this on Drupal.org:

https://www.drupal.org/project/file\_entity/issues/2458377

This is most likely the solution to your problem.

https://www.drupal.org/project/media/issues/2482859

This is a warning to use caution when allowing users to upload SVG files to your website, since they can contain malicious JavaScript.

If you do not know and trust all the users with the permission to upload files to your site, you might want to consider treating SVGs like executable PHP and JavaScript source code on your Drupal site, and manage them in version control instead of with the Media module to prevent Cross-Site Scripting attacks.

---
Tags: media
---


# Question
Title: Table view: "Hide Empty Column" checkbox doesn't seem to work
I've created a view, formatted as a table.

I'm trying to hide empty columns – so, in the table settings, I've checked the "Hide Empty Column" checkbox for most of the table columns.

However, this doesn't seem to have any effect – these columns are still included in the rendered table, with empty \<td\>s.

I expect this checkbox to hide the column entirely when all data cells contain an empty value. Am I understanding this correctly?

This certainly seems to be how it worked in Drupal 7. (I'm converting an existing D7 site to D8 – and this is how the table columns were hidden on the D7 site.)

Is there anything I should check which might be preventing this from working as expected?

Thanks.

# Answer
Someone elsewhere suggested that I disable Twig debugging. This fixed this issue. Weird.
> 1 votes

---
Tags: views, 8
---


# Question
Title: Migrating content with referenced taxonomy field is to be migrated by term name
Is it possible to migrate content with term reference fields, but instead of referencing terms by their tid they are referenced by their term name?

instead of this:

```
field_tags:
  plugin: sub_process
  source: field_tags
  process:
    target_id: tid

```

Do something like this:

```
field_tags:
  plugin: sub_process
  source: field_tags
  process:
    target_id: [term name]

```

# Answer
> 4 votes
i guess `entity_lookup` what you looking for:
here is an example from ***migrate\_plus/src/Plugin/migrate/process/EntityLookup.php***

```
field_tags:
       plugin: entity_lookup
       source: tags
       value_key: name
       bundle_key: vid
       bundle: tags
       entity_type: taxonomy_term
       ignore_case: true

```

---
Tags: taxonomy-terms, migrations, plugins
---


# Question
Title: Cannot export theme settings to the .info file
I am using Drupal 7. After modifying a setting for my theme in the Appearance menu, I get the following alert message on my site's homepage:

```
The settings for this theme are currently served from a variable. You might want to export them to your .info file. This is optional and can be done the Drush command 'drush omega-export'.

```

However, when I try to run the `drush omega-export` command, it fails:

```
$ drush omega-export
The drush command 'omega-export' could not be found.  Run `drush           [error]
cache-clear drush` to clear the commandfile cache if you have installed
new extensions.
A Drupal installation directory could not be found                         [error]

```

This happens even if I run as root. I ran the `drush cache-clear drush` command successfully, but that unfortunately did not fix the issue. How do I fix this?

# Answer
The "omega" theme is the base theme for my theme. It needed to be Enabled, but not set as the default. After enabling the theme, the `drush omega-export` command worked successfully.
> 2 votes

---
Tags: 7, drush
---


# Question
Title: Why does node_access_view_all_nodes() return true for anonymous users?
On a Vanilla Drupal install (tested on D8 and D9), this will print "1":

```
drush eval 'echo node_access_view_all_nodes() . PHP_EOL;'

```

Stepping through the code reveals that it happens because there is a default grant for ALL nodes (`nid = 0`) for anonymous users in the `node_access` table (as far as I can see).

My question is about the rationale of behind this. The function description states:

> Determines whether the user has a global viewing grant for all nodes.

Why would the anonymous user have the permission to view all nodes by default? Why does this not correspond to what I see when trying to access various nodes as the anonymous user? Some nodes (e.g. unpublished nodes or anything blocked by a `node_access` hook) **do** return 403 when trying to load them as the anonymous user, so it obviously does not have access to all nodes. Is there another level of access checking hidden somewhere?

# Answer
whenever drupal needs to check if a current user has the right or not to see a specific node it passes through this process :

# 1. check if current user bypass node access

In determining access rights for a node, `\Drupal\node\NodeAccessControlHandler` first checks whether the user has the "bypass node access" permission. Such users have unrestricted access to all nodes. user 1 (administrator) will always pass this check.

# 2.check Hook\_node\_access implementations

Next, all implementations of `hook_node_access()` will be called. Each implementation may explicitly **allow**, explicitly **forbid**, or **ignore** the access request. If at least one module says to forbid the request, it will be rejected. If no modules deny the request and at least one says to allow it, the request will be permitted,

in the Example bellow whenever any user(except admin) tries to view a node we will check if field\_prevent\_webmaster is checked the user will get access forbidden message.

```
/**
 * Implements hook_ENTITY_TYPE_access
 */
function modul_name_node_access(\Drupal\node\NodeInterface $node, $operation, AccountInterface $account) {

  // 1.limit the action according to the  operation performed on the requested entity
  switch($operation){
    case 'view': // when a user visit a node page ex : /node/52

      // 2.limit the current operation according to the current account information
      if( in_array('webmaster',$account->getRoles()) ){
        //3. then further limit the current operation according to the current requested node entity field
        // ex : if field_prevent_webmaster is checked prevent a user form
        // viewing the node through the /node/{id}
        if($node->hasField('field_prevent_webmaster') ) {
          if ($node->field_prevent_webmaster->value == TRUE) {
            return AccessResult::forbidden(); // send Access denied message to the client
          }
        }

        if($node->hasField('field_allow_webmaster') ) {
          if ($node->field_allow_webmaster->value == TRUE) {
            return AccessResult::allowed(); // send Access denied message to the client
          }
        }

      }
      break;

    case 'delete':// in /admin/content page u won't find the 'delete' button
      if( in_array('webmaster',$account->getRoles()) ){

        if($node->hasField('field_prevent_webmaster') ){
          if(  $node->field_prevent_webmaster->value == true){
            return AccessResult::forbidden();
          }
        }

        if($node->hasField('field_allow_webmaster') ) {
          if ($node->field_allow_webmaster->value == TRUE) {
            return AccessResult::allowed(); // send Access denied message to the client
          }
        }

      }
      break;

    case 'update': // in /admin/content page u won't find the 'update' button
      if( in_array('webmaster',$account->getRoles()) ){

        if( $node->hasField('field_prevent_webmaster')){
          if(  $node->field_prevent_webmaster->value == true){
            return AccessResult::forbidden();
          }
        }

        if($node->hasField('field_allow_webmaster') ) {
          if ($node->field_allow_webmaster->value == TRUE) {
            return AccessResult::allowed();
          }
        }

      }
      break;
  }
}

```

# 3.Getting permissions from node\_access table

If all modules ignore the access request, then the node\_access table is used to determine access and this more complicated then the previous 2 so we need to understand :

### the node access table

* **nid**: The node id that will be affected by this permission line.
* **gid**(like user): the grant id, is simply a way to associate a user with a node.
* **realm**(like user type): It can be pretty much anything you want to consider it as a user type that groups a set of grant ids (gid).
* **grant\_view**: Boolean indicating whether a user with the realm/grant pair can view this node.
* **grant\_update**: Boolean indicating whether a user with the realm/grant pair can edit this node.
* **grant\_delete**: Boolean indicating whether a user with the realm/grant pair can delete this node.

Example according to the node\_access table bellow:

* the user that have **gid=2** and **realm=node\_atuthor**, he can **view** and **update** the **node 52**.
* the user that have **gid=2** but a **realm=node\_super\_user**, he can **view** , **update** and delete the **node 52**.

# Hook\_node\_access\_records()

when a node is saved this hook will be executed, which enables us to fill the **node\_access** table with the permission privileges that have already explore in the previous step.

```
/**
 * Implements HOOK_node_access_records
 **/
function entity_access_node_access_records(\Drupal\node\NodeInterface $node) {
   $grants = [];
   if( $node->isPublished() == TRUE) {
     $grants = [
       [
         'realm' => 'node_author',
         'gid' => $node->getOwnerId(),
         'grant_view' => 1,
         'grant_update' => 1,
         'grant_delete' => 0,
         'priority' => 0,
       ],
       [
         'realm' => 'node_viewer',
         'gid' => $node->getOwnerId(),
         'grant_view' => 1,
         'grant_update' => 0,
         'grant_delete' => 0,
         'priority' => 0,
       ],
       [
         'realm' => 'node_super_user',
         'gid' => $node->getOwnerId(),
         'grant_view' => 1,
         'grant_update' => 1,
         'grant_delete' => 1,
         'priority' => 0,
       ]
     ];
   }
  return $grants;
}

```

### Hook\_node\_grants()

is called every time access to a node is requested to determine access and this is what is used to check the node\_access table and decide who what nodes the current user can see:

```
/**
 * Implements Implements HOOK_node_grants
 */
function entity_access_node_grants(AccountInterface $account, $op) {

  // Allow the user that have 'see_omar_is_nodes' permission and that is also not omar :
  if ($account->hasPermission('see_omar_is_nodes') && $account->id() != 3){
      // to get This gid realm grants ( to see his content + Omar is content)
      $grants = [
        'node_super_user' => [$account->id()],
        'node_viewer' => [3]
      ] ;
  }

 // else if the user acount id =3 (omar)
  else if ($account->id() == 3){
    // get This gid realm grants of current user
    $grants =[
      'node_author' => [3]
    ] ;
  }

```
> 2 votes

# Answer
The node grants system allows for SQL queries to select multiple nodes, limiting them according to a user's access level. Without the grants system, when creating lists of nodes, all nodes would have to be first loaded with an SQl query, then looped through in PHP with an access checker. This is very inefficient, and also makes it nearly impossible to have any kind of efficient method of pagination. Node grants allow for loading nodes with an included permission check as part of the SQL query.

When any module implements node grants, nodes become blacklisted, and permission to perform actions on them needs to be created through a grant. If a node grant exists, permission is given.

However, node grants are added to a system as part of modules. It's very possible that a system will not have any modules that implement any node grants. If I recall correctly, that is the case on a vanilla install, and I believe your comments support that.

With no node grants system, there is no system by which to restrict access to nodes in SQL queries, and therefore it means all nodes are accessible in SQL queries.

`node_access_view_all_nodes()` is a helper function that determines if an access query even needs to be made, bypassing the access part of the SQL query when no modules implement a grants system.

> Some nodes (e.g. unpublished nodes or anything blocked by a node\_access hook) do return 403 when trying to load them as the anonymous user, so it obviously does not have access to all nodes. Is there another level of access checking hidden somewhere?

Once nodes have been loaded, each node passes through a different access control system in PHP; hook\_node\_access(). That system of access control is independent from node grants. Node access is a PHP process that determines whether an operation (view, update, delete) can be performed on a loaded node. Node grants are a system that is used when querying nodes, to allow for SQL queries that implement access controls, without requiring PHP.
> 1 votes

---
Tags: nodes
---


# Question
Title: Remove password field from user registration form
I don't want the password field to be a required user registration field. How can I remove the password field? Is this done by changes in user.module file?

# Answer
> 1 votes
Just Enable "Require e-mail verification when a visitor creates an account." in "admin/config/people/accounts" page. That will remove password fields and provide you extra security also ..

# Answer
> 1 votes
You can use Generate Password module to achieve this goal. This module makes the password field optional (or hidden) on the add new user page (admin & registration). If the password field is not set during registration, the system will generate a password. You can optionally display this password at the time it's created.

For more info go through the documentation of this module.

# Answer
> 0 votes
You need to write form\_alter

```
 function MODULE_form_alter($form, &$form_state, $form_id){
    if ($form_id == "user_register_form") {
          $form['account']['pass']['#access']  = FALSE;

    }
    return $form;
 }

```

in your form\_submit you can not save blank password in DB so while saving create one temporary password

```
        $password = user_password(8);

```

and pass it in user\_save. You may also need to alter the validation hook.

Hope this will help you

# Answer
> 0 votes
To add to @CodeSurfer's answer, you can generate a password on the form\_alter.

```
function MODULE_form_alter($form, &$form_state, $form_id){
     if ($form_id == "user_register_form") {
        $form['account']['pass']['#type'] = 'value';
        $form['account']['pass']['#value'] = sha1(user_password());
     }

```

---
Tags: users
---


# Question
Title: why do my cache entries all double up with a #cache_redirect item?
I'm caching a piece of render array by adding cache keys to it. It's getting cached correctly, but I see two rows for every instance of it.

One looks normal -- contains the render array, with a cid that looks like:

```
CACHE_KEY:[languages:language_interface]=en:[languages:language_url]=en:[theme]=MYTHEME:[user.permissions]=HASH

```

The other one had data that starts like:

```
a:2:{s:15:"#cache_redirect";b:1;s:6:"#cache";a:5:{s:4:"keys";a:1 ...

```

and its CID is:

```
CACHE_KEY:[languages:language_interface]=en:[theme]=MYTHEME:[user.permissions]=HASH

```

It looks like this is something to do with language negotiation, but why, and is this normal? The page I am loading when I am testing this is using the language prefix, so I'm not getting redirected.

# Answer
It's still a bit unclear what you are asking, but to be more precise about my comment. The bubbled up cache contexts depend initially on the content of the render array, but this content can be dependend on other things. For example a rendered link can depend on a configured language negiotiator which provides a path processors rendering links differently dependend on the language and so bubbles up the cache context you have identified.
> 0 votes

---
Tags: caching
---


title: Is filtering using images possible?

text:
# Question
Title: Is filtering using images possible?
Novice here. I'm on Drupal 7.

I have a content type with a title, image and body field. I've created two views to display that content. The two views are on a page and I need help connecting them so that clicking/tapping on the image in **View 2** will change content in **View 1**. Ideally this happens without page reload and **View 1** fades in as new image in **View 2** is clicked/tapped.

This seems like a filtering thing but I can't filter using images, I don't think!? Are Views the best way to set this up? If yes, what specifically needs to happen for the two Views to connect? If there is an easier way to set this up, what would it be? Help all! Any direction is appreciated.

# Answer
Edit: I wrote this for Drupal 8 before reading that the question is for D7. Hopefully it works in D7 as well.

You can do this using a views attachment. I'm basing it off the image you provided.

# Set up

1. Create a new content type, call it Person, give it a title, image and body field. Set up the teaser for that content type according to how you want the selected person to display in the top view.
2. Install the Ajax links API module. This is required for this solution to work.

# View 1, the list

The list is the bottom half of the image, which is a list of the people, showing a thumbnail of the image, and the title of the person.

Create a new view of the people content type. Create a page for this view.

* Set 'format' to 'grid'
* Set 'show' to 'fields'
* Add a field for `Content: ID`. Check 'exclude from display'
* Add a field for `Content: Image` (or whatever you named the image). Make sure it comes AFTER the `Content: ID` above. Rewrite the results to `<a href="/node/{{ nid }}/teaser" class="ajax-link" rel=".view-[VIEW ID] .attachment">{{ [FIELD_NAME] }}</a>`. Note that you have to replace `[FIELD_NAME]` with the name of the field, and `[VIEW ID]` with the machine name of your view.
* Add a field for `Content: Title`. Make sure it comes AFTER the `Content: ID` above. Rewrite the results to `<a href="/node/{{ nid }}/teaser" class="ajax-link" rel=".view-[VIEW ID] .attachment">{{ title }}</a>`. Note that you have to replace `[VIEW ID]` with the machine name of your view.
* Set up a pager if necessary, and customize the number of items to be shown in the grid.

Now you have a page that lists off your items in a grid, with both the title and the image ajaxified using the Ajax links Api module, ready to load content into a div. The final thing to do is to load the content into the div.

# View 2, the attachment

Next, a View's attachment is created. This will display the teaser for the first person in the list, when the page is loaded.

* Click the "+Add" Link, and select "Attachment"
* Set 'Format' to 'Unformatted list'
* Set 'Show' to 'Content', and select 'Teaser' as the view mode.
* Under 'Attachment Settings', set 'Attach to' to the first view you created (the page view).
* Set 'Attachment Position' to 'Before'
* Set 'Inherit contextual filters' to 'Yes'
* Set the pager type to 'Display a specified number of items', and set it to show a single item.

Now, when the page from the first view is loaded, the teaser for the first person will be loaded. You can alter the display of the teaser of the person content type accordingly, to show whichever fields you need.

# View 3, the ajax-loaded content

The first view is set up with ajaxified links, set to display the content of the path `/node/%/teaser`. This page does not yet exist. The final step is to set up this page, so that the links can load this content into the container specified in the ajax links.

* Click the "+Add" Link, and select "Page"
* Set the title to `<none>`
* Set the format to 'Unformatted list'
* Set 'Show' to 'Content' with the 'view mode' to 'teaser'
* Set the 'path' to `/node/%/teaser`
* Set the 'pager' to 'Display a set number of items' and set it to show 1 item.
* Add a contextual filter for `Content: ID`. 'When the value is not in the URL' set it to 'show page not found'

Now you should be able to access the page created in the first view, and click on the links to ajax load the content replacing the attachment that is initially shown on page load.
> 1 votes

---
Tags: views, ajax
---


# Question
Title: Fetching and rendering custom-library generated blocks in twig
I am using the following code in my theme to fetch 3 blocks (each containing 4 fields) generated via the custom block library interface i:e all 3 block are of the HomePage-Block type:

```
function legislation_research_theme_preprocess_page(&$variables, $hook) {
    for($i = 1; $i <= 3; $i++) {
        $block_entity = Drupal\block_content\Entity\BlockContent::load($i);// BLOCK_ID
        $block_view[$i] = \Drupal::entityTypeManager()->getViewBuilder('block_content')->view($block_entity);
    }

    if ($block_view) {
        $variables['page']['my_block'] = $block_view;
    }
}

```

In my *page--front.html.twig*, my blocks output via:

```
    {{ page.my_block }}

```

However, the output is of the individual fields from each of the blocks rather than 3 divs containing 4 fields of content from each block. That's making it impossible to to style:

Can anyone advice how I might be able to output each block but contained in individual parent divs?

# Answer
I render my custom library blocks like this:

```
{{drupal_entity('block', 'block_id')}}

```

So you have to search your block at your library and use this block's machine name where i say block\_id. Hope it helps.
> 0 votes

---
Tags: 8, theming, blocks
---


# Question
Title: How can I use LottieFiles to render animations?
I created an Lotti animation and rendered it as a .json file. Is it possible to use this file in Drupal? Almost every other site builder from Squarespace to Webflow allows this file type of animation. Anyone have experience using it?

# Answer
Sure it is. See the LottiFiles sample. **First**, you need to add the Lotti player **library** yourself first.

```
https://unpkg.com/@lottiefiles/lottie-player@latest/dist/lottie-player.js

```

Learn about adding Adding stylesheets (CSS) and JavaScript (JS) to a Drupal theme in the docs.

And **second**, find a way to place the Lotti markup on the page somewhere.

```
<lottie-player
    src="https://assets4.lottiefiles.com/packages/lf20_32NcN8.json"
    background="transparent"
    speed="1"
    style="width: 300px; height: 300px;"
    loop controls autoplay>
</lottie-player>

```

I'd probably have a field for that where you only paste the animation file URL or upload the animation file which then gets wrapped by the corresponding markup via a **custom field formatter**.

```
<lottie-player
    src="{{ field_lotti.entity.url }}"
    background="transparent"
    speed="1"
    style="width: 300px; height: 300px;"
    loop controls autoplay>
</lottie-player>

```
> 2 votes

---
Tags: 8
---


# Question
Title: Change default text (-Any-) of select option in Exposed View Filter
I am using views exposed filter.

I want to change the text `-Any-` into something else. How can I do that (without using jquery/javascript) ?

# Answer
> 5 votes
I found the solution for this. If anyone is looking for the solution can look into this example.

```
 function MYMODULE_form_views_exposed_form_alter(&$form, &$form_state) {

     //Got the Form Id by using inspect element/Firebug
     if($form["#id"] == 'views-exposed-form-tutors-page'){

         //field_city_tid is the Filter Identifier Key
         $form['field_city_tid']['#options']["All"] = 'Desired Text';

     }

  }

```

# Answer
> 5 votes
If you use the Better Exposed Filters module you can do this using the views interface. Changed exposed form style to 'better exposed filters' and adjust the settings

> The Better Exposed Filters module replaces the Views' default single- or multi-select boxes with radio buttons or checkboxes, respectively. Description fields and Select All/None links can be added to exposed filters to make for a better user experience.

# Answer
> 2 votes
You can achieve this goal via implementing hook\_form\_alter

Let e.g.

```
    /**
     * Implements hook_form_alter().
     */
    function MYMODULE_form_alter(&$form, &$form_state, $form_id) {

        if ($form_id == 'views_exposed_form' && $form_state['view']->name == 'test' && $form_state['view']->current_display == 'page_1') {
           // do your alteration stuff
 $form['field_city_tid']['#empty_option'] = t('All');// Or whatever you want to do
        }
        if ($form_id == 'views_exposed_form' && $form_state['view']->name == 'test' && $form_state['view']->current_display == 'page_2') {
           // do your alteration stuff
        }
    }

```

# Answer
> 0 votes
Concrete example of an exposed Boolean filter for a view on a *custom entity*. Note that I had to add `_value` to field names.

* Custom module name: `rsc`
* View machine name: `transactions`
* Page machine name: `purchase`
* Field name: `field_order_shipped`

Actual code:

```
function rsc_form_views_exposed_form_alter(&$form, &$form_state)
{
  if ($form['#id'] == 'views-exposed-form-transactions-purchase') {
    $form['field_order_shipped_value']['#options']['All'] = 'Any';
    $form['field_order_shipped_value']['#options']['1'] = 'Yes';
    $form['field_order_shipped_value']['#options']['0'] = 'No';
  }
}

```

---
Tags: views
---


title: Find if $view object is a block or page

text:
# Question
Title: Find if $view object is a block or page
I am unable to debug this because when I print the display object I get a memory error from the size. so with something like this I can get the display title.

```
function mailnow_views_pre_render(\Drupal\views\ViewExecutable $view) {
  $displayObj = $view->getDisplay();
  $displayName = $displayObj->display['display_title'];
}

```

I can get the machine name with `$view->current_display == 'companies_page'`

But I want to be able to get the display type for instance "Block" or "Page"

# Answer
You can get it with

```
$plugin_id = $view->style_plugin->displayHandler->getPluginId();

```
> 3 votes

---
Tags: views, 8
---


# Question
Title: Failed asserting that two strings are equal in a patch
I have submit a patch on community but I am getting an error in result that Failed asserting that two strings are equal. This is the patch.

```

index 31bf064..fa079cc 100644
--- a/advagg_css_minify/yui/CSSMin.inc
+++ b/advagg_css_minify/yui/CSSMin.inc
@@ -422,7 +422,10 @@ class CSSmin

         // restore preserved comments and strings in reverse order
         for ($i = count($this->preserved_tokens) - 1; $i >= 0; $i--) {
-            $css = preg_replace('/' . self::TOKEN . $i . '___/', $this->preserved_tokens[$i], $css, 1);
+            $preserved_tokens = $this->preserved_tokens[$i];
+            $preserved_tokens = htmlspecialchars($preserved_tokens);
+            $pt_replacepattern =  preg_replace('[^A-Za-z0-9@*.#:/ \-]', '',$preserved_tokens);
+            $css = preg_replace('/' . self::TOKEN . $i . '___/', $pt_replacepattern, $css, 1);
         }

         // Trim the final string (for any leading or trailing white spaces)
@@ -582,7 +585,10 @@ class CSSmin
         // one, maybe more? put'em back then
         if (($pos = $this->index_of($match, self::COMMENT)) >= 0) {
             for ($i = 0, $max = count($this->comments); $i < $max; $i++) {
-                $match = preg_replace('/' . self::COMMENT . $i . '___/', $this->comments[$i], $match, 1);
+                $comment = $this->comments[$i];
+                $comment = htmlspecialchars($comment);
+                $replacepattern =  preg_replace('/[^A-Za-z0-9@*. \-]/', '',$comment);
+                $match = preg_replace('/' . self::COMMENT . $i . '___/', $replacepattern, $match, 1);
             }
         }

```

# Answer
It looks like the problem might have to do with HTML escape sequences for quotes, ampersands and other meta-characters (at least in part).

Compare these lines:

```
-  content: '/* \" \' */';\n
+  content: '/* quot  */';\n

```

and these:

```
-}"]{color:red}q[style*="quotes: none"]{quotes:none}q[style*='quotes: none']{quotes:none}q:after{content:": colon & escaped double \" quotes \"."}q:after{content:' (brackets & escaped single \' quotes \') '}q:after{content:"I'm Quote"}'
+}"]{color:red}q[style*="quotes: none"]{quotes:none}q[style*='quotes: none']{quotes:none}q:after{content:": colon & escaped double \" quotes \"."}q:after{content:' (brackets & escaped single \' quotes \') '}q:after{content:"I'm Quote"}'

```

Hopefully that sets you on the right path. Don't just look at your diff, look at the PHPUnit test to see exactly what test you are failing. Good luck!
> 0 votes

---
Tags: community-official-site
---