title: Delete files on rollback in Migrate?

text:
# Question
Title: Delete files on rollback in Migrate?
I have a migration that pulls in a PDF with it and populates a content type. When I rollback the migration, it does not delete the PDFs with it.

How can I tell a migration on rollback to clean up after itself? Is there something I can put in the YAML? Is there an event I can hook into?

# Answer
I wound up doing this to solve this case:

```
<?php

namespace Drupal\mymodule\Plugin\migrate\destination;

use Drupal\migrate\Plugin\migrate\destination\EntityContentBase;
use Drupal\migrate\Plugin\MigrationInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\node\NodeInterface;

/**
 * We need rollback support for deleting files.
 *
 * @MigrateDestination(
 *   id = "myplugin"
 * )
 */
class MyPlugin extends EntityContentBase {

  /** @var string $entityType */
  public static $entityType = 'node';

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
    return parent::create($container, $configuration, 'entity:' . static::$entityType, $plugin_definition, $migration);
  }

  /**
   * {@inheritdoc}
   */
  public function rollback(array $destination_identifier) {
    $entity = $this->storage->load(reset($destination_identifier));

    // Delete attached files on Working Papers.
    if ($entity && $entity instanceof NodeInterface) {
      if ($entity->bundle() === 'working_paper') {
        $fid = $entity->get('field_paper_working_paper')->target_id;

        if ($fid) {
          $storage_handler = \Drupal::entityTypeManager()->getStorage('file');
          $entities = $storage_handler->load($fid);
          $storage_handler->delete([$entities]);
        }
      }
    }

    // Execute the normal rollback from here.
    parent::rollback($destination_identifier);
  }

}

```

In the migration yaml definition, point destination at this instead of `entity:node`:

```
destination:
  plugin: myplugin
  bundle: working_paper

```

The `$entityType` member and `create` method seemed to be required as well, otherwise Migrate did not seem to know how to parse this into a node of a particular type, despite extending from `EntityContentBase`.

The reason for wanting to do this is that its cumbersome especially while developing that files are not removed along with their entity on rollback. In my case, I have strictest confidence in that the rollback of this entity does not affect anything else because this is the only place this file will ever appear.

Is this the best way to add this type of behavior?
> 1 votes

# Answer
In my configuration migration files I have a bunch of files generated and two of them are *my\_migration**\_file\_private*** and *my\_migration**\_file***

When I ***drush mr*** I add this migrations explicitly to rollback and the magic is done in db and files folders

Hope it helps, it works for me
> 0 votes

---
Tags: 8, migrations
---


# Question
Title: Drupal 8 migrating json data with no array label
I'm learning how to create migrations in D8. However, I have this annoying issue where my migration is listed when I execute *drush migrate-status* but the **total** and **unprocessed** values are shown as **N/A**, shown below:

```
Group: JSON People (people)  Status  Total  Imported  Unprocessed  Last imported
 nodetest                     Idle    N/A    0         N/A
 people_data                  Idle    1000   0         1000

```

My json config is as follows:

```
id: nodetest
description:  Testing for a node migration
label:  Node Test
migration_group: people

source:
  plugin: url
  data_fetcher_plugin: http
  data_parser_plugin: json
  urls:
    - 'http://api.tvmaze.com/search/shows?q=family'
  # path: 'http://api.tvmaze.com/search/shows?q=family'
  item_selector:  /
  # identifierDepth: 1
  ids:
    show:
      id:
        type: integer
  fields:
    -
      name: name
      label: Name of show
      selector: name

process:
  type:
    plugin: default_value
    default_value: page
  title: name

destination:
  plugin: 'entity:node'

```

I have been unable to figure out what the issue is some I get figures rather than the **N/A** output I'm currently getting.

Any help, please!

**UPDATE:** I found I was incorrectly using **show** as the **item\_selector**. Infact, the json from the api service does not have a "label" which refers to all the json objects, as shown below:

So, I remove item\_selector from the yml data and I then get **10** instead of **N/A** in the total column of the **nodetest** migration.

**The problem now is I get `Invalid argument supplied for foreach() DataParserPluginBase.php:121 [warning]`** warnings (1 for each json object).

And, when I attempt to migrate, I get the following error:

```
Invalid argument supplied for foreach() DataParserPluginBase.php:121                                                                                [warning]
Invalid argument supplied for foreach() DataParserPluginBase.php:121                                                                                [warning]
TypeError: Argument 2 passed to Drupal\migrate\Row::__construct() must be of the type array, null given, called in                                                        [error]
/var/www/d8/core/modules/migrate/src/Plugin/migrate/source/SourcePluginBase.php on line 357 in Drupal\migrate\Row->__construct() (line 101 of
/var/www/d8/core/modules/migrate/src/Row.php) #0 /var/www/d8/core/modules/migrate/src/Plugin/migrate/source/SourcePluginBase.php(357):
Drupal\migrate\Row->__construct(Array, NULL)
#1 /var/www/d8/core/modules/migrate/src/Plugin/migrate/source/SourcePluginBase.php(330): Drupal\migrate\Plugin\migrate\source\SourcePluginBase->next()
#2 [internal function]: Drupal\migrate\Plugin\migrate\source\SourcePluginBase->rewind()
#3 /var/www/d8/core/modules/migrate/src/MigrateExecutable.php(188): FilterIterator->rewind()
#4 /usr/local/share/drush/includes/drush.inc(721): Drupal\migrate\MigrateExecutable->import()
#5 /usr/local/share/drush/includes/drush.inc(712): drush_call_user_func_array(Array, Array)
#6 /var/www/d8/modules/contrib/migrate_tools/migrate_tools.drush.inc(317): drush_op(Array)
#7 [internal function]: _drush_migrate_tools_execute_migration(Object(Drupal\migrate\Plugin\Migration), 'nodetest', Array)
#8 /var/www/d8/modules/contrib/migrate_tools/migrate_tools.drush.inc(272): array_walk(Array, '_drush_migrate_...', Array)
#9 /usr/local/share/drush/includes/command.inc(422): drush_migrate_tools_migrate_import('nodetest')
#10 /usr/local/share/drush/includes/command.inc(231): _drush_invoke_hooks(Array, Array)
#11 /usr/local/share/drush/includes/command.inc(199): drush_command('nodetest')
#12 /usr/local/share/drush/lib/Drush/Boot/BaseBoot.php(67): drush_dispatch(Array)
#13 /usr/local/share/drush/includes/preflight.inc(66): Drush\Boot\BaseBoot->bootstrap_and_dispatch()
#14 /usr/local/share/drush/drush.php(12): drush_main()
#15 {main}.
TypeError: Argument 2 passed to Drupal\migrate\Row::__construct() must be of the type array, null given, called in /var/www/d8/core/modules/migrate/src/Plugin/migrate/source/SourcePluginBase.php on line 357 in /var/www/d8/core/modules/migrate/src/Row.php on line 101 #0 /var/www/d8/core/modules/migrate/src/Plugin/migrate/source/SourcePluginBase.php(357): Drupal\migrate\Row->__construct(Array, NULL)
#1 /var/www/d8/core/modules/migrate/src/Plugin/migrate/source/SourcePluginBase.php(330): Drupal\migrate\Plugin\migrate\source\SourcePluginBase->next()
#2 [internal function]: Drupal\migrate\Plugin\migrate\source\SourcePluginBase->rewind()
#3 /var/www/d8/core/modules/migrate/src/MigrateExecutable.php(188): FilterIterator->rewind()
#4 /usr/local/share/drush/includes/drush.inc(721): Drupal\migrate\MigrateExecutable->import()
#5 /usr/local/share/drush/includes/drush.inc(712): drush_call_user_func_array(Array, Array)
#6 /var/www/d8/modules/contrib/migrate_tools/migrate_tools.drush.inc(317): drush_op(Array)
#7 [internal function]: _drush_migrate_tools_execute_migration(Object(Drupal\migrate\Plugin\Migration), 'nodetest', Array)
#8 /var/www/d8/modules/contrib/migrate_tools/migrate_tools.drush.inc(272): array_walk(Array, '_drush_migrate_...', Array)
#9 /usr/local/share/drush/includes/command.inc(422): drush_migrate_tools_migrate_import('nodetest')
#10 /usr/local/share/drush/includes/command.inc(231): _drush_invoke_hooks(Array, Array)
#11 /usr/local/share/drush/includes/command.inc(199): drush_command('nodetest')
#12 /usr/local/share/drush/lib/Drush/Boot/BaseBoot.php(67): drush_dispatch(Array)
#13 /usr/local/share/drush/includes/preflight.inc(66): Drush\Boot\BaseBoot->bootstrap_and_dispatch()
#14 /usr/local/share/drush/drush.php(12): drush_main()
#15 {main}
TypeError: Argument 2 passed to Drupal\migrate\Row::__construct() must be of the type array, null given, called in /var/www/d8/core/modules/migrate/src/Plugin/migrate/source/SourcePluginBase.php on line 357 in Drupal\migrate\Row->__construct() (line 101 of /var/www/d8/core/modules/migrate/src/Row.php).
Drush command terminated abnormally due to an unrecoverable error.

```

# Answer
> 1 votes
The source in your migration yaml should look more like this:

```
source:
  plugin: url
  data_fetcher_plugin: http
  data_parser_plugin: json
  urls:
    - 'http://api.tvmaze.com/search/shows?q=family'
  item_selector: /
  fields:
    -
      name: id
      label: "Field you want to be the source id"
      selector: path/to/id
    -
      name: name
      label: "Name of show"
      selector: name
  ids:
    id:
      type: integer

```

`ids` are picked from `fields`. In the yaml provided above, you are missing the `ids` definition and its field.

---
Tags: 8, migrations
---


# Question
Title: Change order of breadcrumbs elements in hook hook_system_breadcrumb_alter
I want to add another element to breadcrumb.
I have:
`Home > Node Title`
I want to add another link between the two elements like:
`Home > Link to view > Node Title`

I have tried with `hook_system_breadcrumb_alter` like the following:

```
/**
 * Implements hook_system_breadcrumb_alter().
 */
function MyModules_system_breadcrumb_alter(Breadcrumb &$breadcrumb, RouteMatchInterface $route_match, array $context) {
  if ( $route_match->getRouteName() === 'entity.node.canonical'){
   $node = $route_match->getParameter('node');
   if ($node instanceof  Drupal\node\Entity\Node && $node->getType() === 'my_node_type'){
     // Get the listing view url.
     $listing_url = Url::fromRoute('view.my_view_id.my_display_id');
     // Add the listing url to breadcrumbs.
     $breadcrumb->addLink(Link::fromTextAndUrl(t('Link to view'), $listing_url));
   }
  }
}

```

But i get `Home > Node Title > Link to view` instead of `Home > Link to view > Node Title`
My question is how can i change the order of the last two breadcrumbs elements?

# Answer
> 2 votes
Create a new breadcrumb instance:

