# Question
Title: How do I Install an earlier version of Drupal 8 with composer because install fails on server with PHP 5.6?
My server is using PHP version 5, therefore, I need to install Drupal 8 version 8.6.18. But when I try, `composer create-project drupal-composer/drupal-project:8.x-dev my_site_name_dir --no-interaction --no-install`, I get the following error.

```
  [InvalidArgumentException]
  Could not find package drupal-composer/drupal-project with version 8.x-dev
  in a version installable using your PHP version 5.6.40.

```

Is there anyway to install 8.6.18 with composer?

# Answer
> 2 votes
Drupal 8 does not support PHP version 5. It requires a minimum PHP version of 7.0. Please see here for Drupal install requirements

Drupal Installation Requirements - Drupal.org

So you will have to upgrade PHP on your machine. Also PHP 5.0 is no longer supported and is not secure. So you might want to upgrade PHP on your server any way.

PHP Supported Versions - php.net

---
Tags: 8, composer
---


# Question
Title: Problem creating redirect from page with %20
I've been researching the issue for hours and can't seem to find a working solution to this problem. I've created a redirect from `/sites/default/files/OLB%20Registration%20Guide.pdf` to `/sites/default/files/downl_section/Online-Banking-Registration-Guide.pdf` that doesn't work.

Here is the line in `.htaccess`

`Redirect 301 "/sites/default/files/OLB Registration Guide.pdf" /sites/default/files/downl_section/Online-Banking-Registration-Guide.pdf`

My first inclination was to remove `%20`, but still nothing... Does anyone have any insight as to how to create a redirect where the original url contains `%20`?

Thanks!

# Answer
If you are using the Redirect module it has an admin page for fixing 404 errors with redirects. Your file should be listed there since it gives you a 404 error.

When clicked on "Add redirect" action link, your old link will be pre-populated on the next page for you to create a redirect.

That should fix the redirect issue.

In case it doesn't try replacing `white-space` with `+` (plus) character. In the URLs `+` can be used instead of white-spaces.
> 1 votes

# Answer
The redirect might not be going through because of this block in .htaccess:

```
# Pass all requests not referring directly to files in the filesystem to
# index.php. Clean URLs are handled in drupal_environment_initialize().
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^ index.php [L]

```

Make sure your `Redirect 301 ...` line is above this block.

Notice the part "**not referring directly to files**". So if the old file doesn't exist, the request is being rewritten and coming into Drupal.
> 0 votes

# Answer
The working htaccess rule that will do the Redirect is as follows.

```
Redirect 301 "/sites/default/files/OLB Registration Guide.pdf" "/sites/default/files/downl_section/Online-Banking-Registration-Guide.pdf"

```

This will only work if both the files exist in the system. If the first file does not exist then the rewrite rule that rewrites all urls that do not map to files to index.php will get applied. Here is the reference on the redirect / rewrite order - https://webmasters.stackexchange.com/questions/105937/execution-order-of-different-htaccess-redirects/105938#105938

Now you can also do this using Rewrite Rules. You will need to have the %MN patterns replaced by xMN in the match strings. There is a question related to this - https://stackoverflow.com/questions/46445000/htaccess-characters-not-escaping-in-rewrite-string
> 0 votes

---
Tags: 7, redirection, .htaccess
---


# Question
Title: How to display the pager on top and bottom of a custom search results page?
I have used the core Search Page functionality in Drupal 8 to built a search engine on my site. The pager is displayed at the bottom by default. How can i display the pager on the top also?

**Note:** I have **not** used views to built the search page.

Thanks!

# Answer
You could use CSS

```
.[wrapping-div-class] { position: relative; }
.[wrapping-div-class] .pager { position: absolute; top: 0px; }

```
> 0 votes

# Answer
You can add a custom page template for your search results page and then print the pager above the {{content}}

You can use the template name suggestions as listed here

Twig template naming conventions - Drupal 8

You can also use a preprocess function to duplicate the pager in the render array

Preprocessing output in Drupal 8 - Acquia
> 0 votes

---
Tags: 8, theming, search, paging
---


# Question
Title: How can I avoid getting "This route can only be accessed by anonymous users"?
I'm trying to use REST login from a React native app. When the user tries to log in, the app calls:

```
var data_node = {name:this.state.username,pass:this.state.password};
axios.post('http://IP/user/login?_format=json',data_node)
  .then((response) => {
    console.log(response);
  })
  .catch((error) => {
    console.log(error)
  });

```

If the call succeds, in test, the next time I try to authenticate the user, I get this error because the user has been authenticated in a previous call for which I haven't saved data, so I cannot call user/logout.

> This route can only be accessed by anonymous users.

How can I avoid it, forcing a new login?

# Answer
> 2 votes
This issue happens because you are trying to access the user/login route when you have cookie maintained at your app level. You need to make sure you clear the cookies before visiting that route.

You can use https://github.com/joeferraro/react-native-cookies to make sure all the cookies are cleared before you try to log in.

---
Tags: 8
---


# Question
Title: How do I use hook_preprocess_page_title() on a Bootstrap subtheme?
I've just discovered that Drupal 8 Bootstrap theme doesn't implement all existent hooks. So, for example, `hook_theme_suggestions_page_alter()` works, but `hook_theme_suggestions_node_alter()` doesn't work.

I'm interested on `hook_preprocess_page_title(&$variables)` and I wonder if it's possible to incorporate this hook into my custom Bootstrap sub-theme. I have created the *page-title.html.twig* template and cleared the cache.

I saw https://drupal-bootstrap.org/api/bootstrap/docs!plugins!Preprocess.md/group/plugins\_preprocess/8.x-3.x but it seems this is for extending an already existent hook in Bootstrap theme, not for adding a new one.

How do I add `hook_preprocess_page_title()` in a Bootstrap theme?

# Answer
> How do I add hook\_preprocess\_page\_title() in a Bootstrap theme?

In your sub-theme's **.theme** file you add:

```
/*
 * Implements hook_preprocess_page_title()
 */
SUB_THEME_NAME_preprocess_page_title(&$variables) {
  // your logic goes here
}

```
> 0 votes

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


# Question
Title: What is the correct way to use a Symfony bundle?
I want to use https://github.com/KnpLabs/KnpSnappyBundle in a Drupal 8 project. How do I correctly use it?

# Answer
> 3 votes
Drupal 8 isn't using Symfony bundles, only some Symfony components. Therefore you should use https://github.com/KnpLabs/snappy instead of bundle you've mentioned. You should install it using `composer` and then use available classes in your Drupal code. If you want to create PDF-generation service, you should follow official Drupal documentation.

# Answer
> 2 votes
I can't speak to configuring it as outlined in their documentation, but the typical way of using external packages is to install them with Composer, then one of these scenarios:

1. Define a custom service in your module that injects that bundle as an argument
2. In some cases, you could use `new ClassName(...)` if thats how that package works
3. Inject it from the container in your own classes create/construct method

Here is a more advanced method I wrote about some time ago about taking an external package and configuring it BEFORE it is injected to your class/service:

https://kevinquillen.com/dependency-inject-php-classes-drupal

This might be more in line with what you need to do, since you do not have the Symfony config.yml/app.yml their documentation alludes to for Symfony apps, and you have a need to configure the service as it is injected. This also works for packages that have config methods but are framework independent, like Solarium is.

As Milos also mentioned, this seems like the package you are looking for: https://github.com/KnpLabs/snappy

---
Tags: 8
---


# Question
Title: User list view showing total nodes created for each user
I have a view which displays a list of particular users. For each user displayed I would like to also display the total number of nodes that user has created.

I was wondering if there was an easy and/or efficient way of doing this, or if there is a module available that can? Obviously you would not want to calculate each total on the fly, but rather have the totals cached and updated whenever a user creates/deletes a node.

It would be nice if a module existed that could take care of this aggregate accumulation, and not just for node creation/deletion but for any desired aggregate (per user, or per node, etc).

Any help is greatly appre

# Answer
> 1 votes
If I understand the question this can be done in Views using aggregation.

1. Set up a View to list All Content (not users). Select Unsorted. Show fields rather than teasers.
2. Double check you really don't have any sorting in the **Sort criteria** section. If you do, it'll mess up the aggregation settings. If you forgot, remove it now. *I know I'm repeating here, but if you don't do this you run the risk of driving yourself crazy wondering why aggregation doesn't seem to be doing what it's supposed to.*
3. Add the `Content: author` relationship (in the **Advanced** section). This is so you can gain access to the the name field for the user.
4. Add the 'User: name' field (in the **Fields** section).
5. Turn on the `Use aggregation` option (in the **Advanced** section under **Other**).
6. Change the `Aggregation settings` for the `Content: Title` field. Set aggregation to COUNT. This will count up all titles authored by the same user.
7. If you need sorting, e.g. in descending number of posts, you can add that. But make sure under sorts you set the aggregation settings correctly, e.g. to COUNT. Alternatively, leave the **Sort criteria** section empty and sort via the Table format.

That's the tricky bit. If that's all working you can refine the output with Global: Custom Text fields or use of tables.

Your view configuration will look at bit like this:

**Note:** if you user entity has extra fields, e.g. for a richer user profile or for name variants etc. you may be able to access these through the 'Content: author' relationship. Or you may need to add another relationship.

# Answer
> 0 votes
Have a look at Views Calc module.

Views calc combined with a node relationship should get you the results you need.

# Answer
> 0 votes
To do this within a User-based view:

* Add Relation: *User: Content authored*
* Set Aggregation: *Yes*
* Add Filter: *Content NID \> 0* and *Aggregation Type "Count"* (using the above relation)
* Add Field: *User Name*
* Add Field: *Content NID* and *Aggregation Type "Count"* (using the above relation)

---
Tags: views, css-js-aggregation
---


# Question
Title: How do I enable and use a view mode for a product type?
In default commerce2 (drupal 8) I want to add second product-type view mode, to show in views - like teaser version, including add-to-cart btn with variations. I have additional field in Product type Default (in some custom product types too) and I want to limit them in this second view mode.

Seem like Product type (Default and customs) no options to add other view mode and in views is available Default view mode for Product. Product (type) is not listed in Structure \> Display modes \> Views modes.

## edit:

lamp stack, php-7.0, composer instalation from http://docs.drupalcommerce.org/v2/getting-started/install.html, act as uid 1

admin/commerce/config/product-types/default/edit/display

missing "Custom display settings" above "Save" btn

admin/structure/display-modes/view

Missing "Product (type?)" in list

# Answer
> 3 votes
Adding the answer to the question here as provided by @Bojan Zivanovic in a comment above. You can add View modes for products by clicking on the `+ Add view mode` blue button at the top of the page.

---
Tags: 8, commerce
---


# Question
Title: How do I programmatically create a webform from a newly created node?
This is the code I am using.