```
$links = $breadcrumb->getLinks();
// change order of $links
$cacheability = \Drupal\Core\Cache\CacheableMetadata::createFromObject($breadcrumb);
$breadcrumb = new \Drupal\Core\Breadcrumb\Breadcrumb();
$breadcrumb->setLinks($links);
$breadcrumb->addCacheableDependency($cacheability);

```

---
Tags: 8, breadcrumbs
---


# Question
Title: Which hook can I use to retrieve form values after submitting a webform?
As the title suggests, I would like to know what is the correct hook for retrieving datas after a submission. The goal is to do a task based on the value of a data. Any help would be appreciated.

# Answer
> 1 votes
You can leverage webform\_get\_submissions to retrieve this data.

I also believe this question has been answered earlier with example. Refer

---
Tags: 8, webforms
---


# Question
Title: HTML isn't rendering, HTML tags are being printed
I added a view template `views-view-fields--nieuws--page.html.twig` to my theme.

The template is correct, when I edit it I see the results on my website.

```
{% for field in fields %}
  {{ field.separator }}
  {{ field.wrapper_prefix }}
    {{ field.label_html }}
    {{ field.content }}
  {{ field.wrapper_suffix }}
{% endfor %}

```

In `page.html.twig` I print the region like this:

```
{{ page.content }}

```

But my output has HTML tags in it, any idea how I can solve this?

EDIT: It appears my HTML is rendering at all through Twig

```
{% set hello = '<strong>Hello</strong>' %}
{{ hello }}

```

outputs the `<strong>` tags, too.

# Answer
> 2 votes
This is currently a known bug with the views-view-fields.html.twig template: https://www.drupal.org/node/2363423

# Answer
> 2 votes
None of the above solution worked in my case. Here how I solved it by coding

```
function mytheme_preprocess_views_view_field(&$variables) {
  if ($variables['view']->id() == 'my_viewname' && $variables['field']->field == 'field_description') {
    $output = $variables['field']->getValue($variables['row']);
    $variables['output'] = ['#markup'=> $output];
  }
}

```

In views-view-fields--my-viewname.html.twig just print the value. No need to autoscaping or raw filer

```
{{ fields.field_description.content }}

```

# Answer
> 1 votes
You need to unescape HTML. There are two working ways to accomplish this. First you can mark your field as "raw" and the html would render correctly. `{{ your_field | raw }}` should render ok.

As a second resort you can use twig's autoescape functionality:

```
{% autoescape false %}
{{ your_field }}
{% endautoescape %}

```

By this way you are telling twig not to escape html markup.

# Answer
> -2 votes
You need to add `|raw` for print html `{{ field.content|raw }}` but you need to remove wrapper

```
{{ field.wrapper_prefix }} {{ field.wrapper_suffix }}

```

---
Tags: views, 8, theming
---


title: Migration with duplicate entry error

text:
# Question
Title: Migration with duplicate entry error
I'm running migration in Drupal 8, but got a duplicate error below.

```
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '10b1b105-355b-3c77-8880-a0c247f826f3' for key 'node_field__uuid__value': INSERT INTO     [error]
{node} (vid, type, uuid, langcode) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3); Array

```

My question, is there any configuration or a migration plugin that I have to specify in my migration config yml file to check for existing record and update if exists, if not exists then create a new record?

I'm using migration\_plus module.

# Answer
> 1 votes
I found the answer from someone on Facebook group (Drupal support group) The answer is to add " --update" argument to the migration command, it will check for existing record and update it, or create new record if not exists.

---
Tags: 8, migrations
---


# Question
Title: How to override ViewsExposedFilterBlock with my own class?
I want to add an additional form element in the configuration form for `core/modules/views/src/Plugin/Block/ViewsExposedFilterBlock.php` by adding

```
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
  $form = parent::buildConfigurationForm($form, $form_state);
  $form['my_new_form_element'] = [...];

  return $form;
}

```

If I hack core and add that code in the file, it does what I want. But of course I don't want to hack core. So I'm trying to figure out how to make it so that my custom module's block class is used instead of `ViewsExposedFilterBlock.php`.

So how do I alert Views to use my class, `ExposedFilterImagesBlock.php`?

Information that I've found that might help you help me:

`ViewsExposedFilterBlock.php` has `deriver = "Drupal\views\Plugin\Derivative\ViewsExposedFilterBlock"` in its annotation. So I'm assuming the deriver plays an important role...just one that is unclear to me.

Thanks in advance for any help you can provide!

# Answer
> 3 votes
Thanks to @4k4 (here) and @nikathone and @dorf (via Slack), I was able to arrive at this, placed in `exposed_filter_images.module` (all caps should be replaced with a machine name):

```
function exposed_filter_images_block_alter(&$plugins) {
  if (isset($plugins['views_exposed_filter_block:VIEW_NAME-DISPLAY_NAME'])) {
    $plugins['views_exposed_filter_block:VIEW_NAME-DISPLAY_NAME']['class'] = \Drupal\exposed_filter_images\Plugin\Block\ExposedFilterImagesBlock::class;
  }
}

```

---
Tags: views, 8
---


title: Editor adds <p>&nbsp</p> on every enter

text:
# Question
Title: Editor adds <p>&nbsp</p> on every enter
I've got a problem with CKEditor in Drupal 8. I've searched related questions like CKeditor adds extra \<p\> tags, but almost all questions are related to Drupal 7.

So, my CKEditor automatically applies a `<p>&nbsp</p>` when I hit enter and don't type anything.

>

How can I disable this? I don't want to remove the padding or anything of a `<p>` tag. I need something that checks if the paragraph is empty and then don't display it.

# Answer
> 2 votes
have you tried toggling off the "Convert line breaks into HTML (i.e. `<br> and <p>`)" setting on the text input format?

# Answer
> 1 votes
Note that you can add your own customized filter in a custom module : as an example, this could look like this to remove empty paragraphs :

```
<?php

namespace Drupal\your_module\Plugin\Filter;

use Drupal\filter\FilterProcessResult;
use Drupal\filter\Plugin\FilterBase;
use Drupal\filter\Annotation\Filter;
use Drupal\Core\Annotation\Translation;

/**
 * Class FilterEmptyParagraphs
 * @Filter(
 *   id = "filter_empty_paragraphs",
 *   title = @Translation("Filter empty paragraphs"),
 *   description = @Translation("Removes empty paragraphs."),
 *   type = Drupal\filter\Plugin\FilterInterface::TYPE_MARKUP_LANGUAGE,
 * )
 * @package Drupal\your_module\Plugin\Filter
 */
class FilterEmptyParagraphs extends FilterBase
{
    /**
     * Performs the filter processing.
     *
     * @param string $text
     *   The text string to be filtered.
     * @param string $langcode
     *   The language code of the text to be filtered.
     *
     * @return \Drupal\filter\FilterProcessResult
     *   The filtered text, wrapped in a FilterProcessResult object, and possibly
     *   with associated assets, cacheability metadata and placeholders.
     *
     * @see \Drupal\filter\FilterProcessResult
     */
    public function process($text, $langcode)
    {
        $regex = '@<p([^>]*)>\s*\n*\t*( )*\s*\n*\t*</p>@igm';
        $text = preg_replace($regex, '', $text);
        return new FilterProcessResult($text);
    }
}

```

(regex not tested)

---
Tags: 8, wysiwyg
---


title: Adjusting Main Menu Tabs

text:
# Question
Title: Adjusting Main Menu Tabs
I am able to add tabs in the Drupal 7 Main Menu however I want to adjust spaces between these tabs.How does one adjust spaces between tabs.

Thanks

# Answer
> 1 votes
Website styles in general are coded through CSS.

Drupal implements that through themes. If you're using the default Bartik theme you can override the navigation item spacing with the margin property on the list items.

It's not recommended to modify an existing theme file if you need to adjust its style. The best practice is to create a subtheme based on the original and include the modifications in the subtheme so they override the original one.

If you're not knowledgable in themeing or CSS you can make small CSS adjustments with the help of a module like CSS Editor. This way you don't have to worry about themes or subthemes, the code will always apply.

You can try something like:

```
#main-menu-links li {
  margin-right: 20px;
}

```

You may have to clear your CSS cache in Drupal to see the changes, if you have the CSS aggregated under Performance.

---
Tags: theming
---


# Question
Title: How to display a specific form mode in a programmatically displayed form
I have a custom entity type, `property`. In `admin/structure/display-modes/form` I created a new form mode for this entity type, machine name is `property.property_status`. It only shows one field on the form.

I am now trying to show that form mode on a custom page. Right now I'm using: `\Drupal::service('entity.form_builder')->getForm($property, 'property.property_status')` but I get the error: `Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException: The "property" entity type did not specify a "property.property_status" form class`.

Any ideas? Thanks!

# Answer
You need to specify a form operation in the handler section of the custom entity:

```
/**
 * @ContentEntityType(
 *   id = "property",
 *   handlers = {
 *     "form" = {
 *       "default" = "Drupal\mymodule\Form\MyEntityForm",
 *       "status" = "Drupal\mymodule\Form\MyEntityForm",

```

You can define multiple operations for the same form class. In this example I used `status` for the form operation, because this name usually doesn't contain the entity type name.

Then you should be able to use the form mode `status` in the entity form builder:

```
\Drupal::service('entity.form_builder')->getForm($property, 'status')

```
> 4 votes

# Answer
You could override the form display in a simple way. Or for non-admin users.

**But this is not the best solution!** since this will override the form display everywhere. You may want to add more if conditions to be selective.

```
/**
 * Implements hook_entity_form_display_alter().
 */
function HOOK_entity_form_display_alter(&$form_display, $context) {
  // You may want to add some conditions to ignore this override.
  // For example let's ignore this override if the current user has a specific permission.
  // if (\Drupal::currentUser()->hasPermission('access content')) {
  //   return;
  // }
  // Check the specific content type that we are targeting.
  if (isset($context['entity_type']) && isset($context['bundle'])
    && ($context['entity_type'] == 'node') && ($context['bundle'] == 'CONTENT_TYPE')) {
    $storage = \Drupal::service('entity_type.manager')->getStorage('entity_form_display');
    // $form_display = $storage->load('user.user.VIEW_MODE_MACHINE_NAME');
    // $form_display = $storage->load('node.CONTENT_TYPE.VIEW_MODE_MACHINE_NAME');
    $form_display = $storage->load('node.article.my_custom_view_mode_name');
  }
}

```
> 3 votes

---
Tags: 8, entities
---


# Question
Title: Glossary option in Search API indexed nodes
Does anyone know how to add glossary for search index nodes? In Views+Search API you dont get glossary option in contextual filters as you get in Views with content nodes. Currently I am using grouped filter with each alphabet equal to title (trimmed to one character) but not very efficient way. Looking for a better approach. Thanks.

# Answer
> 1 votes
To my knowledge the Search API does not support making a Glossary listing in a Contextual Filter. The best it can do is provide Facet Searching (after a search is performed).

Solr may support this using Shingles or something to help create the Glossary item, but no such Drupal submodule exists at the moment.

# Answer
> 1 votes
this module can probably help some of you.
https://www.drupal.org/project/search\_api\_glossary
It is working on D7 and D8.

Have a good day.

---
Tags: views, search
---


# Question
Title: Changing a menu link used in the sitemap module but not in main nav
We are using the Sitemap module for creating a sitemap generated from three menus (Footer, Main nav and a 3rd arbitrary one).

In the main nav we have a placeholder LI element which we use to insert a view.

In the sitemap template we need to replace this placeholder with some content without affecting the main nav.

In the sitemap overridden template where `{{ item.content }}` normally appears I tried replacing with the following:

```
{{ item.content|replace('>LRGPH_BRANCHES_BY_SERVICE<', ('>' ~ allBranches ~ '<')) }}

```

Note: `allBranches` is a concatenation of the output of 4 views (Essentially pure HTML)

but Twig/Drupal seems to have issue with this as I get an error, as per below:

> Warning: strtr() expects parameter 1 to be string, array given in twig\_replace\_filter() (line 521 of /var/www/vendor/twig/twig/src/Extension/CoreExtension.php). twig\_replace\_filter(Array, '\>LRGPH\_BRANCHES\_BY\_SERVICE\<', '\>

I next tried using the contributed modules hook, namely `function TEMPLATE_preprocess_sitemap(&$variables)` but although I can see the HTML output of the sitemap I cannot change it using this as far as I can tell.

Is there any way to achieve this change at all without altering the Main navigation?

# Answer
> 0 votes
`{{ something.content }}` is a render array, you can't do a string replace on an array. But you can store the computed string output of the render array, and do a string replace on the rendered output:

```
{# compute the output of the render array and store it #}
{% set rendered_html_string = item.content|render %}

{# do the replacement #}
{% set modified_string = rendered_html_string|replace('seachtext', 'replacetext') %}

{# print the modified string #}
{{ modified_html_string }}

```

---
Tags: 8, theming
---


# Question
Title: Drupal can't create image styles for files located in theme directory
I have an image located in sites/all/themes/mytheme/images directory. I'm displaying it programmatically with attached image style like:

```
  $style =  array(
    'style_name' => 'my_style',
    'path' => drupal_get_path('theme', 'mytheme') . '/images/' . $filename,
    'width' => 30,
    'height' => 30,
    'alt' => $alt,
    'title' => $title,
  );

  return theme('image_style', $style);

```

First error: 404:

> "NetworkError: 404 Not Found - http://j.dev/sites/default/files/styles/my\_style/public/sites/all/themes/mytheme/images/img.png?itok=qsTbAc8I"

Log report:

> Source image at public://sites/all/themes/mytheme/images/img.png not found while trying to generate derivative image at public://styles/my\_style/public/sites/all/themes/mytheme/images/img.png.

I'm sure that img.png exists in sites/all/themes/mytheme/images

File permissions:

* sites/all/themes/mytheme/images: 777
* sites/default/files/styles/my\_style: 777

# Answer
> 2 votes
core module Image Style allow only images from

public:// file system (sites/default/files).

For using image styles with any other images, you should install the Imagecache External module.

> Imagecache External is a utility module that allows you to store external images on your server and apply your own imagecache (D6) / Image Styles (D7).

# Answer
> 0 votes
Your code will not work with the images located inside the theme directory.

From the specific Drupal documentation

**path:** The path of the image file relative to the Drupal files directory. This function does not work with images outside the files directory nor with remotely hosted images. This should be in a format such as images/image.jpg', or using a stream wrapper such as 'public://images/image.jpg'.

Reference

# Answer
> 0 votes
It's actually possible to generate image style with the trick which image module uses to generate image style preview (see theme\_image\_style\_preview()):

```
$original_path = drupal_get_path('theme', 'mytheme') . '/images/' . $filename;
$thumb_file = image_style_path('my_style', $original_path);
if (!file_exists($thumb_file)) {
  $style = image_style_load('my_style');
  image_style_create_derivative($style, $original_path, $thumb_file);
}

$style =  array(
  'style_name' => 'my_style',
  'path' => $original_path,
  'width' => 30,
  'height' => 30,
  'alt' => $alt,
  'title' => $title,
);
return theme('image_style', $style);

```

---
Tags: 7, media
---


# Question
Title: How can I override the empty search message?
What do I have to do to override the message

> Your search yielded no results

from core search module inside `core/modules/search/src/Controller/SearchController.php`?

# Answer
> 5 votes
You can implement `template_preprocess_item_list` (or `hook_preprocess_HOOK` to be precise) in your theme or module to override that.

```
/**
 * Implements template_preprocess_item_list().
 */
function MYTHEME/MYMODULE_preprocess_item_list__search_results(&$variables) {

  $variables['empty']['#markup'] = '<h3>' . t('Foobar') . '</h3>';
}

```

# Answer
> 0 votes
You can replace empty search message by call custom block body by:

* Go to /code/themes/THEMENAME
* open THEMENAME.theme file and add following Hook

As:

```
function THEMENAME_preprocess_item_list__search_results(&$variables) {
  $custom_block = \Drupal::entityTypeManager()->getStorage('block_content')->load('BLOCKNUMBER');
  $fieldcontent = $custom_block->body->value;
  $variables['empty']['#markup'] = $fieldcontent;
}

```

Please change THEMENAME with you theme name and BLOCKNUMBER with your block number.

---
Tags: 8, search
---


# Question
Title: Need help with how custom fields are displayed by article.html.twig file
Noncoder here. After not poking my head under the hood of any CMS in years (not since Drupal 5, I think — and I wasn't very good at it even then), I'm working on a portfolio site. I suspect this question will be an easy one to answer for anyone with even modest coding experience; sadly, I can't claim to have even that.

This site will showcase previously published material, and it has to display the original publication date instead of the date that the content was added to the website. It also should display the name of the original publication.

I've created two fields for my article content type:

* field\_publicationdate
* field\_originalpublication

I would like the content to be displayed like this:

* (Title field)
* "Originally published in " (orginalpublication field) " on " (publicationdate field) \[note: I'd like this to be consistent with the theme's custom date display format of 'F d, Y'\]
* By (author) (time to read)

It currently reads:

* (Title field)
* (date content was added to Drupal) By (content creator) (time to read)

I'm now in the node--article.html.twig file.

Someone who was helping me pointed me to lines 28 and 30 of the attached screencap, assuming I had enough basic knowledge to take it from there. While flattered in by this person's confidence in me, as I mentioned in my first paragraph, I'm an idiot when it comes to this stuff.

Can someone help?

# Answer
> 0 votes
If I understand correctly:

The `node.createdtime` in the screenshot comes from the content type setting "Display author and date information" on the content type edit page. Look at `/admin/structure/types/manage/article`.

If you need a different date shown, you can uncheck that setting to hide Drupal's author and date info display, then ensure your custom fields are displayed on the node instead. Look at `/admin/structure/types/manage/article/display`.

If the template `node--article.html.twig` renders content with just `{{ content }}`, your fields will show once set to display. If your template file is customized, you may need to add `{{ content.field_publicationdate }}`.

As @Kevin mentioned, use the field format options at `/admin/structure/types/manage/article/display` to control the output of your date field.

---

A more technical approach, and if your content is being imported, could be to map your `field_publicationdate` value to the node created time value. (But that's another question :)

---
Tags: theming
---


# Question
Title: Delete a field from the database manually
I installed a module that left a ghost field that isn't tied to any entity bundle :(

How would I go about safely and thoroughly deleting this field from the database?

I have to delete this field to uninstall the module. I have attempted to run cron and clear cache to see if that would remove the field (it does not).

MYSQL command: `show tables like '%<string in field>%';` only produces one result (the field I want to delete). Do I just drop that table?

I am using Drush 9.x, so unfortunately it looks like `drush field-delete` is not available. Is there a way to do this with Drush 9 or Drupal Console?

Thanks in advance for your help!

# Answer
> 5 votes
In Drupal 8 bundle fields are configuration. This looks like you still have the field storage configured.

In this case export configuration:

```
drush cex

```

remove the field storage:

```
rm field.storage.node.field_example.yml

```

and import configuration again:

```
drush cim

```

---
Tags: 8, database, installation
---


# Question
Title: Checking for string in variable fails in twig
I'm working on a twig template for use with a commerce product. Each product has a term applied to it like "Green Ball", "Yellow Ball", "Red Block", and "Purple Block".

I'm trying to take the variable that holds the term, check if it has a string in it, and then use that as the basis for a label. For example if its a Green Ball it would say "Order Ball" and if it was "Red Block" it would say "Order Block".

I'm marking this up based on examples but it always returns false.

```
{% if 'Ball' in product.field_myproduct_type|field_value %} Order Ball {% endif %}
{% if 'Block' in product.field_myproduct_type|field_value %} Order Block {% endif %}

```

I've both tried outputting the variable on its own to confirm the variable is correct and also tried replacing the variable from the conditional with a string to make sure the conditional is the proper syntax and both work as expected. I just can't seem to check in the variable.

I'm doing this from within a twig template that is a variant on commerce-product.twig

# Answer
Via kint and a bunch of trial and error I identified the right way to do this:

```
{% if 'Ball' in product.field_myproduct_type.0['#plain_text'] %} Order Ball {% endif %}
{% if 'Block' in product.field_myproduct_type.0['#plain_text'] %} Order Block {% endif %}

```

Thank you 100pic for your assistance.
> 1 votes

---
Tags: theming, commerce, taxonomy-terms
---


title: Wrap a link around a block in Twig

text:
# Question
Title: Wrap a link around a block in Twig
I have a block and I’m trying to wrap a link around it:

```
{% block paragraph %}
  <div{{ attributes.addClass(classes) }}>
    {% block content %}
        <a href="{{ content.field_link.0['#url'] }}">
          {{ content }}
        </a>
    {% endblock %}
  </div>
{% endblock paragraph %}

```

But when the code is output, the link is above the block instead of around it, and it gets input into multiple other places inside the content. You can see everywhere there’s a /node/2, but nowhere is it doing anything useful (except for wrapping around the “Office” image, which comes from the {{ content }} and not from the wrapped link).

```
<div data-quickedit-entity-id="paragraph/5594" class="paragraph paragraph--transporter-item paragraph--view-mode-default" data-quickedit-entity-instance-id="0">
  <a href="/node/2">
    <!-- THEME HOOK: 'field' -->
    <!-- BEGIN OUTPUT from 'modules/contrib/fences/field.html.twig' -->
  </a>

  <div class="paragraph--transporter-item__icon field field--name-field-icon field--type-entity-reference field--label-hidden field__items" data-quickedit-field-id="paragraph/5594/field_icon/en/default">
    <a href="/node/2">
      <!-- THEME HOOK: 'media' -->
      <!-- BEGIN OUTPUT from 'core/modules/media/templates/media.html.twig' -->
    </a>

    <div data-quickedit-entity-id="media/9" class="contextual-region" data-quickedit-entity-instance-id="0">
      <a href="/node/2">
        <div data-contextual-id="media:media=9:changed=1561152189&langcode=en" data-contextual-token="8VIDU3VuOojWGK9hX_jn8ERolu-tvAZdOewrYfTFUwA" class="contextual" role="form">
          <button class="trigger visually-hidden focusable" type="button" aria-pressed="false">Open  configuration options</button>
          <!-- THEME HOOK: 'links__contextual' -->
          <!-- BEGIN OUTPUT from 'core/modules/system/templates/links.html.twig' -->
          <ul class="contextual-links" hidden=""><li class="quickedit"><a href="" role="button" aria-pressed="false">Quick edit</a></li><li><a href="/media/9/edit?destination=/node/2">Edit</a></li><li><a href="/media/9/delete?destination=/node/2">Delete</a></li></ul>
          <!-- END OUTPUT from 'core/modules/system/templates/links.html.twig' -->
        </div>

        <!-- THEME HOOK: 'field' -->
        <!-- BEGIN OUTPUT from 'modules/contrib/fences/field.html.twig' -->
      </a>
      <div data-quickedit-field-id="media/9/field_media_image/en/default" class="field field--name-field-media-image field--type-image field--label-visually_hidden field__items quickedit-field">
        <a href="/node/2">
          <div class="field__label visually-hidden">Image</div>
        </a>
        <div class="field__item">
          <a href="/node/2">
            <!-- THEME HOOK: 'image_formatter' -->
            <!-- BEGIN OUTPUT from 'core/modules/image/templates/image-formatter.html.twig' -->
          </a>
          <a href="http://arboreal.lndo.site/sites/default/files/2019-06/0010-office.svg">
            <!-- THEME HOOK: 'image' -->
            <!-- BEGIN OUTPUT from 'core/modules/system/templates/image.html.twig' -->
            <img src="/sites/default/files/2019-06/0010-office.svg" alt="Office" typeof="foaf:Image" width="" height="">
            <!-- END OUTPUT from 'core/modules/system/templates/image.html.twig' -->
          </a>
          <!-- END OUTPUT from 'core/modules/image/templates/image-formatter.html.twig' -->
        </div>
      </div>
      <!-- END OUTPUT from 'modules/contrib/fences/field.html.twig' -->
    </div>
    <!-- END OUTPUT from 'core/modules/media/templates/media.html.twig' -->
  </div>
  <!-- END OUTPUT from 'modules/contrib/fences/field.html.twig' -->

  <!-- THEME HOOK: 'field' -->
  <!-- BEGIN OUTPUT from 'modules/contrib/fences/field.html.twig' -->
  <div class=".paragraph--transporter-item__label field field--name-field-link field--type-link field--label-hidden field__items" data-quickedit-field-id="paragraph/5594/field_link/en/default">
    <a href="/node/2">Office</a>
  </div>
  <!-- END OUTPUT from 'modules/contrib/fences/field.html.twig' -->
</div>

```

Why is this happening, and how do I get it so it just outputs the link in the one place and around the whole block?

# Answer
> -1 votes
This is not the answer you are looking for...

I would recommend not wrapping your block in a link. This is bad SEO and difficult for screen readers and other assistive technologies to decipher.

Instead, place the link at the end of your block and use CSS to absolute position it to cover your entire block.

Markup:

```
<div class="my-block>
  <h2>Title</h2>
  <p>Some content</p>
  <a class="my-block-link" title="My helpful title for screen readers"></a>
</div>

```

Styles:

```
.my-block {
  position: relative;

  a.my-block-link {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
  }
}

```

It is important to achieve accessibility as much as possible.

# Answer
> 4 votes
I would recommend a 2 step approach to this.

1. Add a link at the bottom of your block that links to the node like so:

```
<a class="my-block-link" href="node/1" title="My helpful title for screen readers">Full node</a>

```
2. Use a jQuery snippet to link the whole block

```
$(document).on('click', '.contextual-region', function(e) {
  console.log('block clicked');
  window.location = $(this).find('.my-block-link').attr('href');
});

```
3. UX Bonus points - Add this css for your linked block:

```
.contextual-region { cursor: pointer; }

```

EDIT:

I'll add a non JS way to make everyone happy:

```
{% block paragraph %}
  <div{{ attributes.addClass(classes) }}>
    {% block content %}
        <a href="{{ content.field_link.0['#url'] }}">
          <div class="content-container-needed">
          {{ content }}
          </div>
        </a>
    {% endblock %}
  </div>
{% endblock paragraph %}

```

---
Tags: 8, theming
---


# Question
Title: Simple OAuth + JSONapi response when token is expired - Decoupled
We're using the 'Simple OAuth' and 'jsonapi' modules for the front end authentication in Angular of our decoupled Drupal project.

We've noticed that when the user credentials are correct but the token is expired the header response is still 200 'ok' with a message that indicates that the Token no longer valid.

But we need a 400/401 or 403, like it is described in the oath documentations.

Is there a reason why this is implemented like this? Or is there a way to alter the response?

# Answer
> 1 votes
> Is there a reason why this is implemented like this?

`200 ok` is expected status code for collection resources, even if one, many, or all entities were excluded from the collection resource for access reasons.

From https://www.drupal.org/project/jsonapi/issues/2853066:

> The status code for a "collection resource" should be entirely distinct from any or all of the entities represented at that resource.
>
> **Unless there is an access control mechanism that is explicitly a prerequisite for accessing any list of entities of a given type that we can leverage, then it must be assumed that any consumer must have access to any collection resource.**
>
> It is completely consistent with REST to return a 200 response to an empty collection, even when all those entities have been elided for access reasons.

---

> Or is there a way to alter the response?

Of course, you can. Check the documentation about altering routes and providing custom access tagged service:

---

Finally, the link you provided in the question is to oauth specs, and is irrelevant to jsonapi. Oauth resource in Drupal (`/oauth/token`) will correctly give you 4xx in case of any errors when obtaining a new token.

# Answer
> 0 votes
## Edit

I found a method that works for me.

```
<?php

namespace Drupal\modulename\Routing;

use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;

/**
 * Listens to the dynamic route events.
 * https://www.drupal.org/docs/8/api/routing-system/altering-existing-routes-and-adding-new-routes-based-on-dynamic-ones
 */
class ModuleNameRouteSubscriber extends RouteSubscriberBase {

  /**
   * {@inheritdoc}
   */
  protected function alterRoutes(RouteCollection $collection) {
    //issue is this only works for JUST /rahapi and not anything else
    //if ( $route = $collection->get('jsonapi.resource_list') ) {
    //  $route->setRequirement('_user_is_logged_in', 'TRUE');
    //}

    foreach ($collection->all() as $route) {
      if (strpos($route->getPath(), '/jsonapi') === 0 ) {
        $route->setRequirement('_user_is_logged_in', 'TRUE');
      }
    }
  }
}

```

That goes in modulename/src/Routing/ModuleNameRouteSubscriber.php

Then this goes in modulename/modulename.services.yml

```
services:
  route_subscriber:
    class: Drupal\modulename\Routing\ModuleNameRouteSubscriber
    arguments: []
    tags:
      - { name: event_subscriber }

```

So I found it by going here: https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Routing%21RouteSubscriberBase.php/class/RouteSubscriberBase/8.2.x

So I'm extending that... and I see there are many other things that extend it. Like this one for /admin. So I did monkey-see-monkey-do and generated the code above. I hope my sample code works for you.

https://api.drupal.org/api/drupal/core%21modules%21system%21src%21EventSubscriber%21AdminRouteSubscriber.php/function/AdminRouteSubscriber%3A%3AalterRoutes/8.2.x

Thank you zaporylie for pointing me in the initial direction.

# Answer
> 0 votes
Before this implimentation you can call one more api which debugs the token. Just provide token in header and in the results we will get token expiration details.

```
api :- http://your_url/oauth/debug?_format=json

```

---
Tags: 8, authentication-authorization
---


title: Add paragraphs to a node via jsonapi

text:
# Question
Title: Add paragraphs to a node via jsonapi
Added a paragraph to drupal8 via jsonapi and want this paragraph to be in an articles body. I thought it is as easy as

```
    "relationships": {
        "field_body": {
            "data": [
                {
                    "type": "paragraph--text",
                    "id": "b0247bf8-a3c0-4a45-8e05-4f4901011000"
                }
            ]
        }
    }
},

```

but the article is created and the field\_body result is empty. It works already with other entities just fine. And the jsonapi gives me the paragraph /jsonapi/paragraph/text ...What is the problem, am I missing something?

# Answer
> -1 votes
Did you gave node type ? Try the following body data.

```
{
 "data":
  {
     "attributes": {
            "title": "title of your new node",

        },
         "relationships": {
            "field_body": {
                "data": {
                    "type": "paragraph--text",
                    "id": "b0247bf8-a3c0-4a45-8e05-4f4901011000"
                }
            }
        },
      "type": "node--yournode"
    }
  }

```

---
Tags: 8
---


# Question
Title: How do I retrieve multiple values in a CONTAINS condition?
I'm using the JSON:API module (in core since Drupal 8.7), which works well for a *Retrieve all articles with title that contains "MyKeyValue" or subtitle that contains "MyKeyValue"* which, translated in JSON:API query becomes:

```
fields[node--article]=title,field_subtitle
filter[or-group][group][conjunction]=OR
filter[status][value]=1
filter[title-filter][condition][path]=title
filter[title-filter][condition][operator]=CONTAINS
filter[title-filter][condition][value]=MyKeyValue
filter[title-filter][condition][memberOf]=or-group
filter[subtitle-filter][condition][path]=field_subtitle
filter[subtitle-filter][condition][operator]=CONTAINS
filter[subtitle-filter][condition][value]=MyKeyValue
filter[subtitle-filter][condition][memberOf]=or-group

```

How do I manage multi-values within the `CONTAINS` condition, for a query like the following one?

> Retrieve all articles with title that contains ("MyKeyValue" AND "AnotherKeyValue") or subtitle that contains ("MyKeyValue" AND "AnotherKeyValue")

I tried to pass multiple values in this way, but it doesn't work.

```
filter[title-filter][condition][operator]=CONTAINS
filter[title-filter][condition][value][]=MyKeyValue
filter[title-filter][condition][value][]=AnotherKeyValue

```

# Answer
> 0 votes
Just change field name and values if you want change the custom name also here its profile status filter.

```
filter[profileStatusFilter][condition]
[path]=first_field&filter[profileStatusFilter2][condition]
[path]=second_field&filter[profileStatusFilter][condition]
[operator]=CONTAINS&filter[profileStatusFilter2][condition]
[operator]=CONTAINS&filter[profileStatusFilter][condition]
[value]=first_value&filter[profileStatusFilter2][condition]
[value]=second_value&filter[profileStatusFilter][condition][memberOf]=billing-
group&filter[profileStatusFilter2][condition][memberOf]=billing-group

```

---
Tags: 8
---


# Question
Title: Focus problem when Ajax call for multiple fields calling the same callback function
I have implemented a custom form. I put same Ajax callback function for multiple field. When one Ajax call completes, I click on other field. But I can't unfocused previous field. Sometimes the Ajax call runs for multiple field.

My code:

```
$form['worklocation'] = array(
    '#title' => t('Work Location'),
    '#type' => 'textfield',

   '#autocomplete_route_name' => 'advance_search_autocomplete_callback.advancesearch_autocomplete_callback',
    '#autocomplete_route_parameters' => array('type' => 'worklocation'),
    '#ajax' => array(
      'callback' => [$this, 'friends_advance_search_results'],
    ),
    '#attributes' => array('class' => array('form-control')),

  );

  $form['school'] = array(
    '#title' => t('School'),
    '#type' => 'textfield',

    '#autocomplete_route_name' => 'advance_search_autocomplete_callback.advancesearch_autocomplete_callback',
    '#autocomplete_route_parameters' => array('type' => 'school'),
    '#ajax' => array(
      'callback' => [$this, 'friends_advance_search_results'],
    ),
    '#attributes' => array('class' => array('form-control')),

  );
  $form['college'] = array(
    '#title' => t('College / University'),
    '#type' => 'textfield',

   '#autocomplete_route_name' => 'advance_search_autocomplete_callback.advancesearch_autocomplete_callback',
    '#autocomplete_route_parameters' => array('type' => 'college'),
    '#ajax' => array(
      'callback' => [$this, 'friends_advance_search_results'],
    ),
    '#attributes' => array('class' => array('form-control')),

  );

```

Callbakck:

```
function friends_advance_search_results(array &$form, FormStateInterface $form_state) {

 $search_result = array(
                    '#theme' => 'friends_advanced_search_list',
                    '#friends' => $friends_list,
                    '#info' => array('display' => 'hide', 'friend_recommend' => 0, 'load_more' => $load_more, 'no_results' => 1,'search_action' => 1),

                    );

   $output = render($search_result);
   $id = '#advanced-friend-list';
   $response = new AjaxResponse();
   $response->addCommand(new ReplaceCommand($id, $output));

   return $response;

}

```

Problem:

# Answer
Enable `disable-refocus` when adding the ajax callback:

```
'#ajax' => [
  'callback' => [$this, 'friends_advance_search_results'],
  'disable-refocus' => TRUE,
],

```

See https://www.drupal.org/project/drupal/issues/2627788
> 3 votes

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


# Question
Title: How do I import entity related fields using drush migration?
I am trying to do data migration from a Drupal 7 site to a Drupal 8 site using **drush migration**. **Example:** I am trying to import users which has 5-7 fields and I tried to import fields using:

* d7\_field
* d7\_field\_instance

These 2 are importing all fields in Drupal 7 (users, taxonomy, node). How can I restrict this to import only specific entity fields?

# Answer
You can achieve this via a custom migration module, this way you have full control over what will be migrated, note the bold text:

> * Create the migrations using drush migrate-upgrade --configure-only as discussed in Upgrade Using Drush
> * Make sure you have aconfig/syncdirectory, to which the next step will write
> * Export the migrations using drush config:export
> * Create your custom migration module
> * **Copy only the YML files you want** to use from the config/sync directory into the config/install directory of your new custom module, editing them to remove the uuid values and to edit the id, group, label, and other values as needed
> * In the config/install directory of your new custom module, make a new migrate\_plus.migration\_group.your\_module.yml file for your new migration group.

from official handbook: https://www.drupal.org/docs/8/upgrade/customize-migrations-when-upgrading-to-drupal-8

You can also rename the fields. Further processing can happen in `hook_migrate_prepare_row()`, `hook_migration_plugins_alter()`, or even a custom process plugin.

### update

Please note that you will *not* be exporting configuration from a site and moving it to other site. Config export is a bad name here. Read it as *generate migration template*.

When you generated your template (aka, exported), you handpick those fields, entities and configuration that you want from all the available generated files, put them in a custom module, say `my_custom_mig`, enable it, and run it's migration.
> 3 votes

---
Tags: 8, users, migrations
---


# Question
Title: I removed the module from my site and now I'm getting an entity type error
I have an issue where I removed the paragraphs and bootstrap\_paragraphs modules from my site and now I am unable to access the admin or the site. It is saying that the paragraphs entity type doesn't exist is the entity types manager. Is there a way using drush that I can add this entity type or just remove all references to it to get the site back up?

# Answer
> 0 votes
I was able to restore the site using drush and re-installing the modules. I did a drush cache-rebuild then reinstalled the modules via drush dl and drush en and it restored the site.

---
Tags: 8, paragraphs
---


# Question
Title: Is it possible to generate an URL object from a path?
Can I generate a

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Url.php/class/Url/8.2.x

from a simple path, e.g. "/products/widget" ?

(assume /products/widget exists in the system and is a canonical path)

# Answer
Use Url:fromRoute () and pass in the route's name and arguments. You can also use fromUri() for external paths. https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Url.php/function/Url%3A%3AfromRoute/8.2.x

I usually find the route name by searching the routing.yml files for the path.

Alternately, you can do this. How to get the Route object from an URI?
> 1 votes

---
Tags: 8
---


# Question
Title: How do I disable the taxonomy term page?
I would like to disable the taxonomy/term/1 page that list the nodes using that taxonomy term. I have found some modules for older Drupal versions, but I haven't found quite what I'm looking for in Drupal 8.

Is there a configuration setting I am missing? Can I use a hook to disable the taxonomy term page, or does this require a module?

# Answer
The Rabbit Hole module can help you in this task

> Rabbit Hole is a module that adds the ability to control what should happen when an entity is being viewed at its own page.

You need to enable the Rabbit Hole and Rabbit Hole taxonomy submodule and then in the admin/structure/taxonomy/manage/YOUR\_VOCABULARY page you will see the Rabbit Hole Options.
> 2 votes

# Answer
A lightweight solution is to simply edit the taxonomy term view : /admin/structure/views/view/taxonomy\_term

... and restrict the access.
> 23 votes

# Answer
1. Add a *Content revision: ID* filter. Set the operator to *Is equal to*, and input `-1`
2. Click *Add* in the *No results behavior* options box and add *Response status code*
3. Select *404 (Not Found)* as the status code to return and add it
4. Save the view

Step 1 adds a filter that will always fail, because revision ids are positive integers, thus never equal `-1`. This will make the query always return with no results.

Steps 2 and 3 make Drupal return a proper 404 HTTP code when no results are returned from the query.
> 0 votes

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


title: IP blocking doesn't prevent requests

text:
# Question
Title: IP blocking doesn't prevent requests
I am getting a lot of bad requests from a crawler at a specific IP Address non-stop. I added the IP to the blocked list and cleared the cache, but I still see more requests in the dblog coming in from the IP:

```
HTTP response: Bad Request. URL: https://valid.url.example.com/api/123456>; rel="canonical",<https:.json.

```

Why can they still send requests? Is there a way to prevent these?

# Answer
Flood control is just for failed login attempts and some other stuff like forms being filled out. It will not keep your bad bot from the site.

Assuming you have an Apache server, you can modify the .htaccess file in the root of your site to block specific ip with the `DENY FROM {ip}` directive. E.g. adding something like this to the top.

```
order allow,deny
deny from 255.0.0.0
deny from 123.45.6.
allow from all

```

If you don't have Apache / .htaccess support, the process will be different.
> 2 votes

---
Tags: 7
---


# Question
Title: Errors when attempting to load Salesforce object from mapping admin page
We are attempting to push a content type from our Drupal site to a Salesforce object. We have successfully authorized the link between them. When we attempt to start the mapping, we get an AJAX error. I believe the AJAX error is just a symptom of the real error that occurs within the Salesforce module so I am not providing much about it.

In the logs after the error has been triggered, the drupal log shows 2 errors:

Notice: Undefined offset: 8 in salesforce\_mapping\_form\_validate() (line 590 of /.../sites/all/modules/contrib/salesforce/modules/salesforce\_mapping/includes/salesforce\_mapping.admin.inc).

and

Warning: Invalid argument supplied for foreach() in form\_type\_checkboxes\_value() (line 2394 of /home/tim/projects/lca/includes/form.inc).

I have attempted to use xdebug to watch this process as it works its way through the salesforce\_mapping.admin.inc processes, but nothing has jumped out at me. In the end, phpStorm runs out of memory and stops processing the request. The next page load of drupal crashes the browser window as well leading me to believe there is some sort of recursive error happening.

I have searched this modules issue queue and the interwebs extensively, but nothing fits our situation. Please let me know if I can provide further information for you or can otherwise assist.

# Answer
I found the issue. For anyone in the future running into this error, I found that you must have both the push and pull submodules enabled for the mapping to work. I was only planning to push records into Salesforce so I mistakenly assumed I didn't need the pull modules enabled. With it enabled, the mapping worked like a champ.
> 0 votes

---
Tags: 7
---


# Question
Title: How to load paragraph entity on node object?
I'm using paragraphs in my content type. I've created a paragraph type and added content. Now I want to load the paragraphs in a `foreach`. But nothing's showing up. `$paras` is empty:

```
$node  = \Drupal\node\Entity\Node::load(1);
$paras = $node->get('field_paragraph')->referencedEntities();

```

# Answer
> 30 votes
```
$paragraph = $node->field_paragraph->getValue();
// Loop through the result set.
foreach ( $paragraph as $element ) {
  $p = \Drupal\paragraphs\Entity\Paragraph::load( $element['target_id'] );
  $text = $p->field_name->getValue();
}

```

# Answer
> 20 votes
Just replace `get()` with field name directly :

```
$node  = \Drupal\node\Entity\Node::load(1);
$paras = $node->field_paragraph->referencedEntities();

```

# Answer
> 4 votes
This method will work a bit faster.

```
// Get data from field.
if ($paragraph_field_items = $node->get('field_paragraph')->getValue()) {
  // Get storage. It very useful for loading a small number of objects.
  $paragraph_storage = \Drupal::entityTypeManager()->getStorage('paragraph');
  // Collect paragraph field's ids.
  $ids = array_column($paragraph_field_items, 'target_id');
  // Load all paragraph objects.
  $paragraphs_objects = $paragraph_storage->loadMultiple($ids);
  /** @var \Drupal\paragraphs\Entity\Paragraph $paragraph */
  foreach ($paragraphs_objects as $paragraph) {
    // Get field from the paragraph.
    $text = $paragraph->get('field_title')->value;
    // Do something with $text...
  }
}

```

You can also easily implement this code in some method in your custom service with `@entity_type.manager` argument and load storage for nodes and paragraphs in `__construct()`.

---
Tags: 8, paragraphs
---


title: Drush command for setting up databases

text:
# Question
Title: Drush command for setting up databases
I just installed Drush 9 on my ubuntu 19 machine. I also downloaded the latest Drupal 7 and 8 to my /var/www/html folder. My mysql is verified working. Is there a quick drush command to help me setup my databases without me having to manually create them for each drupal instance? I have access to my root user if needed.

# Answer
You can find the docs here: https://drushcommands.com/drush-9x/sql/sql:create/

> drush sql:create --db-su=root --db-su-pw=rootpassword --db-url="mysql://drupal\_db\_user:drupal\_db\_password@127.0.0.1/drupal\_db"

It works on drush v8 as drush v9 doesn't support Drupal 7.
> 0 votes

---
Tags: drush
---


# Question
Title: Store entity with entity reference field programmatically?
I want to create an ECK by hard coding, The ECK being created, but the entity references that I assigning to the main entity cause the problem.

I have two entity references

* field\_student\_account that I assign the Student Account by id 10
* field\_students that I assign the Students by id 48,
* field\_enrollment that I assign the Enrollment by id 270,

> Error: Call to a member function label() on null in Drupal\eck\Controller\EckEntityListBuilder-\>buildRow() (line 43 of modules\contrib\eck\src\Controller\EckEntityListBuilder.php).

I tried these codes:

```
  // Define entity type and bundle.
  $entity_type = "attendees";
  $bundle = "attendees";

  // Get definition of target entity type.
  $entity_definition = \Drupal::service('entity.manager')->getDefinition($entity_type);
  // Load up an array for creation.

  $entity_data = [
    'title' => 'this is test new',
    'field_student_account' => 10,
    'field_students' => 48,
    'field_enrollment' => 270,
    'field_status' => 'Active',
    $entity_definition->getKeys()['bundle'] => $bundle,
  ];
  $new_entity = \Drupal::service('entity.manager')->getStorage($entity_type)->create($entity_data);
  $new_entity->save();

```

here are the values for created entity from the front end.

```
#values: array:12 [▼
    "id" => array:1 [▼
      "x-default" => "15"
    ]
    "type" => array:1 [▼
      "x-default" => "attendance"
    ]
    "uuid" => array:1 [▼
      "x-default" => "9a1fd3ec-3d7d-4926-a1d2-fcafc8fce3c2"
    ]
    "langcode" => array:1 [▼
      "x-default" => "en"
    ]
    "title" => array:1 [▼
      "x-default" => "group lesson"
    ]
    "created" => array:1 [▼
      "x-default" => "1561802666"
    ]
    "changed" => array:1 [▼
      "x-default" => "1561802705"
    ]
    "default_langcode" => array:1 [▼
      "x-default" => "1"
    ]
    "field_enrollment" => array:1 [▼
      "x-default" => array:1 [▼
        0 => array:1 [▼
          "target_id" => "271"
        ]
      ]
    ]
    "field_status" => array:1 [▼
      "x-default" => array:1 [▼
        0 => array:1 [▼
          "value" => "Inactive"
        ]
      ]
    ]
    "field_students" => array:1 [▼
      "x-default" => array:1 [▼
        0 => array:1 [▼
          "target_id" => "69"
        ]
      ]
    ]
    "field_student_account" => array:1 [▼
      "x-default" => array:1 [▼
        0 => array:1 [▼
          "target_id" => "27"
        ]
      ]
    ]
  ]

```

And this is the data that stored when I try it pro-grammatically

```
EckEntity {#1106 ▼
  #values: array:8 [▼
    "id" => array:1 [▼
      "x-default" => "16"
    ]
    "type" => array:1 [▼
      "x-default" => "attendees"
    ]
    "uuid" => array:1 [▼
      "x-default" => "1048d24d-ffc7-4243-81c1-b26b5e9e9ecb"
    ]
    "langcode" => array:1 [▼
      "x-default" => "en"
    ]
    "title" => array:1 [▼
      "x-default" => "this is test new"
    ]
    "created" => array:1 [▼
      "x-default" => "1561806843"
    ]
    "changed" => array:1 [▼
      "x-default" => "1561806843"
    ]
    "default_langcode" => array:1 [▼
      "x-default" => "1"
    ]
  ]

```

# Answer
You should try this for entity reference fields:
Single value:

```
$entity_data = [
'field_student_account' => ['target_id' => 10],
];

```

Multiple values:

```
$entity_data = [
'field_student_account' => [
    ['target_id' => 10],
    ['target_id' => 11],
  ],
];

```

Hope that works :)
> 1 votes

---
Tags: 8, entities
---


title: Node field not sanitize on render

text:
# Question
Title: Node field not sanitize on render
I have a form for users who want to add new content on my Drupal 8 website. I render node field on a twig template :

`{{ node_field_title.value }}`

But field are not sanitized by Drupal. Is it the normal behaviour ?

--\> If the title is `<script>alert('XSS problem!')</script>` the script will be executed.

Drupal 8 documentation says : 'The Twig theme engine now auto escapes everything by default. That means that every string printed from a Twig template (e.g. anything between {{ }}) gets automatically sanitized if no filters are used.'

# Answer
> 0 votes
It seems that there is no autoescaping, at least for Drupal 8.7.3 which the version I tested.
For example:

```
{{ "<div>Is this escaped?</div>" }}
{{ "<script>alert('NOO!');</script> "}}

```

These lines are not escaped by default. However:

```
{{ "<div>Is this escaped?</div>"|escape }}
{{ "<script>alert('NOO!');</script>"|escape}}

```

These are escaped, so better be safe than sorry and use `|escape` for the input you're getting from your users.

---
Tags: theming, nodes, security
---


title: problem with $conf['i18n_variables']

text:
# Question
Title: problem with $conf['i18n_variables']
i have installed i18n module and added this lines to setting.php and empty cache to translate slogan and contact form information and ... but it doesnt affect site and values dont add to i18n\_variable table.

```
$conf['i18n_variables'] = array(
        'site_name',
        'site_slogan',
        'site_mission',
        'site_footer',
        'anonymous',
        'user_registration_help',
        'user_mail_welcome_subject',
        'user_mail_welcome_body',
        'user_mail_approval_subject',
        'user_mail_approval_body',
        'user_mail_pass_subject',
        'user_mail_pass_body',
        'contact_form_information'
    );

```

do you have any suggestion to solve this problem?

# Answer
> 1 votes
You need to actually go to the page in the admin that updates the variable and edit it from the non-default language url.

For example, with site name, if you have one other language with 'es' as a path prefix you would go to 'http://example.com/es/admin/settings/site-information' and change the site name. Once you do that in another language it will create the variable in the i18n\_variable table.

You will know you are on the right track when the element you want to update in the admin says "This is a multilingual variable"

# Answer
> 0 votes
If you are using `drush` you can check what is the actual value of `i18n_variables`.

```
drush variable-get i18n_variables

```

If the list is different from what you put into `settings.php`, it means that there is another statement in `settings.php` or one of the modules that is overriding the variable.

One common cause is having `Internationalization tests` module enabled. This module overrides `i18n_variables` with

```
$conf['i18n_variables'] = array_merge(array('site_name', 'site_frontpage'),
              variable_get('i18n_variables_test', array()));

```

Unless `i18n_variables_test` is also set, you would only get `site_name` and `site_frontpage`.

If this is the case for you disable `Internationalization tests` module in the `Testing` section of *Administer -\> Site Building -\> Modules*.

---
Tags: i18n-l10n
---


title: Fetch and update with foreach loop

text:
# Question
Title: Fetch and update with foreach loop
I need to update the database. the code I am using was working, but after I have done some Drupal updates, it doesn't work anymore. I'm fetching data from table all is working but when I add code db\_update, then it doesn't work, and also I cannot fetch all data, only which is not in db\_update conditions is shown. Could someone help me with the code to fetch all data, then update it with conditions to another table?

```
$queryHomeTeams = db_select('krikis_home_page_today_results','k');
$queryHomeTeams->fields('k');
$results = $queryHomeTeams->execute()->fetchAll();

foreach ($results as $resu) {
  $home_t_id = $resu->h_id;
  $home_scr = $resu->home_score;
  $away_t_id = $resu->v_id;
  $away_scr = $resu->away_score;
  $gamestrt = $resu->gamestart;

 // Insert today match results.
 db_update('football_games')
   ->fields(array('h_score' => $home_scr,'v_score' => $away_scr,))
   ->condition('h_id', $home_t_id)
   ->condition('v_id', $away_t_id)
   ->condition('gamestart', $gamestrt)
   ->execute();
}

```

# Answer
In the db\_select you still need to fetch the results after execute() with something like -\>fetchAssoc() or -\>fetchAll().

See the examples in the comments of the documentation: https://api.drupal.org/api/drupal/includes!database!database.inc/function/db\_select/7.x
> -1 votes

---
Tags: 7, database
---


# Question
Title: Add a conditional CSS class to the label of the view exposed form
I try to add a CSS class `sr-only` to the label of my Views exposed form.

In `form-element-label.html.twig` I added:

```
{% if title is not empty or required -%}
  <label{{ attributes.addClass(classes) }}>{{ title }}</label>
  {% elseif title['#markup'] == "Search" %}
    <label{{ attributes.addClass('sr-only') }}>{{ title }}</label>
{%- endif %}

```

When I debug `{{ kint(title) }}` I get:

What I'm doing wrong?

# Answer
I don't think you need to check for "required" here, just check if the field is not empty, right?

You are first checking if a field is not empty so in the elseif the title will always be empty. You should have two ifs I for your logic to work I believe.

If not empty, do this: if it has this particular value do this otherwise do that.
> 0 votes

---
Tags: views, 8
---


# Question
Title: Roster Views with User data plus office content type
I'm creating a site that is an intranet portal for a company. All the users will be employees that work in different offices. I am adding several fields to the users to be used within the roster display. ie Cell phone, personal email, etc.

I will also have a content type of Office that will have fields relating to the individual locations. ie Address, phone, wifi code, etc.

I need to be able to display the full roster for any given office location. Views seem to be the way to go but getting the relationship between users and the offices is my problem. I know this is a pretty basic application but not something that I haven't done before.

What are possible ways to tie the office content type with the system users so that I can create a view that would have access to all of the fields from both content types?

# Answer
This is usually configured through an Entity Reference field. Either create one on People's accounts that references Content of the "Office" type, or create one on the Office Content type referencing Users.

In most cases it will make sense to create the reference on the People accounts. I guess it mostly depends on *when* the information is being added, to make it most user-friendly. It's more likely People will change their jobs than it is likely that Office information will change, so it's quickest to keep the that data with the person. The ER field will display on user profiles which Office the person belongs to (you can Manage display to turn it off).

Using Views you can create lists that display information in both directions, but you'll probably want the backwards direction of showing all the people referencing a particular office (list ER children that reference a particular parent).

You can do this by creating User type Views, adding a Contextual filter for the ER field and setting it to Provide the default value from the Content URL. There are many questions and answers about this with details about every step.

The ER field solution doesn't change access configuration. If you need to restrict what people belonging to different Offices are allowed to see then using Groups, as suggested in another answer, might help.
> 0 votes

# Answer
Sounds like a perfect usecase for the Group module, whereas you'd use a group type like *Offices*. And so that you create 1 group (of group type *Offices*). From then on you have the Group permission system to configure access rules to fit your needs.

And BTW, this can be for either D7 or D8.
> 0 votes

---
Tags: views
---


# Question
Title: Running a queue worker without using cron tasks
I implemented `hook_queue_info()` with the following code.

```
function ecc_general_queue_info() {
  $queues = array();
  $queues['adding_checklist'] = array(
    'worker callback' => '_ecc_general_apply_queue',
    'time' => 60,
  );
  return $queues;
}

```

I create items for the queue with the following code.

```
$queue_factory = \Drupal::service('queue');
$queue = $queue_factory->get('adding_checklist');
$queue->createItem([$node, 'insert']);

```

The callback function is the following.

```
function _ecc_general_apply_queue($item) {
  // Some code here.
}

```

I want to run this callback for each item in the queue. How can I process the queue to execute its worker callback for each item?

I don't want to use cron tasks for processing the queue.

# Answer
> 7 votes
Drupal 8 doesn't use `hook_queue_info()` but annotates the queue class using the `@QueueWorker` annotation, as in the following code taken from a Drupal core module.

```
/**
 * Updates a feed's items.
 *
 * @QueueWorker(
 *   id = "aggregator_feeds",
 *   title = @Translation("Aggregator refresh"),
 *   cron = {"time" = 60}
 * )
 */
class AggregatorRefresh extends QueueWorkerBase {

  /**
   * {@inheritdoc}
   */
  public function processItem($data) {
    if ($data instanceof FeedInterface) {
      $data
        ->refreshItems();
    }
  }

}

```

That, anyway, is **not an annotation for a generic queue**, but for **a queue handled by the `Cron` class** (which is the class implementing the *cron* service).

If you don't need to handle your queue during cron tasks, you simply don't use the `@QueueWorker` annotation.

The code to consume queue items is similar to the following one. (The code is specific for your case.)

```
$queue = \Drupal::service('queue')->get('adding_checklist');
while ($item = $queue->claimItem()) {
  $node = $item->data[0];
  // ...
  $queue->deleteItem($item);
}

```

# Answer
> 9 votes
Queue is processed by cron through core. You can also use Drush and Drupal Console to run queue items as well.

Drush:

`drush queue:list` to get the available queues.

`drush queue:run` to run a single item.

`drush queue:delete` to clear a queue.

Drupal Console:

`drupal debug:queue` to debug your queue.

`drupal queue:run <name-of-the-queue>` To run a single item.

---
Tags: 8, queue
---


# Question
Title: Body Summary field showing literal ampersand character code in view
I have a Drupal 8 site where we've created a view, and decided to use the summary field instead of the trimmed body field, so that we could have more control over it.

However, I got a bug report that the page had funny characters. When I looked, I found that a literal ampersand character, `&`, was changed to the HTML code `&`.

Thinking this was some weirdness introduced by our settings and configuration, I built a view on a clean install of Drupal 8.7.3 and generated some nodes with `devel_generate`. Sure enough, the ampersand HTML code appeared.

Node:

View Page preview:

View Page:

So, I want to get this to display a regular ampersand, as the user entered it.

I found this question explaining how to modify a twig template to use the raw value, but I'm not sure that's what I want to use. I don't want raw values for the whole field-- users could enter HTML in the summary field; I just want a non-encoded ampersand.

How do I get unencoded ampersands in the summary field in a view?

**Edit** leymannx recommended to uncheck `Display any HTML as plain text` on the text formats filter. However, both on my test fresh install and my real site, that filter is not checked, for any format.

I did my fresh install from downloading the Drupal core, and I think leymannx user composer, so I am going to try that, to see if I get the same behavior as he does. Also, I'm not going to install the devel modules to generate content, I'm just going to do one by hand.

These are screenshots from my fresh install:

Also a screenshot from my actual environment:

So, from those settings, it doesn't seem like the filter is what's causing this behavior.

**Edit 2** I found something that I now suspect as perhaps the source of the error. The view on the fresh install is a view of files. I did not find the summary field in the list of fields, so I added a body field and re-wrote it with `{{ body__summary }}`. This is the config export yaml of the view I created.

# Answer
> 2 votes
This is to confirm and clarify the issue according to my findings.
1. I was able to reproduce your findings by using a fresh Drupa 8.7.3 install and after importing your view in which you used the `{{ body__summary }}` rewrite.
2. I was able to reproduce the error by *enabling* `Display any HTML as plain text` option in Basic HTML text format.
3. I was also able to reproduce the error by rewriting the view field output and choosing `{{ body__value }}` which basically prints the raw value of the body field.

My opinion is that 2 & 3 are normal behavior and it should be expected that in these particular cases the raw HTML is displayed. However, in 1, it seems a bug because the summary shouldn't be displayed as raw HTML; it should follows the same rules as the selected format.
I suggest to open an issue in Drupal issue tracker telling them about 1; maybe there is a reason behind this behavior, or if somebody already knows the answer, please elaborate.

Regards

# Answer
> 1 votes
I couldn't reproduce this in a fresh Drupal 8 installation. Only after I went to configure the text format that's used for the body field and activated the "Display any HTML as plain text" filter the problem occurred. The body field and the summary field are sharing the same text format.

So, I'd suggest you simply disable this filter. And you should be fine. Text formats can be configured under https://example.com/admin/config/content/formats.

---

# Answer
> 1 votes
I import your views and i did two changes and it works:

1. Remove rewrite **REWRITE RESULTS** by unchecking `Override the output of this field with custom text`
2. Change Formatter from `default` to `Summary or trimmed`
3. The result.

**Output before**

**Output after changes**

---
Tags: views, theming
---


# Question
Title: Executing view twice with different filters returns same results
Here's my simple scenario :

* Execute view with exposed filter (min & max dates)
* If there are no results, execute again with min date = 0 to get all results

Unfortunately, the query static cache will execute the same query twice.

```
$view           = views_get_view('my_view');
$view->set_display('default');

$date       = $view->get_item('default', 'filter', 'created');
$date['value']['min']   = date('Y-m-d', $date_from);
$date['value']['max']   = date('Y-m-d', $date_to);
$view->set_item('default', 'filter', 'created', $date);

$view->pre_execute();
$view->execute();
$results = $view->result;

$view->destroy();

// do logic here to determine if view needs to be queried a second time

$view           = views_get_view('my_view');
$view->set_display('default');

$date       = $view->get_item('default', 'filter', 'created');
$date['value']['min']   = date('Y-m-d', 0);
$date['value']['max']   = date('Y-m-d', $date_to);
$view->set_item('default', 'filter', 'created', $date);

$view->pre_execute();
$view->execute();
$results2 = $view->result;

$view->destroy();

// $results and $results2 are identical

```

If I comment the first part of the code, the second query will work correctly and $results2 contains a lot more results.

I've tried answers from this question \[1\], but no luck.

The only solution I found is to clear the entire static cache with `drupal_static_reset();`

How to elegantly solve this problem? I believe clearing only the static cache for the queries will solve this, but I fail to find the good $name argument.

\[1\] Clear views cache after node inserted in Drupal 7

# Answer
Here's the correct static cache to clear in order to solve the issue :

```
drupal_static_reset('views_exposed_form_cache');

```

I guess since the exposed filters are not supposed to change during a request, the developpers did not anticipate this.
> 0 votes

# Answer
The second argument to `views_get_view` is `$reset`:

> If TRUE, reset this entry in the load cache.

So second time around you just need to pass that:

```
$view = views_get_view('my_view');
$view->set_display('default');

...

$view = views_get_view('my_view', TRUE);

```

That will reset the static cache and the data will be fresh.
> 1 votes

---
Tags: 7, views
---


# Question
Title: How to define specific page on hook_page_top?
I want to add some stuff to the top of the page on certain pages.

How can I specify which pages that my custom content should be included on?

# Answer
> 4 votes
You can use the request object to figure out what page you are on and what to do with it.

Fx

```
$uri = \Drupal::request()->getRequestUri();

```

Maybe you want to get the route name instead:

```
$route = \Drupal::routeMatch()->getRouteName();

```

From there it's just a matter of defining your conditions in the hook.

# Answer
> 0 votes
To get the current raw path (the un-aliased Drupal path):

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

```

---
Tags: 8, hooks
---


# Question
Title: How do I identify what type of data or object I have? It's a referenced entity
I am new to Drupal but an experienced developer. I'm creating a DS field in which I will display a custom block chosen by the content editor. I have successfully gotten a referenced entity (two references deep) based on this answer How to get instance of referenced entity?.

Is there some data that will tell me what type of thing it is? Should I find out by looking in the UI at the block layout menu?

It would be simple to answer the question 'How do I get the block ID?' (answer: $bid = $campaignFundraisingBlock-\>id(); and I will fix that shortly) but the question I really want answered is 'How can I find out what type of data I have?'

The top answer (here) How can I programmatically display a block? made it clear that the type of block makes a difference in how you render it, so it seems important to be able to find out what type of data I have.

With the code (below) I am currently getting this error: Error: Cannot use object of type Drupal\block\_content\Entity\BlockContent as array in Drupal\shpf\_campaign\Plugin\DsField\ParentCampaignFundraisingBlock-\>build(), (which I will fix shortly).

Here's my code:

```
class ParentCampaignFundraisingBlock extends DsFieldBase {

  public function build() {
    $campaignStory = $this->entity();
    $fieldCampaignFundraiserOptIn = $campaignStory->get('field_campaign_fundraiser_opt_in')->getValue();
    $showFundraiserCta = FALSE;
    if (!empty($fieldCampaignFundraiserOptIn)) {
      $showFundraiserCta = $fieldCampaignFundraiserOptIn[0]['value'];
    }

    if ($showFundraiserCta) {
      $campaign = $campaignStory
        ->get('field_campaign_node_type')
        ->first()
        ->get('entity')
        ->getTarget()
        ->getValue();
      $campaignFundraisingBlock = $campaign
        ->get('field_campaign_fundraising_block')
        ->first()
        ->get('entity')
        ->getTarget()
        ->getValue();

  /* question: Do I have a renderable block in $campaignFundraisingBlock, or a type? How can I tell? */

      $bid = $campaignFundraisingBlock['values']->id;

  /* This next code assumes that the data I have is a block created in the interface (content block), but that seems like a big assumption that is not necessarily true. */

      $block = \Drupal\block_content\Entity\BlockContent::load($bid);
      $render = \Drupal::entityTypeManager()
        ->getViewBuilder('block_content')
        ->view($block);
      return $render;
    }
  }
}

```

Some background information: The block type is set to 'Featured CTA' and there are a bunch of blocks of that type available for content editors to choose from. The content editor chooses the block in the 'campaign' content type (it is an entity reference). The end user can fill out a form in which they tell a 'campaign story'. The end user can choose to include the campaign fundraiser or not. The campaign story has an entity reference to the campaign it is part of.

So, how do I find out what type of data I have?

# Answer
> 1 votes
> Do I have a renderable block in $campaignFundraisingBlock, or a type? How can I tell? How do I find out what type of data I have?

I will try to address the question how to determine the type of data in this scenario with entity references and the following block of code, which uses Entity and Typed Data APIs.

tl;dr $campaignFundraisingBlock should be an entity of whatever entity type(s) is referenced by the Entity Reference field "field\_compaign\_fundraising\_block", and this entity can be passed to its View Builder dynamically to create the appropriate render array.

```
$campaignFundraisingBlock = $campaign
  ->get('field_campaign_fundraising_block')
  ->first()
  ->get('entity')
  ->getTarget()
  ->getValue();

```

I would break down the method calls to understand this.

`$campaign` seems to be the entity that is injected into the Display Suite Field Plugin. I don't know much about Display Suite, but it's an entity, so some of the basic entity methods are available to determine what it is:

`EntityInterface::getEntityType` can get an object described by its corresponding @EntityType (or @ConfigEntityType or @ContentEntitType) plugin. This can be useful to determine the property/field definitions the entity is capable of.

```
$typedData = $campaign
   ->get('field_campaign_fundraising_block')
   ->first()
   ->get('entity')

```

The `get` method here returns FieldItemListInterface, and the subsequent methods are really a part of the lower-level Typed Data API (See Entity API "implements" Typed Data API quotation mine). When we get an object that is an instance of TypedDataInterface, then we have some different methods for getting definitions.

The basic interface here is very limited, and, depending on what Typed Data Data Type is being represented, then it might implement additional interfaces.

`TypedDataInterface::getDataDefinition` provides Typed Data Definition class that describes this Typed Data Data Type. The `DataDefinitionInterface::propertyDefinitions` returns an associative array DataDefinitionInterface keyed by the property name, and the `getDataType` method returns the plugin ID/string of the data type its representing. In this case, for Typed Data Data Type representing an entity, it's EntityDataDefinition, which calls up to the Entity Type (back in the higher-level Entity API) to get its base and bundle field definitions.

```
$referencedEntity = $typedData
  ->getTarget()
  ->getValue();

```

The EntityReference::getTarget method (really weird in my opinion) gets either a cached version of the *Typed Data* representation of the entity or loads the entity and returns the *Typed Data* representation of it.

Calling getValue on a Typed Data Data Type will return the underlying data. So in the case of primitive data types, a string scalar might be returned, or in the case of complex data types, an entity or an associative array.

Typed Data Data Types do not necessarily return render arrays or have methods that return render arrays. The Entity API has that concept for entities. This is why the entity object returned from getValue can be passed to its view builder.

Unfortunately we can't instantiate a View Builder from the Entity object or EntityType object of an entity because of dependency injection, which is why we need the EntityTypeManager to do so. However I *do* know the entity type dynamically because getEntityTypeId method so I can dynamically return a render array for the correct entity:

```
$render = \Drupal::entityTypeManager()
  ->getViewBuilder($referencedEntity->getEntityTypeId())
  ->view($referencedEntity);

```

So in short, again, if you don't necessarily know what entity type you're dealing with, then you can use `EntityInterface::getEntityTypeId` from an entity object and pass that into getViewBuilder. And hopefully the explanation about Entity and Typed Data will help to realize why that huge method chain is necessary to return the entity object.

---
Tags: blocks, display-suite
---


# Question
Title: Automatically export submissions as PDF to a directory on the server, or external location
**Background** Drupal 8 have a great new feature: Ability to use entity\_print to export submissions as pdf, and even to attach the pdf to email and send.

**Request** Because of the sensitivity of some information, sending them by email is not an acceptable option. Is it possible, to instead automatically generate the PDF when a submission is created or updated, and save it in a directory on the server or another external location?

Thanks for any help...

# Answer
> 1 votes
There is a drush command that will export all PDF documents in the tar file.

```
drush webform-export --exporter='webform_entity_print:pdf' contact >  contact.tar.gz

```

Otherwise, you would have to write custom code to generate the PDF documents when a submission is created. You can use `WebformEntityPrintWebformExporter::writeSubmission` as starting point for generating a submission's PDF document.

BTW, I do not recommend generating the PDF when a submission is created because it would slow down your site. Instead, I would queue the PDF generating.

---
Tags: 8, webforms
---


# Question
Title: Slow page load (seemingly large pulls from MariaDB)
We have a Drupal 8 site running on Windows/Apache/PHP7.2 that pulls data from a MariaDB server (on a different subnet - ie not in our DMZ) also running Windows. When a user is signed in to Drupal the pages load really slowly, looking at the firewall traffic between the drupal host and DB host during sign-in we're getting transfers weighing in between 1.5 MB and 18 MB. This to me seems excessive but as I am unfamiliar with Drupal can't say for certain.

One of our Dev team is adamant the issue is because the host is running Windows, we believe the slow page loads is due to the amount of data being pulled/processed - we would love to hear any experiences/opinions any of may have.

# Answer
> 0 votes
AFAIK, Windows networking is slower than Linux. Here's a study that show this:

https://www.principledtechnologies.com/Red%20Hat/RHEL6\_network\_0613.pdf

I think the underlying problem is that Windows sockets have a lot more overhead than Linux sockets do. So opening connections in Windows takes longer. Applications that are built for Linux often assume opening and closing sockets is quick and this can slow down performance on Windows.

That said, there are also a lot of differences in tuning Apache and MariaDB on windows. Linux has lightweight thread management and Windows doesn't. I seem to remember Linux has a few httpd processes that handle a bunch of threads while Windows may need a lot of separate larger processes to handle multiple connections. I believe there are similar settings for MariaDB as well. Do some searches on optimizing these under windows.

By default windows sticks a lot of cached information in the database, with a separate server, you may have some latency issues slowing things down while the cache info is retrieved. You may want to look at using APCu and Memcache to move this caching into your DMZ. This is not a security risk since these are all things that are going to be displayed via the webserver. There is lots of information on configuring these on the net.

Finally, you might consider using a front end cache agent. Varnish is not hard to set up or CloudFlare can supply a lot of this for free.

---
Tags: database
---


# Question
Title: Recommended Drush version to use and install for Ubuntu 19 with PHP 7.2 and running Drupal 7
It's been awhile since I've upgraded my server and I'm setting it up from scratch. I'm using Ubuntu 19, apache 2 and PHP 7.2. My site is Drupal 7 which is still running php 5.6 in my old server. I'm in the process of installing drush via the command on the new server:

> composer global require drush/drush:8

I'm not sure which version of drush I should be using or if I should even be installing via that method. What version of Drush should I be using for Drupal 7 and am I using the correct PHP version of 7.2?

# Answer
Drush 9 does not work with drupal 7, but drush 8 does work with it. I installed it by creating a new ubuntu user and making sure composer is installed globally then install cgr via:

**composer global require consolidation/cgr**

then add to your ~/.bashrc file

**export PATH="$HOME/.config/composer/vendor/bin:$PATH"**

then

**cgr drush/drush:8.x-dev --prefer-source**

link: https://github.com/consolidation/cgr#installation-and-usage

Then I followed the tutorial here: https://docs.drush.org/en/8.x/install-alternative/

> Install a global Drush via Composer
>
> Follow the instructions below:
>
> Install Composer globally.
>
> Install the cgr tool following the instructions in that project.
>
> Add composer's bin directory to the system path by placing export PATH="$HOME/.composer/vendor/bin:$PATH" into your ~/.bash\_profile (Mac OS users) or into your ~/.bashrc (Linux users).
>
> Install latest stable Drush: cgr drush/drush.
>
> Verify that Drush works: drush status
>
> Please do not install Drush using composer global require. See Fixing the Composer Global command for more information.
> 0 votes

---
Tags: 7, drush, composer
---


# Question
Title: Invalidate Internal Page Cache on cookie change
There's the `cookies` and `cookies:MY_COOKIE_NAME` cache context from core. Now I need to invalidate the Internal Page Cache for anonymous users when the value of a specific cookie changes. How can I implement this?

I tried to add:

```
$build['#cache']['contexts'][] = 'cookies:MY_COOKIE_NAME'

```

in `hook_entity_build_defaults_alter`, but that doesn't help and the page still returns from the cache.

# Answer
You have to override the `PageCache::getCacheId` method by adding the cookie value to form the Cache ID.

Have a look at Page Cache by cookies example.
> 4 votes

# Answer
The *Internal Page Cache* doesn't support cache contexts. It is a simple reverse proxy designed to serve static database content and the only Drupal specific feature it has is to invalidate cache tags. For more dynamic use cases you have to uninstall this module.

The *Dynamic Page Cache* will then be the frontend cache for anonymous traffic. It is not as fast as the *Internal Page Cache*, though, so if it doesn't provide the performance you need consider a third-party reverse proxy which is able to handle cookies dynamically.
> 3 votes

---
Tags: caching, cookies
---


# Question
Title: How to locally export config from a remote environment?
If I have config that's out of sync on production, I may want to export it without copying down the database, or I may have environment-specific config that interferes with exporting config from the local environment. Is there a way to export config from a remote environment locally?

# Answer
Edit: Turns out drush has a `config-pull` command to handle exactly this:

https://drushcommands.com/drush-8x/config/config-pull/

However, it doesn't work with config\_ignore as far as I can tell.

The original answer for posterity:

I've found that this bash command does the trick (on Mac OS X):

```
yes n | drush @site.env cim sync --preview=diff | \
sed -E 's/([\-]{3} ).*(\/.*.yml)/\1a\/config\/sync\2/' | \
sed -E 's/([\+]{3} ).*(\/.*.yml)/\1b\/config\/sync\2/' > cim.patch && \
interdiff -q cim.patch /dev/null > cex.patch && \
git apply cex.patch && \
rm cex.patch cim.patch

```

We use the preview argument of drush config-import (passing in 'n' when it prompts to import), clean up path names with sed, reverse the patch from import to export, and finally apply it and clean up. Note that you have to be on the same git branch as production.

With drush 9, the output and `yes` functionality changes a little, so you can instead use:

```
drush @site.env cim sync --no --preview=diff 2>/dev/null | \
sed -E 's/([\-]{3} ).*(\/.*.yml)/\1a\/config\/sync\2/' | \
sed -E 's/([\+]{3} ).*(\/.*.yml)/\1b\/config\/sync\2/' > cim.patch && \
interdiff -q cim.patch /dev/null > cex.patch && \
git apply cex.patch && \
rm cex.patch cim.patch

```
> 1 votes

---
Tags: importing-exporting, configuration
---


# Question
Title: Get field machine name inside HOOK_preprocess_file_link()?
I am hoping to get the field name inside `hook_preprocess_file_link()`.

I only want to alter the link of the file for certain field names.

`hook_preprocess_field()` would probably work, but I would prefer to use `hook_preprocess_file_link()`.

Is it possible to get the field name in this hook?

### mymodule.module

```
function mymodule_preprocess_file_link(&$variables, $fieldName) {
  // This returns "file_link" instead of the field name like "field_myfilefield".
  kpr($fieldName);
}

function mymodule_preprocess_field(&$variables) {
  if (isset($variables['field_name'])) {
    $fieldName = $variables['field_name'];
  }

  mymodule_preprocess_file_link($variables, $fieldName);
}

```

# Answer
You need to pass the field name to the file link through `hook_preprocess_field()`
A similar approach is used in Themable Forms module.
Check its module file.
> 0 votes

---
Tags: 8, hooks
---