```
function walk_handler_entity_presave(EntityInterface $entity) {
  if (method_exists($entity, 'getType') && $entity->getType() === 'walk') {
    $elements = [];

    $elements[] = [
      '#title' => 'This is a test',
      '#type' => 'textfield'
    ];

    $webform = Webform::create([
      'id' => 'walk_' . $entity->id(),
      'title' => 'Test',
      'elements' => Yaml::encode($elements),
      'settings' => Webform::getDefaultSettings()
    ]);

    $webform->save();
  }
}

```

Somehow, this hook will get triggered twice: once when the node is getting submitted, and another time when the webform is getting created. The result is that I'm getting an error about the `Webform` object not having a `getType()` method and this is why I'm using `method_exists()` in the condition.

I can't seem to find any hook that would only focus on nodes and not on webforms.

What other hook can I use to react to new nodes being created?

# Answer
> 3 votes
`hook_entity_presave()` is called for every entity being saved which means that, since that `hook_entity_presave()` implementation is saving an entity, it is being invoked twice.

Using `method_exists()` is generally wrong, as in PHP is generally preferable to check if the object is an instance of a class implementing an interface or a class extending another class.
In this case, it's also wrong because the code isn't supposed to run for every entity that has a `getType()` method, but just for nodes. (While nodes are the only Drupal core entities with that method, there could be entities implemented from third-party modules that define that method, possibly for different purposes.)

You should check the entity type as said from berramou or use `hook_ENTITY_TYPE_presave()` as said from No Sssweat.
Since the question is asking how to create a webform when a node is created, I would rather use `hook_ENTITY_TYPE_insert()` which is invoked:

* Only when an entity is created, not when an entity is updated
* After the entity has been saved in the storage

Using this hook has the benefit of not creating a new webform every time a node is edited. The implementation code is also simpler, as it doesn't require checking the webform is already created for that node.

# Answer
> 2 votes
If you want the `hook_entity_presave()` to only focus on nodes and not on webforms, you can check the entity type like in the following code.

```
 /**
 * Implements hook_entity_presave().
 */
function YourModule_entity_presave(Drupal\Core\Entity\EntityInterface $entity) {
  if ($entity->getEntityTypeId() == 'node') {
    // Do you webform creation code here
  }
}

```

# Answer
> 2 votes
`hook_entity_presave()` runs when any entity is inserted or saved; thus, it runs twice in your case, since you have a Node and a Webform entity being saved.

You would have to add a conditional to check the entity type as @berramou's answer suggests.

Alternatively, you could use hook\_ENTITY\_TYPE\_presave() and target the node.

```
/*
 * Implements hook_ENTITY_TYPE_presave()
 */
function MODULE_NAME_node_presave(Drupal\node\NodeInterface $node) {
  // your code goes here
}

```

---
Tags: 8, entities, hooks
---


# Question
Title: Upload a file by Ajax without submitting the form
I want to upload a file by Ajax (without submitting the form) than process in backend, and clear the field to allow to add another file. Is it possible with Drupal 8? Can anyone provide an example?

I tried this one but without success.

```
$form['input']['file'] = array(
  '#type' => 'managed_file',
  '#upload_location' => "public://$file_dir/",
  "#upload_validators" => array(
    'my_file_validator' => array(),
  ),
);

```

My questions are: 1. How to add an extra process callback (backend) ? 2. How to clear the field (Front end) ?

Thank you Thank you

# Answer
This code uploads one file with Ajax, attaching it to an existing node's file field. The content type is file\_test, and the field is field\_da\_files.

(I'm not a professional programmer, so there are no doubt better ways to do this.)

Here's some HTML/JS that talks to a Drupal controller. It sends the node id, and the file to be stored.

In uptest.html.twig:

```
<p>NID <input type="text" id="nid" name="nid"></p>
<input type="file" id="file" name="file" />
<input type="button" class="button" value="Upload" id="but_upload">

```

In library JS file:

```
(function($, Drupal) {
  Drupal.uptestInitialized = false;
  Drupal.behaviors.uptest = {
    attach: function(context, settings) {
      if (Drupal.uptestInitialized) {
        return;
      }
      Drupal.uptestInitialized = true;
      $(document).ready(function() {
        $("#but_upload").click(function() {
          var fd = new FormData();
          var files = $('#file')[0].files[0];
          if (! files) {
            alert("No files");
            return;
          }
          var nid = $("#nid").val();
          if (! nid) {
            alert("No nid");
            return;
          }
          fd.append('nid', nid);
          fd.append('file', files);

          $.ajax({
            url: '/uptest-save',
            type: 'post',
            data: fd,
            contentType: false,
            processData: false,
            success: function(response){
              let result = response.success;
              if (result){
                alert('yay!');
              }
              else {
                let msg = response.message;
                alert('file not uploaded: ' + msg);
              }
            },
          });
        });
      })
}}})(jQuery, Drupal);

```

Routing file:

```
uptest.default_controller_hello:
  path: '/uptest'
  defaults:
    _controller: '\Drupal\uptest\Controller\DefaultController::hello'
    _title: 'uptest'
  requirements:
    _permission: 'access content'

uptest.default_controller_upload:
  path: '/uptest-save'
  defaults:
    _controller: '\Drupal\uptest\Controller\DefaultController::saveFile'
    _title: 'Save'
  requirements:
    _permission: 'access content'

```

In the controller:

```
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\File\FileSystemInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use \Drupal\Component\Utility\Bytes;

public function hello() {
  $renderable = [
    '#theme' => 'uptest',
    '#cache' => [
      'max-age' => 0,
    ],
    '#attached' => [
      'library' => [
        'uptest/uptest',
      ],
    ],
  ];
  return $renderable;
}

public function saveFile(Request $request) {
  $nid = $request->get('nid');
  if (!$nid || !is_numeric($nid) || $nid < 0) {
    return $this->makeUploadErrorResponse('Bad NID format');
  }
  $node = $this->entityTypeManager->getStorage('node')
    ->load($nid);
  if (!$node) {
    return $this->makeUploadErrorResponse('No node with nid of ' . $nid);
  }
  /** @var \Symfony\Component\HttpFoundation\File\UploadedFile $uploadedFile */
  $uploadedFile = $request->files->get('file');
  if (!$uploadedFile->isValid()) {
    return $this->makeUploadErrorResponse('Invalid file upload.');
  }
  //Get uploaded file metadata.
  $uploadedFileName = $uploadedFile->getClientOriginalName();
  $uploadedFileExtension = $uploadedFile->getClientOriginalExtension();
  $uploadedFileSize = $uploadedFile->getClientSize();
  $uploadedFilePath = $uploadedFile->getPathname();
  //Get node field metadata.
  $nodeFieldMetadata = $this->getFileFieldMetaData('file_test', 'field_da_files');
  if (!$nodeFieldMetadata) {
    return $this->makeUploadErrorResponse('Problem loading file field metadata.');
  }
  //Check uploaded file's extension.
  $allowedExtensions = explode(' ', $nodeFieldMetadata['extensions']);
  if (!in_array($uploadedFileExtension, $allowedExtensions)) {
    return $this->makeUploadErrorResponse('Extension not allowed.');
  }
  //Check the file size.
  $maxSizeAllowed = Bytes::toInt($nodeFieldMetadata['max file size']);
  if ($uploadedFileSize > $maxSizeAllowed) {
    return $this->makeUploadErrorResponse('File too large.');
  }
  //Check cardinality.
  /** @var \Drupal\file\Plugin\Field\FieldType\FileFieldItemList $fieldValueInNode */
  $fieldValueInNode = $node->get('field_da_files');
  $fieldAttachedFileItemList = $fieldValueInNode->getValue();
  $nodeFileFieldNumAttachments = count($fieldAttachedFileItemList);
  $allowedCardinality = $nodeFieldMetadata['cardinality'];
  if ($nodeFileFieldNumAttachments >= $allowedCardinality) {
    return $this->makeUploadErrorResponse('Maximum number of files for this node already reached.');
  }
  //OK. Attach the file.
  //Prepare the directory.
  $directory = 'private://' . $nodeFieldMetadata['directory'];
  $result = file_prepare_directory($directory, FileSystemInterface::CREATE_DIRECTORY);
  if (!$result) {
    return $this->makeUploadErrorResponse('Error preparing directory.');
  }
  //Read the file's contents.
  $fileData = file_get_contents($uploadedFilePath);
  //Save in right dir, creating a file entity instance.
  $savedFile = file_save_data($fileData,
    $directory . '/' . $uploadedFileName,
    FileSystemInterface::EXISTS_RENAME
  );
  if (!$savedFile) {
    return $this->makeUploadErrorResponse('Error saving file.');
  }
  //Attach to the node.
  $node->field_da_files[] = [
    'target_id' => $savedFile->id(),
  ];
  $node->save();
  return new JsonResponse([
    'success' => TRUE,
  ]);
}

/**
 * Make a response for file upload attempt with an error message.
 *
 * @param string $message The error message.
 *
 * @return \Symfony\Component\HttpFoundation\JsonResponse Response to return to client.
 */
protected function makeUploadErrorResponse($message) {
  $result = [
    'success' => FALSE,
    'message' => $message,
  ];
  return new JsonResponse($result);
}

/**
 * Get metadata for a file field.
 *
 * @param string $contentType Content type with the field.
 * @param string $fieldName Name of the field.
 *
 * @return array|bool Metadata, or false if a problem.
 */
public function getFileFieldMetaData($contentType, $fieldName) {
  if ($contentType === '' || $fieldName === '') {
    return FALSE;
  }
  $entityFieldManager = \Drupal::service('entity_field.manager');
  $fields = $entityFieldManager->getFieldDefinitions('node', $contentType);
  if (!$fields || count($fields) === 0) {
    return FALSE;
  }
  //Get file field definition.
  if (!isset($fields[$fieldName])) {
    return FALSE;
  }
  /** @var \Drupal\field\Entity\FieldConfig $fieldDef */
  $fieldDef = $fields[$fieldName];
  //Get settings, doesn't include cardinality.
  $directory = $fieldDef->getSetting('file_directory');
  //Resolve tokens.
  /** @var \Drupal\Core\Utility\Token $tokenService */
  $tokenService = \Drupal::service('token');
  $directory = $tokenService->replace($directory);
  $fileExtensions = $fieldDef->getSetting('file_extensions');
  $maxFileSize = $fieldDef->getSetting('max_filesize');
  //Get cardinality.
  /** @var \Drupal\field\Entity\FieldStorageConfig $fieldStorageDef */
  $fieldStorageDef = $fieldDef->getFieldStorageDefinition();
  $cardinality = $fieldStorageDef->getCardinality();
  //Return results.
  $result = [
    'content type' => $contentType,
    'field' => $fieldName,
    'directory' => $directory,
    'extensions' => $fileExtensions,
    'max file size' => $maxFileSize,
    'cardinality' => $cardinality,
  ];
  return $result;
}

```

Hope that helps.
> 0 votes

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


# Question
Title: How to create paragraph of particular type using JSONAPI?
I am able to GET the data using endpoint "**site\_url/jsonapi/paragraph/text**". But I am not able to create a new paragraph of type text. Its always giving me error "403 forbidden". I have tried all drupal permissions also i am using simple oauth and i am using admin token to POST.

```
Endpont :- site_url/jsonapi/paragraph/text
Request Type :- POST
Post Body :- {

"data": {
    "type": "paragraph--text",
    "attributes": {
        "field_text": {
            "value": "<p>ദുബായ് ∙ സാമ്പത്തിക അച്ചടക്കമില്ലാത്തവർക്കു കുരുക്കായി ക്രെഡിറ്റ് കാർഡുകൾ. കൃത്യമായി പണം തിരച്ചടയ്ക്കാതെ കുടിശിക പെരുകി കുടുക്കിലാകുന്നവരിൽ മലയാളികളുമേറെ. ബാധ്യത കൂടി ചിലർ വിട്ടുവീഴ്ചയ്ക്കായി ബാങ്കിനെ സമീപിക്കുമ്പോൾ മറ്റു ചിലർ രാജ്യത്തുനിന്നു മുങ്ങും. ഒരു കാർഡിന്റെ ബാധ്യത തീർക്കാൻ മറ്റൊരു ബാങ്കിൽ നിന്നുകൂടി ക്രെഡിറ്റ് കാർഡ് എടുത്ത് രണ്ടും തിരിച്ചടയ്ക്കാത്തവരുമുണ്ട്.</p>\r\n",
            "format": "basic_html",
            "processed": "<p>ദുബായ് ∙ സാമ്പത്തിക അച്ചടക്കമില്ലാത്തവർക്കു കുരുക്കായി ക്രെഡിറ്റ് കാർഡുകൾ. കൃത്യമായി പണം തിരച്ചടയ്ക്കാതെ കുടിശിക പെരുകി കുടുക്കിലാകുന്നവരിൽ മലയാളികളുമേറെ. ബാധ്യത കൂടി ചിലർ വിട്ടുവീഴ്ചയ്ക്കായി ബാങ്കിനെ സമീപിക്കുമ്പോൾ മറ്റു ചിലർ രാജ്യത്തുനിന്നു മുങ്ങും. ഒരു കാർഡിന്റെ ബാധ്യത തീർക്കാൻ മറ്റൊരു ബാങ്കിൽ നിന്നുകൂടി ക്രെഡിറ്റ് കാർഡ് എടുത്ത് രണ്ടും തിരിച്ചടയ്ക്കാത്തവരുമുണ്ട്.</p>"
        }
    },
    "relationships": {
        "paragraph_type": {
            "data": {
                "type": "paragraphs_type--paragraphs_type",
                "id": "6692c53b-f2f3-4a52-a18f-e59d94be3c88"
            }
        }
    }
}
}

```

This is always giving me 403 forbidden error. Am i doing anything wrong ?

# Answer
> 0 votes
Issue was I didn't enable the "Paragraph Type Permission" module. Install it and go to drupal permissions.

---
Tags: 8, paragraphs
---


# Question
Title: Show/hide fields in a form based on the value of a checkbox
Is there a way to hide a specific or specifics fields in Drupal when you create content until you checked a checkbox?

Now it looks like this:

I need something like this:

But I need some checkboxes to decide if I have a certain field to show or not. Like this:

(Fieldcollection item 'some information' is showing up now because I checked the checkbox before the label)

Is there a module for this?

What would be nice is if all fields only become mandatory if you checked a checkbox.

# Answer
In Drupal 7 you can use $form #states instead of custom jQuery script. Example:

```
  $form['student_type'] = array(
    '#type' => 'radios',
    '#options' => array(
      'high_school'   => t('High School'),
      'undergraduate' => t('Undergraduate'),
      'graduate'      => t('Graduate'),
    ),
    '#title' => t('What type of student are you?')
  );

  // High school information.
  $form['high_school']['tests_taken'] = array(
    '#type' => 'checkboxes',
    '#options' => drupal_map_assoc(array(t('SAT'), t('ACT'))),
    '#title' => t('What standardized tests did you take?'),
    // This #states rule says that this checkboxes array will be visible only
    // when $form['student_type'] is set to t('High School').
    // It uses the jQuery selector :input[name=student_type] to choose the
    // element which triggers the behavior, and then defines the "High School"
    // value as the one that triggers visibility.
    '#states' => array(
      'visible' => array(   // action to take.
        ':input[name="student_type"]' => array('value' => 'high_school'),
      ),
    ),
  );

```
> 0 votes

# Answer
Drupal 8 has a very well structured system to show hide fields based on values of other fields. It is called the Form API #states system. You can see drupal.org documentation on #states.

While defining the form you can map the visible and invisible states of the form element based on the value of another form element.

This is an example from the documentation above

```
$form['toggle_me'] = array(
  '#type' => 'checkbox',
  '#title' => t('Tick this box to type'),
);
$form['settings'] = array(
  '#type' => 'textfield',
  '#states' => array(
    // Only show this field when the 'toggle_me' checkbox is enabled.
    'visible' => array(
      ':input[name="toggle_me"]' => array(
        'checked' => TRUE,
      ),
    ),
  ),
);

```

There are other states besides visible and invisible that can be controlled through the same mechanism. Lullabot has a good article on Form API #states

Other states including making a field required is available. The full list is as follows.

```
enabled
disabled
required
optional
visible
invisible
checked
unchecked
expanded
collapsed

```
> 0 votes

# Answer
You can use module conditional fields if you want to do this node form
> 0 votes

---
Tags: forms
---


# Question
Title: How do I add more pages to views pagination on mobile?
I'm using Open Social and I want to add more pages to the paginationon mobile phones.

One of my views has 11 pages of users and on mobile the pagination is as the following example (\<\< = previous page, \>\> = next page):

```
<< 5 >>

```

Now what I want to achieve is the following:

```
<< 3 4 5 6 7 >>

```

Now I have searched through all the settings but I can't seem to find where to change this. I believe it should be in the code but no luck so far either. Can anyone push me in the right direction?

# Answer
You must do this in the views configuration.

First you need to set the pager to use `full pager` instead of `mini pager`.

Then in the settings you can set the amount of pager links visible (in your case 5).

That should show the pager you want with 5 pager links visible.
> 0 votes

---
Tags: views, 8
---


# Question
Title: Bootstrap simple carousel: how to display it on front-end?
I've installed Bootstrap simple carousel module and I know how to add/edit slides. But I didn't find anywhere instructions on how to display them on the front-end. Module didn't create any new block, view or something?!?

How to display slide show on the front-end?

# Answer
If you look at https://git.drupalcode.org/project/bootstrap\_simple\_carousel/blob/8.x-1.x/src/Plugin/Block/CarouselBlock.php

> ```
> /**
>  * Provides a 'Bootstrap simple carousel' Block.
>  *
>  * @Block(
>  *   id = "bootstrap_simple_carousel_block",
>  *   admin_label = @Translation("Bootstrap simple carousel block")
>  * )
>  */
>
> ```

There is a block for it, called, "Bootstrap simple carousel block". You just have to place it in a region over at /admin/structure/block
> 0 votes

---
Tags: 8
---


# Question
Title: Webform: how to wrap each form field with a div?
Due to a design request, I need to add a DIV around each textfield/select field in my webform.

Since a webform is, both, a form and a node, I'm struggling to figure out how to do that.

In a normal form, I would use the hook\_form\_alter() and use the #prefix and #suffix attributes to add extra markup, but when printing out the webform in the hook to see the structure of the fields I can't see how to target each field.

Any help will be greatly appreciated!

Thanks.

# Answer
You're correct in thinking to use the `#prefix` and `#suffix` attributes. Webform components are stored in the 'submitted' part of the form array. To add a surrounding div to each textfield and select, you can do the following in hook\_form\_alter:

```
if ($form_id == 'webform_client_my_form_id') {
  foreach($form['submitted'] as &$field) {
    if($field['#type'] == 'textfield' || $field['#type'] == 'select') {
        $field['#prefix'] = '<div class="my-div">';
        $field['#suffix'] = '</div>';
    }
  }
}

```

To find out your form id, you can add a watchdog statement:

```
watchdog('My Module', "Form Id: $form_id");

```

Then check the dblog at /admin/reports/dblog.

This link may also be helpful: https://drupal.org/node/1558246
> 6 votes

# Answer
Alternative to Form Hook, you can use the *webform-form-{form-id}.tpl.php* template file to accommodate your changes.

For Example,

```
$form['submitted']['name']['#prefix'] = '<div class="form-group">';
$form['submitted']['name']['#suffix'] = '</div>';
$form['submitted']['name']['#attributes']['class'][] = 'form-control snow_form_control';

```

Like above you can add the required class or wrappers. Hope this helps.
> 0 votes

---
Tags: forms, webforms
---


title: Alter block form

text:
# Question
Title: Alter block form
I'm using the contrib module contact block and I would like to edit the block form settings. By default, there is a textfield (title) and the "Display title" checkbox, I need to hide those fields by use of some hook(s) but I don't know which one should I use, already tested:

* hook\_form\_alter()
* hook\_field\_widget\_WIDGET\_TYPE\_form\_alter()

My form.

How could I hide them (without css)? Thanks all.

# Answer
You can use `hook_form_alter` do this but first should check the form concern only your block, if you check only on `$form_id == 'block_form'` you will hide those field in all block forms.
Try with the following.

```
/**
 * Implements hook_form_alter().
 */
function MyModule_form_alter(&$form, $form_state, $form_id) {
  // Check if the provider is contact_block, to target only contact_block form
  if ($form_id == 'block_form' && isset($form['settings']['provider']['#value']) && $form['settings']['provider']['#value'] == 'contact_block') {
    // Hide  Display title checkbox
    $form['settings']['label_display']['#access'] = FALSE;
    // Hide title textfield
    $form['settings']['label']['#access'] = FALSE;
  }

```
> 3 votes

---
Tags: 8, blocks
---


# Question
Title: Query that converts a timestamp to a date
Is it possible to convert a timestamp to a date format in a query?

This is the code I am using.

```
$query = db_select('my_submissions', 's');
$query->fields('s', array('sid','name','company','email','phone','is_customer','submitted','count'));
$entries = $query->execute();

$rows = array();
foreach ($entries as $entry) {
  $row = array_map('check_plain', (array) $entry);
  $row['submitted'] = $row['submitted'] ? date('d.m.Y H:i', $row['submitted']) : "";
  $rows[] = $row;
}

```

# Answer
> 4 votes
```
$select->addExpression("DATE_FORMAT(FROM_UNIXTIME(submitted), '%d.%m.%Y %H:%i')", 'submitted_formatted');

```

http://www.w3schools.com/sql/func\_date\_format.asp

then in your loop, reference it as $row\['submitted\_formatted'\];

# Answer
> 1 votes
MySQL allows converting a timestamp into a formatted date, using the FROM\_UNIXTIME function.

In your case, instead of the 'submitted' field, you might add an expression to the query with the addExpression method, in the following way:

```
$query->addExpression("FROM_UNIXTIME(submitted, '%d.%m.%Y %H:%i')");

```

# Answer
> 0 votes
While

```
$select->addExpression("DATE_FORMAT(FROM_UNIXTIME(yourDBcolumn), '%d.%M.%Y')", 'c.yourDBcolumn_formatted');

```

Does indeed work, this is definitely not best practice if you're displaying this on a page/block.

A themer/front-end dev shouldn't have to go into PHP code to change the format of the date.

It's best practice for your custom module to have a template file where they can easily format it with Twig's `|date` filter

```
{{ mydate|date }}           <!-- November 17, 2019 23:12 -->
{{ mydate|date('d/m/Y') }}  <!-- 17/11/2019 -->

```

Also, you could add timezone here, ex:

```
{{ mydate|date('d/m/Y', 'Europe/Paris') }}

```

---
Tags: database, datetime
---


# Question
Title: How do i dynamically import changing feed links within a feed
I am uncertain how to approach this.

I have a feed with housing cases that is changing constantly. The feed consists of a case number and a feed link to that particular house. Each house has so much information that it has its own feed. Over time, more will be added and these feed links will change.

For each of these feed links, I want to create a single node. My issue is that I don't really see a solution on how to create these dynamic feeds from the one "main" feed.

It's going to be about 75-150 feeds within the "main" feed. So I have this list of changing feed links that I need to dynamically import.

This is in Drupal 8 and I have been trying to use the module feeds to accomplish this.

# Answer
> 0 votes
It sounds like you need a custom implementation that will dynamically add feed importers based on a particular "Master feed import".

Personally I would do this with the migrate API instead of feeds as it gives you much higher flexibility for data manipulation and queue control for large datasets.

# Answer
> 0 votes
If each feed has the same structure, you would only need to create one feed type and then one feed of that type for each house.

You could write a custom module to dynamically create the feed entities, or to dynamically update them.

Of course, you could also look into Migrate. Migrate does indeed have a larger feature set, but also a steeper learning curve and almost no UI.

---
Tags: 8, feeds
---


# Question
Title: How to add HTML5 attribute "autocomplete" to form fields?
According to an accessibility test, I have to add the HTML5 attribute "autocomplete" an the proper tags to all form fields on my website where the user fills in his/ her personal data.

E.g. "Your E-Mail" \> `autocomplete="email"`, "Your Family Name" \> `autocomplete="family-name"`, etc. (The proper tags are listet in the WHATWG HTML standard https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill)

Some of the fields are in Drupal core (like the user registration form), others are webforms (like an event registration).

What is the best way to achieve this in Drupal 8?

# Answer
> 0 votes
I think it's possible to add this attribute to all input fields using a bit of JS, something like this should work:

```
(function($, Drupal) {
  Drupal.behaviors.autocompleteFieldBehavior = {
    attach: function (context) {
      $(context).find('input').each(function () {
        var name = $(this).attr('name');
        if ($(this).attr('autocomplete').length === 0) {
          if (name) {
            $(this).attr('autocomplete', name);
          }
          else {
            $(this).attr('autocomplete', 'Default autocomplete value.');
          }
        }
      });
    }
  };
})(jQuery, Drupal);

```

The other solution would be alter all forms using `hook_form_alter`, see @berramou's comment.

---
Tags: 8, forms, webforms
---


# Question
Title: Change views exposed filter value only on page reload
Is there a clean way to alter a View exposed filter field, but only on page reload and not each time you submit the exposed filters form ?

---

**Example**

I have a View with exposed filters. When a user is loading this View, I want to change the value of an exposed filter field, depending on a cookie value.

I've managed to make it work with the `hook_form_views_exposed_form_alter` function.

```
function HOOK_form_views_exposed_form_alter(&$form, FormStateInterface $form_state, $form_id) {
    if ($form['#id'] == 'views-exposed-form-MY-VIEW') {
        $cookies = \Drupal::request()->cookies->all();
        if (isset($cookies['MY_COOKIE'])) {
            $form['MY_FIELD']['#value'] = $cookies['MY_COOKIE'];
        }
    }
}

```

Problem is : if the user manually change the exposed filter and submit the form, the value is getting back to the first one because the hook\_form\_alter is getting called again.

Here is a video : https://i.stack.imgur.com/ZSRLQ.jpg

---

**Poor solution**

I've found a solution, but it doesn't looks like a good one. I've found out that when the hook\_form\_alter is getting called by a submit, there is a new entry (`'a' => ''`) in the UserInput array that you can find by calling `$form_state->getUserInput()`.

First load :

```
[
    'MY_FIELD' => 'All',
    '...' => '...'
]

```

After submit :

```
[
    'MY_FIELD' => 'New value',
    'a' => '',
    '...' => '...'
]

```

So now I can use the following to change the field value only on the page load :

```
if (isset($cookies['MY_COOKIE']) && !array_key_exists('a', $form_state->getUserInput())) {
    $form['MY_FIELD']['#value'] = $cookies['MY_COOKIE'];
}

```

*But I'm not even sure it is fully functional, is there a better way to do it ?*

---

**Clean solution**

Thank's to @NoSssweat, here's a cleaner solution :

```
function MODULE_views_pre_build(ViewExecutable $view) {
    $request = \Drupal::request();
    $is_ajax = $request->isXmlHttpRequest();
    if (!$is_ajax) {
        $cookies = \Drupal::request()->cookies->all();
        if (isset($cookies['MY_COOKIE'])) {
            $view->setExposedInput(['MY_FIELD' => [$cookies['MY_COOKIE'] => $cookies['MY_COOKIE']]]);
        }
    }
}

```

# Answer
> 1 votes
> Just added a video link to show you : imgur.com/EmVha6e

You just need to add a conditional to check if it's not ajax

```
   $request = \Drupal::request();
   $is_ajax = $request->isXmlHttpRequest();
   if (!$is_ajax) {
     // code that sets the filter initial value
   }

```

Credit: How can I detect AJAX request inside Drupal?

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


title: Job queue – dealing with stuck records

text:
# Question
Title: Job queue – dealing with stuck records
I have a cron job that gets stuck because I have a loop claiming items from the queue that ends on `numberOfItems() == 0`, which never happens because one of the queue items is stuck and cannot be claimed.

Clearly this is a flaw on my side, but I am trying to understand how to best address it. The `claimItem()` method returns `FALSE` every time in this case, so it should be easy to handle cases of bad queue processing, for example:

```
while ($item = $queue->claimItem()) {
    // process item
}

```

However, what if the first queue item is "faulty", while there are other queue items that are perfectly fine? I will never be able to retrieve them in this method. It also seems impossible to move on to the next item in the queue if `claimItem()` returns false (please correct me if I am wrong).

What is the correct way to handle such cases with Drupal's queue?

# Answer
When looking at the code from the `claimItem` method it only returns FALSE if no items are available to claim.

So if `$queue->claimItem()` returns FALSE you can be sure that all available items are claimed (or failed to be claimed).

```
public function claimItem($lease_time = 30) {
  // Claim an item by updating its expire fields. If claim is not successful
  // another thread may have claimed the item in the meantime. Therefore loop
  // until an item is successfully claimed or we are reasonably sure there
  // are no unclaimed items left.
  while (TRUE) {
    try {
      $item = $this->connection->queryRange('SELECT data, created, item_id FROM {' . static::TABLE_NAME . '} q WHERE expire = 0 AND name = :name ORDER BY created, item_id ASC', 0, 1, [':name' => $this->name])->fetchObject();
    }
    catch (\Exception $e) {
      $this->catchException($e);
      // If the table does not exist there are no items currently available to
      // claim.
      return FALSE;
    }
    if ($item) {
      // Try to update the item. Only one thread can succeed in UPDATEing the
      // same row. We cannot rely on REQUEST_TIME because items might be
      // claimed by a single consumer which runs longer than 1 second. If we
      // continue to use REQUEST_TIME instead of the current time(), we steal
      // time from the lease, and will tend to reset items before the lease
      // should really expire.
      $update = $this->connection->update(static::TABLE_NAME)
        ->fields([
          'expire' => time() + $lease_time,
        ])
        ->condition('item_id', $item->item_id)
        ->condition('expire', 0);
      // If there are affected rows, this update succeeded.
      if ($update->execute()) {
        $item->data = unserialize($item->data);
        return $item;
      }
    }
    else {
      // No items currently available to claim.
      return FALSE;
    }
  }
}

```
> 1 votes

---
Tags: 8, cron, queue
---


title: How to use service container correcly?

text:
# Question
Title: How to use service container correcly?
I want to use service container inside my class so I have this this:

```
class SomeController extends ControllerBase {

  protected $entityTypeManager;
  protected $requestStack;

  public function __construct(EntityTypeManagerInterface $entityTypeManager,RequestStack $requestStack){
    $this->entityTypeManager = $entityTypeManager;
    $this->requestStack = $requestStack;
   }

  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('entity_type.manager'),
      $container->get('request_stack'),
    );
  }

  public function content() {
    $testEntityTypeManager = $this->entityTypeManager->getStorage('node')->getQuery();
    $testRequest = $requestStack->getCurrentRequest();
    //do something with these...
  }

}

```

What I wanted to do here is create a container for EntityTypeManager and RequestStack. Now phpStorm is giving me a warning regarding `public static function create(ContainerInterface $container)` and it says `Method call uses 2 parameters, but method signature uses 1 parameters` and I can't use it in my method `content()`.

$testEntityTypeManager and $testRequest are just examples with which I would do something else but even now it doesn't work and phpStorm tells me getCurrentRequest().

Sure I can use them statically but that is not what I'm trying to achieve here. Any push in right direction is appreciated!

# Answer
> 0 votes
The error:

> `Method call uses 2 parameters, but method signature uses 1`

Your create() method is defined to only receive a single argument, `$container`. This must be a debugger in PHPStorm giving you this output, because what it is saying is that the code calling SomeController::create() is passing two arguments. So the second is getting lost. Your problem is likely stemming from that, and probably means one of two things:

1. The code calling the create() function is mistakenly passing a second value, or
2. Your create() function needs to be re-defined to catch the second argument, and do something with it.

ControllerBase::create only expects a single argument, `$container`, and since your function defines that, I'd guess the more likely culprit is the calling function passing an unnecessary argument (#1 above). However, if the passed variable is necessary for some reason, SomeController::create() can be redefined to catch an optional argument:

```
public function create(ContainerInteface $container, $additional_param1 = NULL) {
  if (is_null($additional_param1)) {
    throw new \Exception('$additional_param_1 is required');
  }

  // Continue as normal.

}

```

---
Tags: 8, dependency-injection
---


# Question
Title: How to normalize / resolve membership ID to all account UID per group_content
I'm trying to add the owner's membership to every `GroupContent`. By default ownership is only identified by the Account ID.

It seems a Normalizer and/or custom resolver is necessary. Beyond my struggles to get the correct dependency injection to add my serialization service to my controller, I'm not even sure if this is possible since it seems the `$context` variable never includes anything related to the URL or parent entity (Group).

So far, I'm basically parsing the group's ID from `$_SERVER['REQUEST_URI']` and then `SELECT id as memberid from group_content_field_data where type = 'groups-group_membership' AND entity_id = :uid AND gid = :gid`.

1. Could some caching making `$_SERVER['REQUEST_URI']` unreliable from within a Normalizer?
2. How can I add normalize `GroupContent` to include both the owner's account ID and membership id?

# Answer
I was using extending `Drupal\serialization\Normalizer\FieldItemNormalizer`. I added this service extending `Drupal\serialization\Normalizer\ContentEntityNormalizer` to get the group id from `group_content`

```
  serializer.normalizer.group_content:
    class: Drupal\tam_api\Normalizer\GroupContentNormalizer
    arguments: ['@entity.manager']
    tags:
      - { name: normalizer, priority: 8 }

```

```
<?php
namespace Drupal\tam_api\Normalizer;

use Drupal\group\Entity\Group;
use Drupal\group\Entity\GroupContent;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Drupal\serialization\Normalizer\ContentEntityNormalizer;

class GroupContentNormalizer extends ContentEntityNormalizer implements NormalizerInterface {

  protected $supportedInterfaceOrClass = 'Drupal\group\Entity\GroupContent';
  const FORMAT = 'json';

  public function normalize($entity, $format = NULL, array $context = []) {

    $attributes = parent::normalize($entity, $format, $context);
    $gid = $attributes['gid'][0]['target_id'];

    $connection = \Drupal::database();
    $sql = "SELECT G.id as memberid, G.label, F.field_name_value, P.field_headshot_target_id as fid
            FROM group_content_field_data G LEFT JOIN group_content__field_name F
            ON F.entity_id = G.id
            LEFT JOIN group_content__field_headshot P
            ON P.entity_id = G.id
            WHERE G.type = 'groups-group_membership' AND P.deleted = 0 AND F.deleted = 0
            AND G.entity_id = :uid AND G.gid = :gid";

    $fields = ['uid', 'field_leaders', 'field_editors']; // my fields that need the membership data
    foreach($fields as $field_name) {
      if (isset($attributes[$field_name])) {
        foreach($attributes[$field_name] as &$entry) {
          $uid = $entry['target_id'];
          $membership =  $connection->query($sql, array(':uid'=>$uid, ':gid'=>$gid))->fetchAssoc();
          $entry['target_gc'] = intVal($membership['memberid']);
          if (!empty($membership['field_name_value'])) {
            $entry['target_label'] = $membership['field_name_value'];
          } else {
            $entry['target_label'] .= ' FALLBACK';
          }
          if (!empty($membership['fid'])) {
            $file = \Drupal\file\Entity\File::load($membership['fid']);
            if ($file->getSize() > 600000) {
              $entry['url'] = \Drupal\image\Entity\ImageStyle::load('medium')->buildUrl($file->getFileUri());
            } else {
              $entry['url'] = $file->url('canonical');
            }
          }
        }
      }
    }

    return $attributes;
  }

  public function supportsNormalization($data, $format = NULL) {
    return $format === static::FORMAT && $data instanceof \Drupal\group\Entity\GroupContent;
  }

}

```
> 0 votes

---
Tags: 8, group
---


# Question
Title: Views date filter by year - only one select list for the year
I have a content type "news" and a views page to list the news. The views contains a exposed filter (category and year).

How can I realize the select list "Year" with the follwing options as exposed filter:

* All
* 2016
* 2015
* 2014
* 2013
* 2012

When the user selects '2015' the list below is updatet (ajax) and only news entry form 2015 are listed.

How can I realize this?

# Answer
> 1 votes
1. Add filter criteria of **Year** field.
2. Now expose this field by selecting 'Expose this filter to visitors, to allow them to change it' option from field setting.
3. For Ajax behaviour, choose **Use AJAX** from advance view section.

# Answer
> 0 votes
Using Views, you will need to use a contextual filter based on the year. For the exposed filter, I have utilized the settings for the date like so:

---
Tags: 7, views, datetime
---


# Question
Title: How to determine if a View display is being used in a site?
We have many Views and Views displays. Over 3 years of building the site we have many displays that are not being used. We would like to delete them and clean up the view but are concerned that a display might be used in the site. Is there a way of determining if a views display is being used on the site? I thought of different ways to check this:

1. A View display that is a Page will have a URL path. Check the path to see if it is working.
2. A View display that is a block display will be in Managed Blocks. Go to Managed Blocks and see if is placed in any region.
3. You can look at the view display machine name. And see if there are any twig templates that match that name.
4. Also do a grep search in our templates for the display machine name to check if it printed in a twig template.

# Answer
If this is in Drupal 8, you can export all config and search for the display id in both code and config and you should be able to find if it is being used anywhere.
> 2 votes

---
Tags: views, theming, blocks
---


# Question
Title: Drupal 8 - some child pages are not visible on particular book using view
I would like to ask for your help as I'm having a trouble in displaying some child pages of a particular Book in Drupal 8 using view. There's a book which displayed all the child pages but there's some book which displayed incomplete child pages and some book, doesn't display the child pages at all.

I created two views, one for the list of all top level book and the other one is for the child pages.

Here's what I have done on view settings:

**to display the list of book:**

```
Format: Unformatted list
Show: Fields
Filter Criteria:
  Content Published (=Yes)
  Content: Content type (= Services)
  Book: Depth (= 1)
Sort Criteria: Content: Title (asc)

```

**to display the child pages:**

```
Format: Unformatted list
Show: Fields
Filter Criteria: Content Published (=Yes)
Sort Criteria: Content: Title (asc)
Contextual Filters: (Book Parent) Content: ID
Relationships: Book Parent
Configure Relationship: Book Parent : Required this Relationship

```

After saving it, I added this to the block layout.

I'm not sure what went wrong on my settings.

Thank you in advance for you help!

# Answer
I'm not too experience in Drupal. But normally I would not use Views for the child pages. If the book module is enabled, the BOOK NAVIGATION block will be available to list with hierarchy like a table of content. You can select in the option to display only for book pages under a particular book. Not sure whether this helps.
> 1 votes

---
Tags: views
---


title: Where to include common scripts

text:
# Question
Title: Where to include common scripts
I am looking at adding a new javascript library to drupal 8. I want the ability to call this library from other modules / libraries.

The way WordPress does this is by the use of `wp_enqueue_scripts`. Using a common library would make sure that my library is loading just once.

An existing implementation of this in drupal is the way you can add dependencies into your the yml files

```
js:
 dependencies:
  - core/jquery

```

Is there a way I can add my own javascript library as the dependency that can be used throughout my drupal instance (all modules and themes should be able to use this as a dependency)

# Answer
To add dynamic libraries as shared libraries, check the following

hook\_library\_info\_build() for dynamic library definitions

You can add javascript libraries to a theme like the following

Adding Javascript to a D8 theme

You can add javascript libraries to a module like the following

Adding Javascript to a D8 module
> 0 votes

---
Tags: 8, theming
---


# Question
Title: How do I migrate block content from a dev to a production site?
I've finally started looking at Drupal 8 seriously and I'm particularly interested in the configuration management. I've come across something that could be a little bit problematic and that's regarding custom block content.

I can see that the configuration management system is able to export block configuration - region, theme, weight, visibility etc. however the actual block content does not come across in the config export, which is reasonable and understandable.

On importing that block config to a production site, what appears to happen is the block config is created and a holding message is put in place, reporting the block is broken or missing. Obviously the block content doesn't exist on the production server.

How can custom blocks be migrated from a dev/staging server to a production server? I realise that blocks in Drupal 8 are fieldable entities like nodes and so will need to be migrated in the same way and I understand there is a Migrate API in Drupal 8 but this appears to be built for migrating content from Drupal 6 and 7 sites to Drupal 8 as opposed to Drupal 8 to Drupal 8 sites.

This issue is specifically regarding custom blocks as blocks generated by other modules such as Views will obviously migrate across as configuration.

# Answer
Another answer I haven't seen mentioned here is to use the Simple Block module, which is pretty much identical to core's 'Custom Block' setup, but instead of having a weird hybrid of content + config, you have all the Block settings and content stored in configuration, which can be cleanly exported and imported.

See, for further discussion in Drupal 8 core: Custom blocks cannot be properly exported and imported.
> 10 votes

# Answer
I have just publish a contributed module that solves this. Essentially, the module provides a type of block based on configuration (the fixed block) that wraps a custom block (the content block). If the content block does not exist, it is created with a default content or empty if no default content was set. Everything is done through UI, no special files or custom module are needed.

I named it Fixed block content and it is published at:

https://www.drupal.org/project/fixed\_block\_content
> 6 votes

# Answer
Please have hands on the Structure Sync module.

> Structure sync provides Drush commands and admin interface screens for synchronizing content that could also be considered configuration. Including menu items, custom blocks and taxonomy terms.

Steps:

1. Go to structure sync.
2. Go to Blocks tab.
3. Export.
4. Your configurations and content will be exported in configuration folder.
5. Take the configurations to other sites & Import.
6. Go to structure sync & click on import.
7. Done
> 4 votes

# Answer
Another approach for keeping content that is added as part of development also pushed to live is to use the Default Content module to export the content. It is built for the content to be exported to an installation profile's 'content' folder, and then the module, if enabled, automatically brings the content in when the site is installed, but it's also possible to import the content one item at a time, such as in an update hook, with the below code in your example.install or example.profile:

```
<?php
/**
* Import a piece of content exported by default content module.
*/
function example_import_default_content($path_to_content_json) {
  list($entity_type_id, $filename) = explode('/', $path_to_content_json);
  $p = drupal_get_path('profile', 'guts');
  $encoded_content = file_get_contents($p . '/content/' . $path_to_content_json);
  $serializer = \Drupal::service('serializer');
  $content = $serializer->decode($encoded_content, 'hal_json');
  global $base_url;
  $url = $base_url . base_path();
  $content['_links']['type']['href'] = str_replace('http://drupal.org/', $url, $content['_links']['type']['href']);
  $contents = $serializer->encode($content, 'hal_json');
  $class = 'Drupal\\' . $entity_type_id . '\Entity\\' . str_replace(' ', '', ucwords(str_replace('_', ' ', $entity_type_id)));
  $entity = $serializer->deserialize($contents, $class, 'hal_json', array('request_method' => 'POST'));
  $entity->enforceIsNew(TRUE);
  $entity->save();
}

```

Export a custom block with an ID of 8:

```
drush dcer block_content 8

```

(If you don't set your profile path in Drush settings you'll have to specify it above.)

And use the resultant export in your example.install file like this:

```
<?php
/**
* Add the footer block content.
*
* Implements hook_update_N().
*/
function example_update_8001() {
  example_import_default_content('block_content/136efd63-021e-42ea-8202-8b97305cc07f.json');
}

```

http://data.agaric.com/easily-add-content-update-hooks-use-default-content-module-exports-create-content-needs-be-sync-conf
> 2 votes

# Answer
Having the same issue and not really a solution, only additions: In collaborative development we're using a staging server which pulls from the repository and resets all configuration. This means that block config is being reset automaticalls, you simply cannot place blocks you consider as "content" directly on that server.

It's easy to use drush config-export sync while knowing exactly what you've done and being sure that any configurations changes are meant for deploying. But Drupal decides for us that blocks are configuration (while obviously block content is handled as content). So this seems to be broken by design.

For the time given I reckon the most practical solution would be to add the block-related yml files to .gitignore.
> 1 votes

# Answer
I'm not sure I see any strong advantages of synching block configurations amongst multiple environments as blocks are so intertwined with content.

The reason for this is that there's a new block being created from the yml files that has no title/body (content) and is therefore giving the 'broken/missing' message.

You could try to make the UUID (if you wanted to make the block in both places - make sure the machine name matches...) in your development block\_content table match what uuid you have in production (the other relationships seem to use the entity id). Then, when you do a config sync you could see the 'View differences' in the yml files and possibly see what else you need to change on dev to get it to match production uuids, etc. I got this to work, but still figured it's easiest to ignore all your block configurations in code unless you go through this process or create some kind of database block sync for yourself using block\_content, block\_content\__body, and block\_content\_field\_data.

It's not very elegant but could allow you to keep your block configs in code. Otherwise, if you keep deploying blocks with config, they will always be 'broken or missing'.

Another blog post suggests creating a custom block in live environment but not placing it. After syncing the database to dev, custom block could be configured, config exported and since it already exists in live import of placement is possible.
> 0 votes

# Answer
I am not sure too, however, if you didn't find any solution you may look this module https://www.drupal.org/project/deploy. Frankly speaking, I don't remember can deploy push blocks from DEV to PROD or not.
> 0 votes

# Answer
I think the best way to handle this would be to:

This is what I usually see people using and I personally use. But it syncs the entire database as compared to only the block content.
> 0 votes

---
Tags: blocks, 8
---


# Question
Title: How to enable click-sorting for views table display based on Search API index?
I'm trying to create a view with table display based on Search API (database search) index, with column-sorting (column set as `Sortable` in the display settings). However, this option isn't available for my view fields, no matter if they are based on `string` or `fulltext` Search API fields. Is there anything I can do to enable this?

I'm using latest Drupal 8.7.x nad Search API 1.12

Edit:

It seems that availability of click-sorting is determined in `\Drupal\search_api\Plugin\views\field\SearchApiFieldTrait::clickSortable` method. The check inside that fails, because field definition array doesn't contain a `search_api field` key. So is there anything I can do to add it there?

BTW. th support for click-sorting was added in https://www.drupal.org/project/search\_api/issues/2816979. There are some SOLR-related issues mentioned, but noting related to my use-case.

# Answer
> 2 votes
As it turned out, it was my stupid mistake - search index field can be added to views (as a views field) in 2 ways, with one of them having (Indexed field) appended to the field label.

**When I added field with (Indexed field) appended, I can set that field a Sortable**.

---
Tags: views, 8, search
---


title: Error when applying patch

text:
# Question
Title: Error when applying patch
I seem to getting an error when trying to apply a patch and I'm a bit stumped on where I am going wrong if anyone knows that would be fantastic - I need to apply this patch: https://www.drupal.org/files/issues/media\_entity\_image\_thumbnail\_problem\_2767501\_13.patch

I am inside the mysite/public folder where I have placed the patch file and then try to run:

`git apply media_entity_image_thumbnail_problem_2767501_13.patch`

It doesn't seem to do anything so I then run:

```
$ patch -p0 < media_entity_image_thumbnail_problem_2767501_13.patch

can't find file to patch at input line 5
Perhaps you used the wrong -p or --strip option?
The text leading up to this was:
--------------------------
|diff --git a/src/Plugin/MediaEntity/Type/Image.php b/src/Plugin/MediaEntity/Type/Image.php
|index 09b9655..398d3c0 100644
|--- a/src/Plugin/MediaEntity/Type/Image.php
|+++ b/src/Plugin/MediaEntity/Type/Image.php
--------------------------
File to patch:

```

it seems to have an isssue with: `@@ -7,6 +7,7 @@ use Drupal\Core\Datetime\DrupalDateTime;` should I be placing the patch file somewhere else?

# Answer
Yes. The patch needs to be placed inside the `media_entity_image` folder alongside the `media_entity_image.info.yml` file. And then you should be able to execute

```
patch -p0 < media_entity_image_thumbnail_problem_2767501_13.patch

```

without any issue.

**If you are using composer-** I would highly encourage you to use the `cweagans/composer-patches` composer package. Details at https://groups.drupal.org/node/518975
> 0 votes

---
Tags: 8
---


# Question
Title: Create a custom blocks visibility tab (show on certain domain only)
I want to show a block only on a certain domain. I know I can use the *domain access* module for this but this looks like a to heavy module for my use case. How can a create a custom visibility tab for blocks?

I tried looking at other modules doing this but most of the time they are to complex for me to understand and filter out the right code to make it my own.

Can someone point me in the right direction? Is there a simple module I can look at to understand how this works? Or maybe a snippet of code?

---

Following up on the great answer of 4k4: I used the not node type module to work on my own, not perfect yet but already working for 90%.

```
<?php

namespace Drupal\block_visibility_conditions\Plugin\Condition;

use Drupal\Core\Condition\ConditionPluginBase;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Routing\CurrentRouteMatch;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Provides a 'Domain Name' condition. The block will still be shown on all
 * other pages, including non-content types. This differs from the negated
 * condition "Content types", which will only be evaluated on node pages, which
 * means the block won't be shown on other pages like views.
 *
 * @Condition(
 *   id = "domain_name",
 *   label = @Translation("Domain Name")
 * )
 */
class DomainName extends ConditionPluginBase implements ContainerFactoryPluginInterface {

  /**
   * The EntityTypeManager object.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * The CurrentRouteMatch object.
   *
   * @var CurrentRouteMatch
   */
  protected $routeMatch;

  /**
   * Creates a new DomainName instance.
   *
   * @param array $configuration
   *   The plugin configuration, i.e. an array with configuration values keyed
   *   by configuration option name. The special key 'context' may be used to
   *   initialize the defined contexts by setting it to an array of context
   *   values keyed by context names.
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param CurrentRouteMatch $route_match
   *   The route match.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, CurrentRouteMatch $route_match) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->entityTypeManager = $entity_type_manager;
    $this->routeMatch = $route_match;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('entity_type.manager'),
      $container->get('current_route_match')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $form = parent::buildConfigurationForm($form, $form_state);

    // Disallow negation of this condition.
    //unset($form['negate']);

    $form['domains'] = [
      '#type' => 'textarea',
      '#title' => $this->t('Domain'),
      '#rows' => 3,
      '#description' => $this->t('Add domain name without www. or https://. Separate multiple domains by a comma.'),
      '#wysiwyg' => FALSE,
      '#default_value' => implode(', ', $this->configuration['domains']),
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
    $domainList = explode(',',$form_state->getValue('domains'));
    $this->configuration['domains'] = array_filter($domainList);
    parent::submitConfigurationForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function summary() {
    if (count($this->configuration['domains']) > 1) {
      $domains = $this->configuration['domains'];
      $last = array_pop($domains);
      $domains = implode(', ', $domains);
      return $this->t('The domain is @domains or @last', [
        '@domains' => $domains,
        '@last' => $last,
      ]);
    }
    $bundle = reset($this->configuration['domains']);
    return $this->t('The domain is @bundle', ['@bundle' => $bundle]);
  }

  /**
   * {@inheritdoc}
   */
  public function evaluate() {
    // Check if a setting has been set.
    if (empty($this->configuration['domains'])) {
      return TRUE;
    }

    //fetch host
    $host = \Drupal::request()->getHost();

    //if current domain is in domains array
    if($this->configuration['negate'] === false) {
      if (in_array($host, $this->configuration['domains'])) {
        return TRUE;
      }
      else {
        return FALSE;
      }
    }
    else{
      if (in_array($host, $this->configuration['domains'])) {
        return FALSE;
      }
      else {
        return TRUE;
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration() {
    return ['domains' => []] + parent::defaultConfiguration();
  }
}

```

# Answer
> 3 votes
You need a condition plugin like RequestPath checking the host name in evaluate():

```
$request->getHost()

```

and set in getCacheContexts() a context for "per site" caching:

```
public function getCacheContexts() {
  $contexts = parent::getCacheContexts();
  $contexts[] = 'url.site';
  return $contexts;
}

```

This is a very simple module containing only one PHP file, see for example https://git.drupalcode.org/project/block\_visibility\_conditions/-/blob/8.x-1.0-beta4/src/Plugin/Condition/NotNodeType.php

---
Tags: 8, blocks
---


# Question
Title: How can I programmatically load and display all available blocks?
```
$block = Drupal\block\Entity\Block::load($block_id);
ksm($block);

```

This code loads only one specific block. But how can I load and display **all** available blocks?

# Answer
> 6 votes
Using the service plugin.manager.block we will get all blocks available definition.

```
$blockManager = \Drupal::service('plugin.manager.block');

$contextRepository = \Drupal::service('context.repository');

// Get blocks definition

$definitions = $blockManager->getDefinitionsForContexts($contextRepository->getAvailableContexts());

```

To get details about one specific block you can use below code.

```
print_r($definitions['help_block']);

```

# Answer
> 3 votes
Try this:

```
$blocks = Drupal\block\Entity\Block::loadMultiple();
ksm($blocks);

```

# Answer
> 1 votes
The core block module using "getFilteredDefinitions" method to list the blocks

```
$blockManager = \Drupal::service('plugin.manager.block');
$contextRepository = \Drupal::service('context.repository');

// Get blocks definition
$definitions = $blockManager->getFilteredDefinitions('block_ui', $contextRepository->getAvailableContexts());

print_r($definitions);

```

# Answer
> -2 votes
```
$query = \Drupal::entityQuery('block_content');
$ids  = $query->execute();

```

You can also use 'block' instead of 'block\_content' to get blocks from code

---
Tags: 8, blocks
---


# Question
Title: Add inline styles/JS from fields to <head>
My site contains nodes which require different styles (and the occasional inline JS script) and the ability to adjust these styles through the interface rather than via code. These styles are currently implemented via a Code-only text field using `<style>` tags, which is not ideal. However for systemic reasons I can't place these node-specific styles in individual libraries.

How can I extract the contents of specific code-only fields and reposition this content as inline styles in the `<head>` of the page? I understand that this is not the preferred Drupal way, however I need a solution.

# Answer
> 0 votes
You could do this with a preprocess function. The code here works for full views only (it won't work e.g. in a view of multiple teaser nodes).

```
function THEME_preprocess_html(array &$variables) {
  $router = \Drupal::routeMatch();
  $node = $router->getParameter('node');
  if (is_numeric($node)) {
    $node = \Drupal\node\Entity\Node::load($node);
  }
  if ($node instanceof \Drupal\node\NodeInterface) {
    $variables['node_object'] = $node;
  }
}

```

Now you can use `{{ node_object }}` in your html.twig.twig, e.g.:

```
<html>
<head>
  {% if node_object %}
    {% if not node_object.field_css.isEmpty %}
      <style>
        {{ node_object.field_css.value|raw }}
      </style>
    {% endif %}
    {% if not node_object.field_js.isEmpty %}
      <script>
        {{ node_object.field_js.value|raw }}
      </script>
    {% endif %}
  {% endif %}
  ...

```

And yes... don't try this at home kids ;-P

---
Tags: 8, theming
---


# Question
Title: How can I programmatically distinguish if a block is enabled or disabled from block layout?
I have 2 custom blocks. I have added both this in regions of block layout. But when i disabled the block from layout. I must identify it from code or api that the particular block is disabled. How to know that?

# Answer
Use BlockContent::getInstances to get all blocks placed for this custom block, then check for each block instance if it is enabled with `$block->status()`.

See Get block programmatically and How can we check whether block is enabled or disabled in .theme file?
> 4 votes

---
Tags: 8, blocks
---


# Question
Title: DDEV php/twig error "Unknown "link_attributes" filter."
So I'm trying to setup a local environment with ddev for the first time. I got it running, cloned my live files with git and imported my DB.

Site ain't working and got this in the log : "PHP message: Uncaught PHP Exception Twig\Error\SyntaxError: "Unknown "link\_attributes" filter." at /var/www/html/web/themes/customs/myTheme/templates/menu--main.html.twig

Any pointer how to fix that ? I did :

> ddev exec drush en link\_attributes
>
> -\> \[notice\] Already enabled: link\_attributes

This site with the same file/db is working on 2 VPS. What's going on ?

# Answer
> 0 votes
It was an module identification problem. I thought it was the link\_attributes modules but the error is from twig\_link\_attributes. That one didn't download cause it's a git submodule or something... Anyway that folder is empty.

---
Tags: 8
---


title: Editing classes on a div in CKEditor

text:
# Question
Title: Editing classes on a div in CKEditor
We are using the ckeditor\_div\_manager module on our Drupal 8 site to provide the Div Manager plugin on our CKEditor.

On of my content editors reports that, while it does allow her to add a wrapper div that has our pre-defined classes onto elements, there is no way with the widgets to edit existing divs to remove the class, or remove the div altogether. She has to go into the source and 'manually' pick out the wrapping div tags.

The only operation that this plugin/module provides is to add a new wrapping div; it explicitly says so in its dialog: "Create Div Container". When I click on an existing div in the editor, and click the widget icon, it's the same dialog, "Create Div Container", and it wraps a new div around the div I've selected. It doesn't provide editing options.

I looked around, and I didn't find anything specifically for this situation.

Is there a way I can configure our site so that our content editors can edit classes on divs, or delete wrapping divs, via the WYSIWYG, without editing the source?

# Answer
Okay, I found out at least one way to edit and remove divs. We have a "Show Blocks" widget (not sure if that's stock or what).

This causes outlines to show for block elements:

Hover over the div, and then right-click to get a menu with edit and remove:
> 1 votes

---
Tags: wysiwyg
---


title: How to get the media that owns a file?

text:
# Question
Title: How to get the media that owns a file?
I have a file and I know there is a media that references it. How can I get this media?

In the opposite direction, knowing the media id, I can get the file:

```
$media = Media::load($mid);
$fid = $media->field_media_image->target_id;
$file = File::load($fid);

```

But now I know the file id and I want the media. How can I get it?

# Answer
You can use `entityQuery`:

```
$fid = 13141;
$usedIn = \Drupal::entityQuery('media')
  ->condition('field_media_image.target_id', $fid)
  ->execute();

```

Example response:

```
Array
(
    [15105] => 13109
)

```
> 4 votes

---
Tags: 8, media, files
---


# Question
Title: Disable cache a custom block for anonymous user
I have a custom block, it displays in every pages with dynamic data calculates in every refresh, How can I disable cache for this block for anonymous users?

I try with:

```
public function build() {
  return [
    '#markup' => time(),
    '#cache' => [
      'max-age' => 0,
    ],
  ];
}

```

It won't work.

**Edit:** I don't want to disable the cache for the entire page, I just need a specific block not to be cache.

# Answer
If you want to completely disable caching for the block, use this function in your block class:

```
  public function getCacheMaxAge() {
    return 0;
  }

```

I've never found in the documentation why

```
'#cache' => [
      'max-age' => 0,
    ],

```

doesn't work with blocks but, like you discovered, it doesn't seem to.
> 0 votes

---
Tags: 8, caching
---


# Question
Title: How to affect kernel request hostname when bootstrapping from custom PHP script
I'm bootstraping from a custom PHP script using:

```
$autoloader = require_once 'web/autoload.php';
$request = Request::create('/');
// $_SERVER['SERVER_NAME'] = 'whatever';
// $request->server->set('SERVER_NAME', 'whatever');
$this->kernel = DrupalKernel::createFromRequest($request, $autoloader, 'prod');
$this->kernel->boot();
$this->kernel->prepareLegacyRequest($request);

```

When rendering a URL from that bootstrapped Drupal, via `$item->link->getUrlObject()->toString()`, it has a `localhost` hostname:

```
http://localhost/sites/default/files/styles/large/public/images/pages/1.JPG?itok=gSuAsMq-

```

I want to change that to `whatever` and I've tried what is commented out in the initial block which doesn't work. I've confirmed that the `$request->server->set(..., ...);` does set the value though.

Any idea on how to solve this?

# Answer
> 2 votes
You need to use the `HTTP_HOST` instead the `SERVER_NAME`, also you can pass it as `$server` param to the `Request::create()`

```
$autoloader = require_once 'web/autoload.php';
$request = Request::create('/', 'GET', [], [], [], ["HTTP_HOST" => 'whatever']);
$this->kernel = DrupalKernel::createFromRequest($request, $autoloader, 'prod');
$this->kernel->boot();
$this->kernel->prepareLegacyRequest($request);

```

Remember to add the hostname to `$settings['trusted_host_patterns']`

---
Tags: 8, bootstrapping
---


title: Database API and Security

text:
# Question
Title: Database API and Security
I'm working on a controller that queries a table based on the value in a route parameter

Example route path:

```
path: '/path/{parameter}'

```

Controller:

```
  public function myFunction($parameter) {
    $connection = \Drupal::database();
    $query = $connection->select('my_custom_table', 'mct');
    $query->condition('mct.col', $parameter, '=');
    ...
    $result = $query->execute();
    $records = $result->fetchAll();

```

Is there any sanitization that should occur in this circumstance or does the database API take care of this?

# Answer
> 3 votes
For input, saving to the DB, Database API takes care of it, automatically prevents SQL injection **when using dynamic query**. Since your code is using dynamic query, you're all good.

If you were to use **static query** you have to make sure you use placeholders as the docs mention.

For output, to prevent XSS, you'll want to use a template file, and print your value via Twig. Which auto escapes everything by default. If you don't use Twig, then you need to use the appropriate API function.

---
Tags: database
---


# Question
Title: Drush disable module updates email notifications
Is there a Drush command to disable email notifications about Module updates.

# Answer
You can turn off just the email notify feature like this:

```
drush vdel update_notify_emails

```

(See in update.fetch.inc: `$notify_list = variable_get('update_notify_emails', '');`)

You might also want to consider the following alternative:

```
drush pm-disable update

```

This will completely disable the update module on your live server, which will also disable email notifications about Module updates. At first blush, you might be sad that you won't be able to see the module updates page on your live server any more; however, you should really be doing your updating on a development machine anyway, so you can just re-enable update on the dev server.

To automatically re-enable the update module every time you sql-sync from live to dev, see symc\_enable.drush.inc.

Finally, to insure that your *dev* machine does not send out unwanted email notifications, enable the devel module, and then add to your settings.php file:

```
$conf['mail_system'] = array(
  'default-system' => 'DevelMailLog',
);
$conf['devel_debug_mail_directory'] = '/path/to/dir/to/save/email';

```

Then, devel will intercept all email that is sent and write it into the target directory instead of emailing it.
> 8 votes

# Answer
No, unless you installed a module that provides functionality to disable email notifications about Module updates, and drush command to switch it (or at least configuration in variable that can be easily changed with drush).

There is no such option in Drupal Core as far as I can remember.
> 2 votes

# Answer
This is an old post, but I just had to set this up for our devops for Drupal 8. @Clive is correct, you can disable by removing email addresses in /admin/reports/updates/settings. There can be more than one, and I wanted to make sure to remove them all. It is not obvious how to set an empty array using config-set, so I used php-eval.

```
drush php-eval '\Drupal::service("config.factory")
                ->getEditable("update.settings")
                ->set("notification.emails", [])
                ->save();'

```
> 2 votes

---
Tags: drush
---


# Question
Title: Is it possible to have pre-load elements in webforms?
I have to add two elements (checkbox, texfield) in the creation process of the webform. This is because I want a simple terms and conditions inside all webforms. How can I do this?

# Answer
> 3 votes
You could pre-load the elements in a hook\_ENTITY\_TYPE\_create hook:

*mymodule.module:*

```
  /**
   * Implements hook_ENTITY_TYPE_create() for webform entities.
   */
  function mymodule_webform_create(\Drupal\webform\WebformInterface $webform) {

    $elements = [
      'name' => [
        '#type' => 'textfield',
        '#title' => 'name',
      ],
      'other' => [
        '#type' => 'textfield',
        '#title' => 'other',
      ],
    ];

    $webform->setElements($elements);
  }

```

# Answer
> 0 votes
Webforms now has a "prepopulate" option for most fields. Use the URL query string to populate a field that has been enabled for prepopulation

---
Tags: 8, forms, webforms
---


# Question
Title: Field Formatter Class and limit number of characters
I have to insert in a field (admin/structure/types/manage/article/display) a string of classes to get a button from a text but the "Field Formatter Class" field has a character limit so I can't enter the code which I need to get the result. I did some research but couldn't find the solution.

My Class: btn btn-sm btn-primary stpe-outlinebutton test-util-color-primary test-util-border-primary test-util-hover-background-primary test-util-hover-color-white test-util-hover-border-primary

Any help?

Best Regards

# Answer
I believe you are using the module Field Formatter Class to have this option for your fields.

The module does not set a maximum value for this field. So I believe it is using a default of 128 chars in core.

128 is a fairly long limit for a class field. But if you want to alter this you can write an alter function in your module like they have done in their module and set the #maxlength property of the field\_formatter\_class element.

Having said that, the following is a quick hack to get this working for you.

You can open the file `field_formatter_class/field_formatter_class.module`

and add a line

```
'#maxlength' => 256,

```

in the element class array in the alter function in line 44. After modification this will be like the following (view original code)

```
function field_formatter_class_field_formatter_settings_form_alter(&$settings_form, $context) {
  $display = $context['instance']['display'][$context['view_mode']];
  $settings = $display['settings'];
  $settings_form['field_formatter_class'] = array(
    '#type' => 'textfield',
    '#title' => t('Field Formatter Class'),
    '#maxlength' => 256,
    '#default_value' => $settings['field_formatter_class'],
  );

```

Do note that this is modifying a contrib module and is generally not a recommended approach. You will have to maintain this patch in a patches folder.
> 0 votes

---
Tags: theming
---


# Question
Title: Encode Forward Slash with &#x2F in Text area drupal 7 form
I am facing issue in Encoding forward slash with &#x2F in my custom drupal 7 form. I have a text area field with name "Address", i am using check\_plain for encode special characters, All HTML related tags are getting encoded, but i want to encode forward slash(/) as well.

Any suggestions?

# Answer
You can use something like the following to convert all characters you want to convert into their corresponding HTML entity version. I have added a check on converting only non alpha-numeric characters into HTML entities. You can add a different logic to convert only those characters you want to convert (in the if condition with ctype\_alum)

The following is adapted from the answer here

```
function encode($str) {
  $str = mb_convert_encoding($str , 'UTF-32', 'UTF-8'); //big endian
  $split = str_split($str, 4);

  $res = "";
  $pos = 0;
  foreach ($split as $c) {
    // Check if the character is alpha numeric and
    // if not, convert to HTML entity.
    if (!ctype_alnum ($str[$pos])) {
      $cur = 0;
      for ($i = 0; $i < 4; $i++) {
        $cur |= ord($c[$i]) << (8*(3 - $i));
      }
      $res .= "&#" . $cur . ";";
    }
    else {
      $res .= $str[$pos];
    }
    $pos++;
  }
  return $res;
}

```
> 1 votes

---
Tags: forms
---


title: If statements in twig

text:
# Question
Title: If statements in twig
I've got the following card in my drupal installation, I've hidden unnecessary items for my question in the picture.

What I want to achieve is the following: I want the icon to change based on the taxonomy term showed besides the little icon (in this case, test).

This is the code that generates the card:

```
{% if topic_type %}
  {% embed "node--teaser__field.html.twig" %}
    {%- block field_icon -%} group {%- endblock -%}
    {%- block field_value -%} {{ topic_type }} {%- endblock -%}
  {% endembed %}
{% endif %}

```

I think it should look something like this but it gives me an error:

```
{% if topic_type %}
  {% embed "node--teaser__field.html.twig" %}
    {% if topic_type == 'test' %}
      {%- block field_icon -%} icon 1 {%- endblock -%}
    {% else %}
      {%- block field_icon -%} icon 2 {%- endblock -%}
    {% endif%}
    {%- block field_value -%} {{ topic_type }} {%- endblock -%}
  {% endembed %}
{% endif %}

```

# Answer
> 0 votes
Twig blocks are named control structures, you can't define them multiple times within the same scope. Either try to move the `if` statement inside one single block

```
{% if topic_type %}
  {% embed "node--teaser__field.html.twig" %}
    {%- block field_icon -%}
      {% if topic_type == 'test' %}
        icon 1
      {% else %}
        icon 2
      {% endif%}
    {%- endblock -%}
    {%- block field_value -%} {{ topic_type }} {%- endblock -%}
  {% endembed %}
{% endif %}

```

or don't overwrite the block at all, instead use variables and pass them down in the embed statement

```
{% set custom_icon = (topic_type == 'test' ? 'icon1' : 'icon2') %}
{% embed "node--teaser__field.html.twig" with {'icon': custom_icon, 'title': topic_type } %}

```

I'd recommend the first when there are major overwrites in the HTML output, and the 2nd when only strings/variables/placeholders are replaced.

---
Tags: 8, theming
---


title: Override a function in a contrib module

text:
# Question
Title: Override a function in a contrib module
My company received a maintenance contract for a website developed in Drupal 7. The Drupal 7 website uses the Quiz contrib module, ver. 7.x-4.0-rc10. The module is used to implement a feature where authenticated users answer questions to tests.

When an authenticated user completes the test and views his result, the following notice errors are displayed on the results page,

* Notice: Undefined index: nid in quiz\_take\_quiz() (line 2078 of C:\wamp64\www\\........\modules\contrib\quiz\quiz.module).
* Notice: Undefined index: vid in quiz\_take\_quiz() (line 2078 of C:\wamp64\www\\........\modules\contrib\quiz\quiz.module).
* Notice: Trying to get property 'type' of non-object in quiz\_take\_quiz() (line 2082 of C:\wamp64\www\\........\modules\contrib\quiz\quiz.module).
* Notice: Undefined index: in quiz\_take\_quiz() (line 2082 of C:\wamp64\www\\........\modules\contrib\quiz\quiz.module).
* Notice: Trying to get property 'is\_valid' of non-object in quiz\_take\_quiz() (line 2084 of C:\wamp64\www\\........\modules\contrib\quiz\quiz.module).

The Quiz module has a function, `quiz_take_quiz($quiz)`.

As part of contract signed by my company, I have to resolve all notices. Therefore, what I intend to do is override this function and modify the exact line which is responsible for throwing the above notices (line no. 2078) and add a variable validation there.

However being a newbie to Drupal development I don't know where to start and what to do. I do know that modifying the code in a contrib module is not the best practice. I have hidden the path to the .module file with ........ to maintain privacy.

Can anyone please provide me the solution to this?

# Answer
After going through all of your replies and a few internal discussions in my company, I have decided to modify the Quiz module's code by creating and applying a patch, `quiz_notice_messages_in_result_screen.patch`.

As per the information provided by Alfred Armstrong's the said patch will be solely used for our company's internal purposes, so as to find a way around the Drupal's general practice of reporting a contrib module's issues and suggesting patches for the same.

Below are the contents of the `quiz_notice_messages_in_result_screen.patch` file.

```
diff --git a/modules/contrib/quiz/quiz.module b/modules/contrib/quiz/quiz.module
index dd2b88c..e551aac 100644
--- a/modules/contrib/quiz/quiz.module
+++ b/modules/contrib/quiz/quiz.module
@@ -2075,13 +2075,19 @@ function quiz_take_quiz($quiz) {
     $_SESSION['quiz_' . $quiz->nid]['quiz_questions'][0]['rid'] = $_SESSION['quiz_' . $quiz->nid]['result_id'];
     $_SESSION['quiz_' . $quiz->nid]['previous_quiz_questions'][] = $_SESSION['quiz_' . $quiz->nid]['quiz_questions'][0];
     $former_question_array = array_shift($_SESSION['quiz_' . $quiz->nid]['quiz_questions']);
+    if (empty($former_question_array['nid']) || empty($former_question_array['vid'])) {
+      $former_question_array['nid'] = $quiz->nid;
+      $former_question_array['vid'] = $quiz->vid;
+    }
     $former_question = node_load($former_question_array['nid'], $former_question_array['vid']);

     // Call hook_evaluate_question().
     $types = _quiz_get_question_types();
-    $module = $types[$former_question->type]['module'];
+    $module = empty($types[$former_question->type]['module']) ? '' : $types[$former_question->type]['module'];
     $result = module_invoke($module, 'evaluate_question', $former_question, $_SESSION['quiz_' . $quiz->nid]['result_id']);
-    $q_passed_validation = $result->is_valid;
+    if(isset($result->is_valid)) {
+      $q_passed_validation = $result->is_valid;
+    }
     $check_jump = TRUE;
     if ($q_passed_validation === TRUE) {
       quiz_store_question_result($quiz, $result, array('set_msg' => TRUE, 'question_data' => $former_question_array));

```

Thank you No Sssweat, Alfred Armstrong and Alan Dixon for your inputs.
> 1 votes

# Answer
I think the assumption in your answer "I do know that modifying the code in a contrib module is not the best practice" is incorrect in this case, even though it's true in general.

If all you want to do is fix the notices, then just fork the project and even pull in the upstream patches that fix these notices.

The issues you note are almost certainly easy to fix and just related to php versions.

Most importantly: your question demonstrates why clients should not be hiring non-Drupal shops to do maintenance on their Drupal sites.
> 0 votes

---
Tags: 7
---


# Question
Title: The provided host name is not valid for this server
I'm trying to migrate a drupal website from a server into my localhost but I trigger the error

> The provided host name is not valid for this server.

I've seen I need to add the trusted host pattern, but looks like this is not working I still get the error

My server is run on port 9000

```
sudo php -S 127.0.0.1:9000

```

My trusted hosts, and I've no Vhost

```
$settings['trusted_host_patterns'] = array(
  '^serverStuffWeDontMind$',
  '^localhost\:9000$',
);

```

# Answer
If this is a dev - env, simply add

```
$settings['trusted_host_patterns'] = [$_SERVER['SERVER_NAME']];

```

But never do this in production.
> 1 votes

---
Tags: 8, installation
---


# Question
Title: How Update item on the second page in WebForm wizard
I am starting to work with webform in drupal 8 and I need to show values on the second page of the webform wizard, I have reviewed several solutions but I cannot do it. I tried using $ form\_state-\> setValue

```
function webform_certificadoemail_webform_element_alter(array &$element, FormStateInterface $form_state, array $context) {

  if ($form_state->get('current_page') == 'preview') {

    $value_entered = $form_state->getValue('nombre');
    drupal_set_message('Valor del nombre en el preview =:'.$value_entered);

     $form_state->setValue('valor','This value is .......'); // This not work
  }
}

```

# Answer
When you are in the preview page, you're too late then.

You need to set this in your previous step in a validate function

```
function webform_certificadoemail_webform_element_alter(array &$element, FormStateInterface $form_state, array $context) {

   if ($form_state->get('current_page') == 'step_1') { // or whatever you called the first page
     $element['#element_validate'][] = 'webform_certificadoemail_set_valor';
  }

}

function webform_certificadoemail_set_valor($element, FormStateInterface $form_state) {
   $form_state->setValue('valor','This value is .......');
}

```
> 1 votes

---
Tags: 8, webforms
---