title: Migrate geolocation field

text:
# Question
Title: Migrate geolocation field
I have gone through the /upgrade gui part on my website. However the geo location fields have not copied across.

Am I correct in thinking that instead of manually entering the data again, I could:

1. Create the field (same name) and add it to the content types I was using.
2. Export the field\_data\_field\_location
3. Import both these fields into the Drupal 8 database as field\_revision\_field\_location respectively?

As far I can see the tables are pretty similar, although there are same number of fields 2 of them are different.

* The D7 Table has a field entity\_type
* The D8 Table has field\_location\_data

I will attach the schema for both tables.

D7:

```
+------------------------+------------------+------+-----+---------+-------+
| Field                  | Type             | Null | Key | Default | Extra |
+------------------------+------------------+------+-----+---------+-------+
| entity_type            | varchar(128)     | NO   | PRI |         |       |
| bundle                 | varchar(128)     | NO   | MUL |         |       |
| deleted                | tinyint(4)       | NO   | PRI | 0       |       |
| entity_id              | int(10) unsigned | NO   | PRI | NULL    |       |
| revision_id            | int(10) unsigned | YES  | MUL | NULL    |       |
| language               | varchar(32)      | NO   | PRI |         |       |
| delta                  | int(10) unsigned | NO   | PRI | NULL    |       |
| field_location_lat     | double           | NO   | MUL | 0       |       |
| field_location_lng     | double           | NO   | MUL | 0       |       |
| field_location_lat_sin | double           | NO   |     | 0       |       |
| field_location_lat_cos | double           | NO   |     | 0       |       |
| field_location_lng_rad | double           | NO   |     | 0       |       |
+------------------------+------------------+------+-----+---------+-------+

```

D8:

```
+------------------------+------------------+------+-----+---------+-------+
| Field                  | Type             | Null | Key | Default | Extra |
+------------------------+------------------+------+-----+---------+-------+
| bundle                 | varchar(128)     | NO   | MUL |         |       |
| deleted                | tinyint(4)       | NO   | PRI | 0       |       |
| entity_id              | int(10) unsigned | NO   | PRI | NULL    |       |
| revision_id            | int(10) unsigned | NO   | MUL | NULL    |       |
| langcode               | varchar(32)      | NO   | PRI |         |       |
| delta                  | int(10) unsigned | NO   | PRI | NULL    |       |
| field_location_lat     | double           | YES  | MUL | NULL    |       |
| field_location_lng     | double           | YES  | MUL | NULL    |       |
| field_location_lat_sin | double           | YES  |     | NULL    |       |
| field_location_lat_cos | double           | YES  |     | NULL    |       |
| field_location_lng_rad | double           | YES  |     | NULL    |       |
| field_location_data    | longblob         | YES  |     | NULL    |       |
+------------------------+------------------+------+-----+---------+-------+

```

All help and advice appreicated!

Mark.

# Answer
> 0 votes
Turns out I was using the wrong version of geolocation. If you use the 8.x-1.11 when you run the upgrade script it pull over the geolocation data into your system. Although this isn't the default that composer installed for me, I had to re-install it.

Hope it helps someone out there,

Mark.

---
Tags: 8, migrations
---


# Question
Title: Uncaught PHP Exception InvalidAgrumentException: the uri is invalid
I am getting an error related The URI '/photo-gallery' is invalid. You must use a valid URI scheme at /core/lib/Drupal/Core/Url.php line 280

# Answer
You can use the `internal` scheme to make a valid URI from an internal route. e.g.

```
internal:/photo-gallery

```
> 2 votes

# Answer
You can also get this error if you are providing a URL to a Link field that is external but not providing an http/https:// value, like this:

"www.google.com/foo/bar"

The field validation will prevent this from being entered, but if you are doing content migrations or any scripted imports they can still get in.
> 2 votes

---
Tags: 8
---


# Question
Title: CSS and JS 404 On Admin Site Only - New Install
This is a new server build...

```
me@server:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.3 LTS
Release:    18.04
Codename:   bionic

```

Apache...

```
me@server:~$ apache2 -v
Server version: Apache/2.4.29 (Ubuntu)
Server built:   2019-09-16T12:58:48

```

I downloaded the `Drupal 8.7.8 tar.gz` and installed using the `Standard` installation profile into an Apache `VirtualHost`. The visitor portion of the site displays and functions as expected, however the admin portion has issues. The main page, /admin, displays styled. However, clicking on the various links, Content, Structure, Appearance, etc, result in a page with no style. Inspect's Network tab shows...

```
http://my.server/admin/sites/default/files/css/css_<snip-long-random-string>.css?0
...
http://my.server/admin/core/assets/vendor/modernizr/modernizr.min.js?v=3.3.1
http://my.server/admin/sites/default/files/js/js_<snip-long-random-string>.js
...

```

Still in Inspect on the Network tab, the CSS files show a Status of "`(cancelled)`" and the JS files are all `404`.

Maybe I have something wrong with URL rewriting. During installation in the "Requirements review" I received the warning about clean URLs - the server is capable but not enabled. Well, `mod_rewrite` is enabled and I have the following in my `VirtualHost` config...

```
RewriteEngine on
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?q=$1 [L,QSA]

```

With setting `RewriteEngine off` the visitor site only partially works. For example, the contact form is 404 while search works but has no CSS.

All other prerequisites passed.

I removed the whole Drupal filesystem and dropped the database. Another new installation yields the same results. Further suggesting that this is an Apache config issue.

Your time and help in resolving this is appreciated, thank you.

== Edit ==
The more I investigate the more I feel this is `rewrite` related. I moved all of the Rewrite statements into the top `<Directory>` and the site, visitor and admin, is 100% broken and I now receive the following in Apache's error log...

```
AH00124: Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace.
AH00121: r->uri = /index.php
AH00122: redirected from r->uri = /index.php

```

The last entry is repeated a number of times. I have `LogLevel debug`.

I understand the result but I'm not sure what the Rewrite statements should be and where they belong. My \[current\] vhost...

```
<VirtualHost *:80>
    ServerName [redacted]
    DocumentRoot /var/www/html/test
    <Directory /var/www/html/test>
            Require all granted
            RewriteEngine on
            RewriteBase /
            RewriteOptions inherit
            RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
            RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
            RewriteRule ^(.*)$ /index.php?q=$1 [L,QSA]
    </Directory>
</VirtualHost>

```

# Answer
Don't forget `AllowOverride All` if your Apache is defaulted to `AllowOverride None`. The missing directive was prohibiting rewriting from working \[properly?\] since I had, lastly, moved the rules to .htaccess (where they are in a default installation). Added it to the "main" `<Directory>` in my `<VirtualHost>` and all is well.
> 2 votes

---
Tags: 8, theming, javascript, css-js-aggregation
---


title: How do I print out a embed video?

text:
# Question
Title: How do I print out a embed video?
I have a paragraph which can either contain an image or a video. When I let the output just come out in `{{item.content}}` the actual youtube iframe is output. However when I start parsing things to detect if a video or image is there I seem to lose this functionality.

I can still manually grab the URL output. However, Drupal seems to have some inbuilt features that I'd like to preserve. For example, the Youtube link ends with *watch?* which Drupal knows to convert to *embed?*, otherwise Youtube will refuse the iframe connection.

This is what I'm currently doing.

```
{% for item in items %}
    <div class="leftItem">
        <h4>{{ item.content['#paragraph'].field_content_2_headline.value }}</h4>
        <p>{{ item.content['#paragraph'].field_content_2_content.value|raw }}</p>
    </div>
    <div class="rightItem">
        {% if item.content['#paragraph'].field_content_2_media.0.entity.field_media_oembed_video is not empty%}
            {{  item.content['#paragraph'].field_content_2_media.0.entity.field_media_oembed_video.value }}
        {% else %}
            {% for list in item.content['#paragraph'].field_content_2_media.0.entity.field_media_image_1 %}
                <img src="{{ file_url(list.entity.fileuri) }}" alt="{{ list.value.alt }}">
            {% endfor %}
        {% endif %}
    </div>
{% endfor %}

```

If I just output `item.content['#paragraph'].field_content_2_media` when there's a video detected, I get an error that I'm trying to print a field list item.

Is there a way to reference the iframe functionality that Drupal seems to have?

# Answer
> 3 votes
Use field formatters instead of printing raw values. With Twig Tweak module it can be done as follows:

```
{{ item.content['#paragraph'].field_content_2_media|view }}

```

# Answer
> 0 votes
this one works for me. https://www.drupal.org/project/embed

Set your providers after adding the field

---
Tags: theming
---


# Question
Title: InvalidArgumentException: The specified translation (fr) cannot be removed
Configurations:

```
"drupal/core": "8.4.3",
"acquia/blt": "8.9.10",
"acquia/lightning": "2.2.5",

```

I am trying to run migration of workbench moderation to content moderation on drupal core version 8.4.3, Install that module `wbm2cm` and run below the commands,

```
$ drush wbm2cm-save
$ drush wbm2cm-clear
$ drush pm-uninstall workbench_moderation
$ drush en content_moderation
$ drush wbm2cm-restore

```

After run `drush wbm2cm-restore` getting the error:

> InvalidArgumentException: The specified translation (fr) cannot be removed. in Drupal\Core\Entity\ContentEntityBase-\>removeTranslation() (line 901 of /var/www/cgicom/docroot/core/lib/Drupal/Core/Entity/ContentEntityBase.php). The specified translation (fr) cannot be removed. (/var/www/cgicom/docroot/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php:805)

My References: https://atendesigngroup.com/blog/fixing-invalid-translations-drupal-8-content-moderation https://www.drupal.org/project/entity\_clone/issues/2984049

Here I am not getting the solutions. Please can anyone suggest me?

# Answer
"#3" patch file is working to me! https://www.drupal.org/files/issues/2019-03-26/3043535-no-failure-deleting-multiple-translations-3.patch

Please refer: https://www.drupal.org/project/drupal/issues/3043535
> 1 votes

---
Tags: drush
---


# Question
Title: How to render a node with absolute URL to use in a mail?
I have to send node content by mail using an API. I manage to load and render the content to use it with my API class, and to send it. But when Drupal render the node, all URLs and image SRC are relatives, and it can't be used in a mail.

Here is the code I got so far

```
$node = \Drupal::entityTypeManager()->getStorage('node')->load($test_node); // $test_node is a (integer) NID
$renderBuilder = \Drupal::entityTypeManager()->getViewBuilder('node');
$node_view = $renderBuilder->view($node, $view_mode); // $view_mode is define in my admin settings
$html = \Drupal::service('renderer')->render($node_view); // I also tried renderRoot and renderPlain
dump($html); // URLs are relatives
exit;

```

I really search for days now, and I cannot figure how to tell Drupal Renderer to use absolute URL to generate the HTML string.

# Answer
> 3 votes
Two possible approaches:

1. Find the URLs in preprocess targeting this specific view mode and apply setAbsolute(), see for example How do I render the absolute URL of a referenced entity in a simplenews newsletter?
2. Apply a regex on the rendered output $html or use Html::transformRootRelativeUrlsToAbsolute() like added recently to the core MailManager:

```
$html = Markup::create(Html::transformRootRelativeUrlsToAbsolute((string) $html, \Drupal::request()->getSchemeAndHttpHost()));

```

Source: https://git.drupalcode.org/project/drupal/commit/530f7ac

By the way, use instead of render() the method renderPlain(), see How to deal with Bubbleable Metadata when there's no rendering context and no render array

---
Tags: 8
---


# Question
Title: drupalSettings object not showing for anonymous users. core/drupalSettings is added as a library dependency
I'm stumped on this one. I’m having an issue where the `drupalSettings` object is empty when not logged in. Works fine when I am authenticated. `- core/drupalSettings` is in theme’s \*.libraries.yml file.

I've tried

* Cleared cache (1million times).
* Triple checked the YAML indentation
* Verified that the settings are being added when stepping through via Xdebug
* The JS file that I'm adding is via \['# attached'\] works great

What am I missing here? Where to start troubleshooting? I'll owe if someone can help point me in the right direction.

themename.libraries.yml

```
views-load-more:
  js:
    js/views-load-more.js: {}
  dependencies:
    - core/drupalSettings

```

In my themename.theme

```
function themename_preprocess_views_view(&$variables) {
  if (!empty($variables["pager"])) {
    $view_selector = '.view-' . $variables["id"] . '.view-display-id-' . $variables["display_id"];
    $view_content_selector = $view_selector . ' .view-content';
    $view_pager_selector = $view_selector . ' .pager';

    $variables["view_array"]["#attached"]["library"][] = 'themename/views-load-more';
    $variables["view_array"]['#attached']['drupalSettings']['themename']['viewsLoadMore']['viewSelector'] = $view_selector;
    $variables["view_array"]['#attached']['drupalSettings']['themename']['viewsLoadMore']['viewContentSelector'] = $view_content_selector;
    $variables["view_array"]['#attached']['drupalSettings']['themename']['viewsLoadMore']['viewPagerSelector'] = $view_pager_selector;
  }
}

```

Note that the `themename/views-load-more`library does get attached when anonymous (I can see the JS file within it).

And also note that this works perfectly when authenticated. This tells me that the drupalSettings dependency isn't working even though I'm declaring this.

How do I troubleshoot this?

# Answer
> 7 votes
Solved the issue... and the answer is *weird*...

within the `html.html.twig` file, we have a `<div class="body-inner">` tag that wrapped the `<js-bottom-placeholder token="{{ placeholder_token }}">` placeholder.

For whatever #drupalWTF reason, if this placeholder tag is wrapped inside of a div, `drupalSettings` will load an empty object. Once I moved it directly underneath the `body` tag, it worked fine.

Hope this helps someone!

# Answer
> 2 votes
Add `core/drupal` as a dependency.

**themename.libraries.yml**

```
views-load-more:
  js:
    js/views-load-more.js: {}
  dependencies:
    - core/drupal
    - core/drupalSettings

```

# Answer
> 1 votes
Tip: look for other javascript errors happening on the page. If a JS error happens before the assignment of `drupalSettings`, it will not be initiated.

---
Tags: views, theming, javascript
---


# Question
Title: Setup many to many relationship - custom content entity
I'm currently setting up a site and using 2 custom content entities (generated with Drupal Console) :

* A tenant, with some custom fields
* A Building, with some custom fields

Theses two entities need a many to many relationship.

Here is my current status, I'd like to know if it is the valid way to do or if I'm implementing this badly.

I'd also like to know how to handle the update of an entity properly (if I add a tenant in a building, I need to update the tenant to add him to this building)

My issue is that if I create a new tenant, add him to an existing building, the ID of my tenant will be null since it is a new entity not saved yet. But I can't save my tenant yet since I may have to add others data to it first, or pass some validation...

A workaround would be to do the building mapping at last, and saving twice my tenant (one when setting basing fields so it can have an ID and one after setting building relationship).

I know that Doctrine can handle many to many relationship by referencing the entity when it is not saved and I'd like to know if their is a way to do it with Drupal properly.

```

/**
 * Defines the Tenant entity.
 *
 * @ingroup bnpp_re_business
 *
 * @ContentEntityType(
 *   id = "bnpp_re_business_tenant",
 *   label = @Translation("Tenant"),
 *   handlers = {
 *     "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
 *     "list_builder" = "Drupal\bnpp_re_business\TenantListBuilder",
 *     "views_data" = "Drupal\bnpp_re_business\Entity\TenantViewsData",
 *     "translation" = "Drupal\bnpp_re_business\TenantTranslationHandler",
 *
 *     "access" = "Drupal\bnpp_re_business\TenantAccessControlHandler",
 *   },
 *   base_table = "bnpp_re_business_tenant",
 *   data_table = "bnpp_re_business_tenant_field_data",
 *   translatable = TRUE,
 *   admin_permission = "administer tenant entities",
 *   entity_keys = {
 *     "id" = "id",
 *     "label" = "name",
 *     "uuid" = "uuid",
 *     "langcode" = "langcode",
 *     "published" = "status",
 *   },
 * )
 */
class Tenant extends ContentEntityBase implements TenantInterface {

  /**
   * {@inheritdoc}
   * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
   *
   * @return array|\Drupal\Core\Field\FieldDefinitionInterface[]
   */
  public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
    $fields = parent::baseFieldDefinitions($entity_type);

    // ... some fields

    $fields[self::BUILDING_CODE] = BaseFieldDefinition::create('entity_reference')
      ->setLabel(t('Buildings'))
      ->setDescription(t('The associated buildings.'))
      ->setSetting('target_type', 'bnpp_re_business_building')
      ->setCardinality(BaseFieldDefinition::CARDINALITY_UNLIMITED);

    return $fields;
  }

  // ... some methods

  public function addBuilding(int $building_id) {
    $items = $this->get(self::BUILDING_CODE)->getValue();
    if (is_null($items) || !is_array($items)) {
      $items = [];
    }
    $data = ['target_id' => $building_id];
    if (!in_array($data, $items)) {
      $items[] = $data;
      $this->set(self::BUILDING_CODE, $items);
      $building = Building::load($building_id);
      // FIXME Here is the bug. If my tenant is new, it does not have an ID yet so this will be null.
      $building->addTenant($this->id());
    }
  }

}

```

```
/**
 * Defines the Building entity.
 *
 * @ingroup bnpp_re_business
 *
 * @ContentEntityType(
 *   id = "bnpp_re_business_building",
 *   label = @Translation("Building"),
 *   handlers = {
 *     "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
 *     "list_builder" = "Drupal\bnpp_re_business\BuildingListBuilder",
 *     "views_data" = "Drupal\bnpp_re_business\Entity\BuildingViewsData",
 *     "translation" = "Drupal\bnpp_re_business\BuildingTranslationHandler",
 *
 *     "access" = "Drupal\bnpp_re_business\BuildingAccessControlHandler",
 *   },
 *   base_table = "bnpp_re_business_building",
 *   data_table = "bnpp_re_business_building_field_data",
 *   translatable = TRUE,
 *   admin_permission = "administer building entities",
 *   entity_keys = {
 *     "id" = "id",
 *     "label" = "name",
 *     "uuid" = "uuid",
 *     "langcode" = "langcode",
 *     "published" = "status",
 *   },
 * )
 */
class Building extends ContentEntityBase implements BuildingInterface {

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

    // some fields ...

    $fields[self::TENANT] = BaseFieldDefinition::create('entity_reference')
      ->setLabel(t('Tenants'))
      ->setDescription(t('The associated building.'))
      ->setSetting('target_type', 'bnpp_re_business_tenant')
      ->setCardinality(BaseFieldDefinition::CARDINALITY_UNLIMITED);
    return $fields;
  }

  // some methods...

  public function addTenant($tenant_id) {
    $items = $this->get(self::TENANT)->getValue();
    if (is_null($items) || !is_array($items)) {
      $items = [];
    }
    $data = ['target_id' => $tenant_id];
    if (!in_array($data, $items)) {
      $items[] = $data;
      $this->set(self::Tenant, $items);
      // Since we only call this method from addBuilding (Tenant Entity) method, we save the building.
      $this->save();
    }
  }

}

```

Thanks by advance for your help !

# Answer
> 0 votes
I think you need a "many-to-many" helper table like "TenantBuilding" and that must be a custom entity also. TenantBuilding then contains reference fields to Tenant and Building.

This is because each entity in Drupal is (more or less) a table in your DB. And there's no such SQL Syntax to describe many2many relations with just two tables.

Then, when you save your entities, encapsulate the creation of all of them in a Drupal::database()-\>startTransaction().

---
Tags: 8, console
---


title: Add class to content field (link)

text:
# Question
Title: Add class to content field (link)
I want to add a class to the `<a>` tag of a field that consists of a link and text. (It's a field of type *Link*.) The name of the field is content.field\_c\_button\_link.

In the template file, I want to add something like the following.

```
{{ content.field_c_button_link.0.addClass('button blue') }}

```

How can I add a class properly?

According to Patrick Scheffer's answer, I looked at the settings for a field where I can add extra CSS classes, but I could not find any. This is a screenshot of what I can edit in the link field.

>

# Answer
> 11 votes
This is a solution I found, but it isn't really handy to use... I really want a better solution, like something directly from twig templates.

```
function template_preprocess_field(&$variables, $hook) {
  $element = $variables['element'];
  if ($element['#name'] == 'field_c_button_link') {
    $variables['items'][0]['content']['#options']['attributes']['class'][] = 'button';
  }
}

```

# Answer
> 7 votes
The easiest way to achieve this would be by using either of these two modules.

1.Link Class \- Link class module provide a new widget form for field type Link. This widget allows editor to add class to fields Link attached to their content.

2.Link Attributes \- Link attributes widget provides an additional widget for the link field found in Drupal core. The widget allows users to set attributes on their link.

In addition the module alters the default menu link content link field to use this widget, allowing menu links to have attributes too

id, class, name, target, rel, accesskey

Once either of the two are enabled we can set the widget settings for the "Link" field under "Manage Form Display" for the particular link field.

See attached image for reference.

Once this is set enter each class separated by a space in the field that appears at the time of content creation.

# Answer
> 5 votes
If you edit that link field in your content type (admin/structure/types/manage/your\_contenttype/fields/field\_c\_button\_link), there's a field **Extra CSS-classes**.

However, the classes entered here apply to all links created with 'field\_c\_buton\_link'. If you want to add a class on one specific location, you might take a look at hook\_preprocess\_field\] or even theme\_link.

**Edit:**

In Drupal 8 there is also a theme\_preprocess\_field. So I think you can do something like this:

```
function template_preprocess_field(&$variables, $hook) {
  $element = $variables['element'];
  if ($element['#name'] == 'field_c_button_link') {
    $variables['attributes']['class'][] = 'button';
    $variables['attributes']['class'][] = 'blue';
  }
}

```

I haven't tested this so I think you need to make some adjustments to make this work.

# Answer
> 5 votes
To do this in twig using the field template (i.e. `field--field-c-button-link.html.twig` )

Normally the field template will loop over your link(s) using:

```
  {% for item in items %}
    {{ item.content }}
  {% endfor %}

```

But you can change that to something like this:

```
  {% for item in items %}
    <a class="btn btn-secondary btn-lg m-1" href="{{ item.content['#url'] }}">{{ item.content['#title']}}</a>
  {% endfor %}

```

by dealing with the link title and url separately.

# Answer
> 4 votes
To add to Tony Fisler's answer above, in Drupal 8.1.2 I needed to check for *#field\_name* instead of *name* to add a class. This is what works for me.

```
function yourthemename_preprocess_field(&$variables, $hook) {
  $element = $variables['element'];
  if ($element['#field_name'] == 'field_link') {
    $variables['items'][0]['content']['#options']['attributes']['class'][] = 'blarg';
  }
}

```

This is if you want the class on the `<a>` tag. The link class solution offered is easier, but when I tried it only applied to class to the wrapper of the a. So, if you're using Bootstrap for example, the link class module wouldn't work.

# Answer
> 2 votes
You can use Project Link class which permit to add classes on Link field. You should set the widget to "Link with class". See screenshot.

# Answer
> 2 votes
It's easy to create your own formatter that overrides the link formatter. Although, now that I see there is a module for this (Link), you may want to use that one, as you can set it at the field level, rather than as a setting in the formatter. But I thought this might be useful to someone, who wants to build their own formatter for a link where you can add a class.

```
namespace Drupal\mymodule\Plugin\Field\FieldFormatter;

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\link\LinkItemInterface;
use Drupal\link\Plugin\Field\FieldFormatter\LinkFormatter;

/**
 * Plugin implementation of the 'link' formatter.
 *
 * @FieldFormatter(
 *   id = "link_with_class",
 *   label = @Translation("Link with Custom Class"),
 *   field_types = {
 *     "link"
 *   }
 * )
 */
class LinkClassFormatter extends LinkFormatter {

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

  }

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

    $elements['class'] = array(
      '#type' => 'textfield',
      '#title' => t('Class on Link'),
      '#default_value' => $this->getSetting('class'),
    );

    return $elements;
  }

  /**
   * {@inheritdoc}
   */
  public function settingsSummary() {

    $summary = parent::settingsSummary();

    $settings = $this->getSettings();

    if (!empty($settings['class'])) {
      $summary[] = t('Class(es) on button = "@classes"', array('@classes' => $settings['class']));
    }

    return $summary;
  }

  /**
   * {@inheritdoc}
   */
  protected function buildUrl(LinkItemInterface $item) {
    $url = parent::buildUrl($item);

    $settings = $this->getSettings();

    if (!empty($settings['class'])) {
      $options = $url->getOptions();
      $options['attributes']['class'] = $settings['class'];
      $url->setOptions($options);
    }

    return $url;
  }

}

```

# Answer
> 1 votes
Here is the simple solution -

```
function THEME_preprocess_file_link(&$variables)
{
  $variables['attributes']->addClass(array('your_custom_class'));
}

```

# Answer
> 0 votes
I'm still testing it out for any bugs, but placing this in your .theme file will add the field's name as a class for all fields. This is for Drupal 8.2:

```
function mytheme_preprocess_field(&$variables, $hook) {
  $variables['attributes']['class'][] = $variables['element']['#field_name'];
}

```

Seems like something every theme should include to make styling easier.

# Answer
> 0 votes
All the other solutions add classes to the field wrapper. This one adds a class to the `<a>` tag itself:

```
/*
 * Implements hook_preprocess__HOOK().
 */
function hook_preprocess_field(&$variables) {
  $classes = [
    'button',
    'blue'
  ];
  $variables['items'][0]['content']['#url']->setOption('attributes', ['class' => $classes]);
}

```

---
Tags: entities, 8, theming, navigation
---


title: How add pager with external request

text:
# Question
Title: How add pager with external request
After many search and read posts, I'm still stuck with my code. Let me explain : I created a custom module who display newsletters from Mailjet and old newsletters comming from drupal. To avoid the scrolling, I'd like to use pager but as I understood I cannot use the Drupal pager to do that. So I created a custom pager service but it doesn't work. I read some posts like this one : How to add Pager to a custom page? but it's only for drupal entities I little help can be usefull.

I'm using Drupal 8.6

Here is my code

my Controller :

```
<?php
/**
 * @file
 * Contains AnrsNewsControler.php
 *
 */
namespace Drupal\anrs_news\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\anrs_news\AnrsNewsMailjetService;
use Drupal\anrs_news\AnrsNewsPagerService;

use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 *
 */
class AnrsNewsController extends ControllerBase
{

    private $mailjetService;

    protected $pagerService;

    public $_result;
    /**
     * Inject Mailjet and Pager services
     *
     */
    public static function create(ContainerInterface $container){
        $mailjetService = $container->get('anrsnews.mailjet');

        return new static(
            $mailjetService,
            $container->get('anrsnews.pager')
        );
    }

    public function __construct(AnrsNewsMailjetService $mailjetService, AnrsNewsPagerService $pager){
        $this->mailjetService = $mailjetService;
        $this->pagerService = $pager;
    }

    /**
     * Create Drupal element with
     * buildNewsletters object
     *
     * @return array $element
     */
    public function getContent() {
        $element[] =    [
            '#theme'    =>  'list_news',
            '#newsletter'   =>  $this->mergeResult(),
            '#pager'        =>  $this->getPagination(),
            '#attached' =>  [
                'library'   =>  [
                    'anrs_news/section'
                ]
            ],
        ];
        $element[] = $this->attachPager();

        return $element;
    }

    /**
     * Create newsletters objects
     * using Mailjet service
     *
     * @service $mailjetService
     * @return array{} $newsletterObj
     */
    public function buildNewsletters(){
        $newsletters = $this->mailjetService->_getNewslettersID();
        $newsletterObj = array();
        $nbNews=0;
        $contactListId=$this->mailjetService->getConfig()->get('mailjet.contact_list_id');

        for($i=sizeof($newsletters)-1; $i>=0; $i--){
            if($newsletters[$i]) {
                $response = $this->mailjetService->displayNewsletterById($newsletters[$i]);
                $elements = json_decode($response);

                foreach ($elements as $key => $value) {
                    if(( $value->Url != "")&&($value->DeliveredAt != '')&&($value->ContactsListID==$contactListId)) {
                        // on each index, initialize object
                        $newsletterObj[$nbNews] = new \stdClass();

                        $newsletterObj[$nbNews]->title = $value->Subject;
                        $newsletterObj[$nbNews]->id = $value->ID;
                        // convert datetime to timestamps
                        $newsletterObj[$nbNews]->date = strtotime($value->DeliveredAt);
                        $newsletterObj[$nbNews]->url = $value->Url;
                        $nbNews++;
                    }
                }
            }
        }

        return $newsletterObj;
    }

    /**
     * Retreive old newsletters
     * from 'simplenews_issue' entity
     *
     * @return array{Obj} $result
     *
     */
    public function getOldNewsletters() {
        $storage = \Drupal::EntityTypeManager()->getStorage('node');
        $entityQuery = \Drupal::entityQuery('node')
        ->condition('type', 'simplenews_issue')
        ->condition('status', 1);

        $entities_ids = $entityQuery->execute();

        $total = $entityQuery->count()->execute();  // total rows

        $entities = $storage->loadMultiple($entities_ids);

        $oldNews = array();
        $n = 0;

        foreach ($entities as $key => $value) {
            $oldNews[$n] = new \StdClass();

            $oldNews[$n]->title = $value->getTitle();
            $oldNews[$n]->id = $value->id();
            $oldNews[$n]->date = $value->getCreatedTime();
            $oldNews[$n]->url = $value->url();
            $n++;
            //id : $value->id()
            //created (tmp): $value->getCreatedTime()
            //title: $value->getTitle()
            //link : $value->url()
        }

        return $oldNews;
    }

    /**
     * Merge result of Mailjet newsletters and
     * 'simplenews_issue' newsletters
     *
     * @return array{obj} desc
     */
    public function mergeResult(){
        $this->_result = array_merge($this->buildNewsletters(), $this->getOldNewsletters());

        // sort array
        usort($this->_result, function($a, $b){
            if($a->date == $b->date ){
                return 0;
            } else {
                return ($a->date < $b->date)? +1:-1;
            }
        });
        // return slice array
        $offset = $this->pagerService->getResults($this->_result);

        return $offset;
    }

    public function getPagination() {

        if(count($this->_result)){
            $pagination = $this->pagerService;
            $response = $pagination->getResults($this->_result);

            if(count($response) != 0){
                $pageNum = '<div class="numbers">'.$pagination->getLinks($_GET).'</div>';
            }
        }
        // kint($_GET,$pageNum);
        return $pageNum;
    }

```

here is my pager service :

```
<?php
namespace Drupal\anrs_news;

use Symfony\Component\DependencyInjection\ContainerAwareTrait;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\HttpFoundation\RequestStack;

class AnrsNewsPagerService implements ContainerAwareInterface{

    use ContainerAwareTrait;

    private $_properties = array();

    public $_defaults = array(
        'page'  => 1,
        'perPage'   => 3//\Drupal::Config('anrsnews.settings')->get('mailjet.posts_per_page')
    );

    public $page, $pages, $curpage, $length, $start;

    /**
     * Custom pager constructor
     *
     */
    public function __construct($curPage = null, $perPage = null) {

        $this->curPage = ($curPage == null ? $this->_defaults['page']: $curPage);
        $this->perPage = ($perPage == null ? $this->_defaults['perPage']: $perPage);
    }

    public function __get($name){
        if(array_key_exists($name, $this->_properties)){
            return $this->_properties[$name];
        }
    }

    public function __set($name, $value){
        $this->_properties[$name] = $value;
    }

    public function getResults(array $array) {
        $this->array = $array;

        if(!empty($this->curPage)   ){
            $this->page = $this->curPage;
        } else {
            $this->page = 1;
        }

        $this->length = count($this->array); // array length

        // number of pages
        $this->pages = ceil($this->length/$this->perPage);

        // starting point
        $this->start = ceil(($this->page - 1) * $this->perPage);

        // return result offset
        return array_slice($this->array, $this->start, $this->perPage);
    }

    public function getLinks($params = array()) {
        $plinks = array();
        $links = array();
        $slinks = array();

        $queryUrl = '';
        // if(!empty($params) === true){
        //  unset($params['page']);
        //  $queryUrl = '&'.http_build_query($params);
        // }
        if(!empty($params) === true){
            unset($params['page']);
            $queryUrl = '&'.http_build_query($params);
        }

        if(($this->pages) > 1){
            if($this->page != 1){
                $plinks[] = '<a href="?page='.($this->page - 1).$queryUrl.'">«Prev</a>';
            }

            for($j=1; $j < ($this->pages +1); $j++) {
                if($this->page == $j){
                    $links[] = '<a class="selected">'.$j.'</a>';
                } else {
                    $links[] = '<a href="?page='.$j.$queryUrl.'">'.$j.'</a>';
                }
            }

            // Assign the 'Next page'
            if( $this->page < $this->pages) {
                $slinks[] = ' <a href="?page='.($this->pages+1).$queryUrl.'"> Next » </a>';
            }

            return implode(' ', $plinks).implode(' | ', $links).implode(' ', $slinks);
        }

    }
}

```

thank u 4 ur help

# Answer
One of my mate find a solution, I had all the things on the file!! :,-( On the controller, in mergeResult function, instead to slice the array by the pager service, I sliced the array inside the function :

```
public function mergeResult(){
    $this->_result = array_merge($this->buildNewsletters(), $this->getOldNewsletters());

    // sort array
    usort($this->_result, function($a, $b){
        if($a->date == $b->date ){
            return 0;
        } else {
            return ($a->date < $b->date)? +1:-1;
        }
    });
    // return slice array
    $limit = \Drupal::config('anrs_news.settings')->get('mailjet.posts_per_page');
    $offset=0;
    if(!empty($_REQUEST['page'])){
        $offset = $_REQUEST['page'] * $limit;
    }

    return array_slice($this->_result, $offset, $limit);
}

```

and in the getContent function, I removed the pager variable :

```
public function getContent() {

    $element[] =    [
        '#theme'    =>  'list_news',
        '#newsletter'   =>  $this->mergeResult(),
        '#attached' =>  [
            'library'   =>  [
                'anrs_news/section'
            ]
        ],
    ];
    $element[] = $this->attachPager();

    return $element;
}

```

that's it!!
> 0 votes

# Answer
You can use the internal paging capabilities of Drupal without writing all that code. You just have to attach it in the returned render array. Here is an example

```
protected function method attachPager(int $totalRows, int $limit) : {
  pager_default_initialize($totalRows, $limit);
  return ['#type' => 'pager'];
}

```

Then attach that to the render array, like you are already doing, with the arguments:

```
$element[] = $this->attachPager(totalRows, limit);

```

The totalRows would come from your total results, and the limit is how many per page you want to show. The pager will generate based on that information. Your code would just need to implement the offset, based on the current page.

I would really evaluate this and try that out, otherwise you are having to maintain a lot more code. I have done this method for different types of data before, not just core entities.
> 0 votes

---
Tags: 8, paging, symfony-services
---


# Question
Title: Drupal 7 as an Oauth 2.0 and/or 1.0a provider
I am trying to make my Drupal 7 site a Oauth provider. I have found the Drupal modules for Oauth 1, yet I am having trouble with finding Oauth 2.0 provider modules and I am not sure that Drupal supports Oauth 1.0a.

I found this project at Drupalcode: http://drupalcode.org/project/oauth2.git it supports Oauth 2.0 for Drupal 6. While browsing to the repository I saw the tags: "7.x-1.x-dev" and "7.x-1.x-Rj" (don't know what this Rj stands for..) which made me very happy. So I checked out the code and put that, together with the latest http://code.google.com/p/oauth2-php/ in my Drupal installation. However when I wanted to enable the module in Drupal 7 and it says: "This version is not compatible with Drupal 7.x and should be replaced."

Furthermore, while implementing a OAuth-PHP client for my OAuth 1 setup, I found that Drupal does not return a "verified token". I read somewhere that this is implemented since OAuth 1.0a to fix a security bug. Does Drupal support OAuth 1.0a? If so what am I missing if I don't recieve a Verified token?

Has anyone got any idea if this module should work in Drupal 7? (the tags confuse me) and if not is there another module for Oauth 2.0 for Drupal?

Thank you in advance

# Answer
> 2 votes
I think you should try http://drupal.org/sandbox/sadashiv/1857254 for google\_oauth2 This module is yet is sandbox but you can give it a try.

# Answer
> 1 votes
I successfully used simpleSAMLphp plus the drupalauth simplesaml module (not a Drupal module) to use Drupal as a SAML 2.0 Identity Provider. It's not clear to me whether simpleSAMLphp supports being an OAuth 2 provider (it supports a bunch of protocols), but even if it doesn't, it could be a tool that helps connect the dots.

# Answer
> 1 votes
For OAuth 1.0a, you need the OAuth module.

For OAuth2 there were no solutions until recently (the module you mentioned implements draft 10 of the standard. There were 31 drafts before the final version). I have written a new module for that, called OAuth2 Server, and it now has its first release.

# Answer
> 1 votes
I spent some days for using Drupal7 as oauth2 provider and successfully implemented. I am sharing two github repositories Drupal repository (oauth2 provider).. database is in database folder

Client code to test oauth2 provider.. this repository contains curl code to test

# Answer
> 0 votes
I found this Drupal OAuth Server module to be very useful as it allowed me to integrate with many OAuth Clients very easily

---
Tags: 7, authentication-authorization
---


# Question
Title: How do I pass multiple block configurations to a behavior?
I am trying to create a Drupal 8 module that implements a Curator IO widget, so I created a block plugin with its own custom configuration.

```
public function blockForm($form, FormStateInterface $form_state) {
  $form['curator_io_settings'] = array(
    '#type' => 'fieldset',
    '#title' => t('Curator IO Settings'),
    '#collapsible' => TRUE,
    '#collapsed' => FALSE,
  );

  $form['curator_io_settings']['feed_id'] = [
    '#type' => 'textfield',
    '#title' => $this->t('Enter your unique Feed Id'),
    '#default_value' => $this->configuration['feed_id'],
    '#maxlength' => 256,
    '#size' => 64,
    '#description' => t('Set your unique feed id found at curator io'),
  ];

  return $form;
}

```

I attached my library from the build method and passed a variable so I can work with it in jQuery.

```
public function build() {
  $build = [
    '#theme' => 'curatorio_io',
    '#attached' => [
      'library' => [
        'curatorio/curatorio_assets',
      ],
      'drupalSettings' => [
        'curatorio' => [
          'feed_id' => $this->configuration['feed_id'],
        ]
      ]
    ],
  ];

  return $build;
}

```

I am getting this variable value in JavaScript using the following code.

```
(function ($, Drupal, drupalSettings) {
  'use strict';
  Drupal.behaviors.curatorio = {
    attach: function (context, settings) {
      console.log(drupalSettings.curatorio);
    }
  }
};

```

It is working fine for one instance of the block.

When I add 2 or more instances of this block, only the first block works. I can understand that no matter how many instance I create for this block, the JavaScript will always get included once, so how do I pass multiple values for feed\_id to the JavaScript behavior?

# Answer
> 1 votes
So as Leigh suggested I send this data values into a twig file

```
  public function build() {

    $build = [
      '#theme' => 'curatorio_io',
      '#id' => uniqid(),
      '#feed_id' => $this->configuration['feed_id'],
      '#widget_type' => $this->configuration['widget_type'],
      '#attached' => [
        'library' => [
          'curatorio/curatorio_assets',
        ],
      ],
    ];

    return $build;
  }

```

Now in my twig file, I put those values into data attributes

```
<div class ="curator-feed"  id = "{{ id }}" data-feed-id = "{{ feed_id }}"  data-widget-type = "{{ widget_type }}" >

</div>

```

and in js I attached my JS logic to get attribute value and attach Plugin into it.

---
Tags: 8, blocks
---


# Question
Title: After restoring, incorrect database credentials are used
I am trying to get a local drupal environment up and running using an sql dump from a production environment. I am attempting to follow instructions from drupal's documentation.

So far, from our production server, I went ahead and ran `drush sql-dump > prod_drupal_backup.sql`. Then, I used `scp` to pull the prod\_drupal\_backup.sql file from the production server.

On my local machine, using MAMP, I created a database (*prod\_drupal*, same as the database on the production server) and gave a user, admin, access to the database. I went ahead and pulled down the codebase and created a fresh Drupal instance. During this set up, I gave Drupal the *admin* credentials to connect to the database and had a fresh site up and running.

With a backup, I was ready to restore the database using the *prod\_drupal\_backup.sql* SQL dump file. So I went and ran `/Applications/MAMP/Library/bin/mysql -uroot prod_drupal < ~/Desktop/db_backup.sql`. After this completed, I checked the database via MAMP's localhost:8888/phpmyadmin. The *prod\_drupal* database had the correct data in it. So then I went to the website (localhost:8888) and saw what I wanted, the login screen with all of our styling and everything. When I logged in using one of the accounts registered for the site, it thrown the *The website encountered an unexpected error. Please try again later.* error.

When I look at my MAMP sql error logs in *mysql\_error.log*, I see errors like *access denied for user 'mikesmith@localhost'*. This makes zero sense because Drupal is supposed to be connecting to the database with admin, not `mikesmith`. The way Drupal is trying to connect to the database doesn't match what's in the settings.php file.

What am I doing wrong?

I am using MAMP Pro 5.5.1 and PHP 7.2.21, if this makes any difference.

# Answer
> 1 votes
Some possible solutions / debugging steps:

Check that your local settings.php file is correct by using `drush status` command. Do this when in the same directory as the settings.php file (or with a correctly set up site alias). You should see information about the database and drupal version. If you don't then something is wrong with your settings.

Next, Drupal uses the DB to cache things in the DB. This cached information in an SQL dump can cause a local site to crash. Some ways to possible ways to correct this are:

* On the local site, try using the `drush cc` (assumed D7 per tag) on the command line.

(OR)

* Prior to making the dump from production, clear cache (either via admin screen or `drush cc`).

(OR)

* Remove the contents of any Cache\_\* table on the local site (keep the tables)

Another possibility is that the password encryption salt string is different between the sites. This is set in the settings.php file and should be the same on both sites.

Finally, you can always reset the local user password via drush. Two useful drush commands are:

* `drush uli --name=xxx` (Gets a password reset URL.. may need to put the correct host name)
* `drush upwd [username] [new-password]`

---
Tags: 7, installation
---


title: What does the embed display type do?

text:
# Question
Title: What does the embed display type do?
I've been trying to find an answer but any search for views embed display brings up a bunch of unrelated modules and questions.

There is a Views Display Type/Mode/Whatever called "Embed" that you select when creating different views in your view:

For what can I use this display type?

# Answer
This is a display which can be embedded via views\_embed\_view() or drupal\_view() of Twig Tweak.

You can embed other display types, too, for example *Page* or *Block*, but the first one generates a route and the second one a block derivate you see when adding blocks to the block layout. So *Embed* is basically a display type which does nothing until you embed it in code.

The only explanation you can find in Views UI is in the general settings, where there is this checkbox:

> \[x\] Allow embedded displays
>
> Embedded displays can be used in code via views\_embed\_view().

Which by the way is without function and there is an open issue to remove it.
> 10 votes

---
Tags: views, 8
---


# Question
Title: Why can I choose the widget for grouped filters, but not exposed?
When I create a view (block) and create an exposed filter I have the choice of a *Filter type to expose* between

* *Single filter* and
* *Grouped filters*

If I choose the *Grouped filters* I am presented with an option to chose the *Widget type*

* *Radios* or
* *Select*

But if I chose the default *Filter type* the form lacks the *Widget type* option.

I cannot think of any reason why the regular exposed filters shouldn't have this widget type option to chose from.

Can anyone tell me ...

* Is there a reason for this?
* Is there any patch that I didn't find until now that fixes this/add's the feature?

## FYI:

There is a hard coded switch in the Drupal core which automatically changes the widget type from checkboxes/radios to select based on the number of options regardless of the *Widget type* settings in the views form (1-4 options: radios, 5+: select). That issue is patched here: Grouped exposed filter with "Allow multiple selections" ignores widget setting

# Edit

I don't want the alpha version of Better Exposed Filters module like suggested by some.

# Answer
There are two questions asked in the OP:

* What is the reason for not being able to choose the widget type for an exposed filter?

Space: It seems that Views decide that for you, in the module's wisdom. I find this is a good enough argument, the rest can be handled as wished by a custom filter.

> // Exposed filter: use a select box to save space.

Source: https://git.drupalcode.org/project/drupal/blob/8.8.x/core/modules/views/src/Plugin/views/filter/BooleanOperator.php#L156
* Is there any patch that I didn't find until now that fixes this/add's the feature?

None that I know off, but, this is not something that needs patching I believe; all additional wishes can be handled by a custom views filter plugin.

Good luck in any case!
> 1 votes

# Answer
I can see two possible solutions to this problem:

## Solution 1: Better Exposed Filters

Install the Better Exposed Filters module. There are over 31,227 sites using it at the moment. Don't let the fact that it is in `alpha` hold you back unless your organization has a policy preventing you from using alpha releases.

## Solution 2: Custom Code

If you cannot use Better Exposed Filters for some reason, then write a `hook_form_FORM_ID_alter()` to modify your views exposed form the way you want.

### Sample code

Create a `hook_form_FORM_ID_alter()` in a custom module. In the example below, the module name is `custom_general`.

```
/**
 * Implements hook_form_FORM_ID_alter().
 */
function custom_general_form_views_exposed_form_alter(
  &$form,
  FormStateInterface $form_state,
  $form_id
) {
  $view_data = $form_state->getStorage('view');

  // Content administration.
  if ($view_data['view']->id() === 'VIEW-ID') {
    // Analyze the structure of your form with kint().
    // Say, the field that matters to you is "field_foobar".
    // kint($form); exit;

    if (isset($form['field_foobar']) {
      $form['field_foobar']['#type'] = 'select';
      $form['field_foobar']['#multiple'] = FALSE;
      $form['field_foobar']['#size'] = 1;
      // TODO: Do other things as necessary.
    }
  }
}

```
> 2 votes

---
Tags: views, 8
---


# Question
Title: Redirect to referring page after form submission
Trying to figure out how to redirect a user back to referring page after they have completed our feedback form. So a scenario would be if im on page `foo/bar` and I click on feedback webform link on that page. I then proceed to fill out the webform and then hit submit I will then be directed back to `foo/bar` page with confirmation message displayed at top of page. Webform module does give me an option to add in a custom confirmation URL and also the ability to add in tokens. However I have had no success with current tokens as none of them redirect me back to referring page.

Would creating a custom token maybe help with resolving this issue or `hook_form_alter`? Kind of stuck on how best to approach this.

# Answer
> 0 votes
You can't rely on the referrer header, because clients can refuse to provide one. For this use case Drupal has implemented a query parameter `destination`. Configure the webform with a default Confirmation URL, like `<front>`, and then add the current url as destination query string to links pointing at the webform.

For example add a feedback link to nodes:

```
use Drupal\Core\Url;

/**
 * Implements hook_preprocess_HOOK() for node templates.
 */
function mymodule_preprocess_node(&$variables) {
  $variables['content']['feedback'] = [
    '#type' => 'link',
    '#title' => t('Feedback'),
    '#url' => new Url(
      'entity.webform.canonical',
      ['webform' => 'feedback'],
      ['query' => ['destination' => Url::fromRoute('<current>')->toString()]]
    ),
    '#cache' => ['contexts' => ['url.path']],
  ];
}

```

This overrides the configured confirmation URL and returns to the referring page after the webform is submitted.

In a page template you don't need the cache context and you can use this Twig only solution, as @PaulH has suggested:

```
href="/form/feedback?destination={{ path('<current>') }}"

```

---
Tags: 8, webforms
---


# Question
Title: How can I set the default format for a node body field and hide the form element to choose it?
I am trying to set the default input format for a node body field and avoid users can select a different input format by hiding the form element to change it.

I am using the following code, but it doesn't work.

```
/**
 * Implements hook_form_alter().
 */
function mymodule_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ($form_id == 'node_article_form') {
    $form["body"]["widget"][0]['#allowed_formats'] = ['full_html'];
    $form["body"]["widget"][0]['#after_build'][] = 'mymodule_hide_format';
  }
}

function mymodule_hide_format(&$element, FormStateInterface $form_state) {
  if (isset($element["format"]["format"])) {
    $element["format"]["format"]["#access"] = FALSE;
  }

  return $element;
}

```

# Answer
The module suggested (in comments above) seems interesting, but if you want to do it with code only for body field and you don't want to use the module,
you can use `hook_field_widget_form_alter()` instead of `hook_form_alter()`.

```
use Drupal\Core\Form\FormStateInterface;
use Drupal\field\Entity\FieldConfig;

/**
 * Implements hook_field_widget_form_alter().
 */
function mymodule_field_widget_form_alter(&$element, FormStateInterface $form_state, $context) {
  /** @var \Drupal\Core\Field\FieldDefinitionInterface $field_definition */
  $field_definition = $context['items']->getFieldDefinition();

  // Base fields are not configurable.
  if (!$field_definition instanceof FieldConfig) {
    return;
  }

  if ($field_definition->getName() === 'body'){
    // Set only full_html as allowed format.
    $element['#allowed_formats'] = ['full_html'];
    // Add after build to remove the help wrapper and text.
    $element['#after_build'][] = 'MODULE_NAME_after_build';
  }
}

function mymodule_after_build(array $element, FormStateInterface $form_state) {
  // Remove Guidelines and Help text.
  unset($element['format']['help']);
  unset($element['format']['guidelines']);
  unset($element['format']['#type']);
  unset($element['format']['#theme_wrappers']);
  return $element;
}

```
> 5 votes

---
Tags: 8
---


title: Insert row into a view

text:
# Question
Title: Insert row into a view
I have a view which fetches nodes from content type A, arranges them in a grid and uses a displaysuite buildmode to render them...nothing fancy so far. Now I want to insert a specific node of content type B at a specific position in the grid...like this:

```
+----------+----------+
|          |          |
|  type A  |  type A  |
|          |          |
+----------+----------+
|          |          |
|  type B  |  type A  |
|          |          |
+----------+----------+
|  type A  |  type A  |
.          .          .

```

I'm not sure where to start. I was hoping there would be some hook, preprocess function or whatever where I get an array of node objects to insert my special node into which then gets rendered...

# Answer
> 8 votes
I found the function I was looking for. You can insert nodes in the results array just after the query has been executed.

This goes in the module:

```
function modulename_views_post_execute(&$view) {
  // wait for the right view
  if($view->name == "name_of_the_view") {
    // create the object you want to insert in the result
    $temp = new stdClass;
    // creation date of that node
    $temp->node_created = 1314807643;
    // nodeID
    $temp->nid = 13;

    $new_result_array = array();
    $i = 0;
    foreach($view->result as $single_result) {
      if($i == 2) {
        // insert the extra node at 3rd position
        $new_result_array[] = $temp;
        $new_result_array[] = $single_result;
      } else {
        $new_result_array[] = $single_result;
      }
      $i++;
    }
    // replace the old result array
    $view->result = $new_result_array;
  }
}

```

# Answer
> 1 votes
For any latecomers to this question, there's a module that does just this Views Row Insert

It has it's limitations when you start to push it, but it would do just as OP requests with very minimal effort and no hooks needed.

# Answer
> 0 votes
You can do it also using views theming feature. Place PHP file `views-view-unformatted--taxonomy-term--page.tpl.php` right in your theme's folder and with this code you can print custom code after every 3th row for *Taxonomy term page* default views:

```
<?php if (!empty($title)): ?>
  <h3><?php print $title; ?></h3>
<?php endif; ?>
<?php foreach ($rows as $id => $row): ?>
  <div<?php if ($classes_array[$id]) { print ' class="' . $classes_array[$id] .'"';  } ?>>
    <?php print $row; ?>
  </div>
  <?php if ($id == 2): ?>**My custom code after first row in Drupal views**<?php endif; ?>
<?php endforeach; ?>

```

This line does the trick

```
<?php if ($id == 2): ?>**My custom code after first row in Drupal views**<?php endif; ?>

```

Source and more details.

---
Tags: 7, views
---


title: Weird apostrophe issue

text:
# Question
Title: Weird apostrophe issue
Using Drupal version - 8.7.4. Added a 'Text (plain, long)' field for news summary to news content type.

There is a news view that shows all recent news items with the summary.

I created a new news item and pasted the summary from a document from Google Drive.

The apostrophe shows up as `'` on the view but in the drupal edit page, it shows a `'`

Any thoughts on why this is happening? Any solutions? I am completely clueless. Thanks for reading.

# Answer
This is a known issue with CKEditor.

In your case, the ampersand character `&` is being escaped as `&` which is causing the HTML entity for your apostrophe to appear as `&#039;`.

The entity for the ampersand is well-formed, so the ampersand appears in your rendered output. But this causes the entity for the apostrophe to be malformed, so it appears as a literal string.

There's a CKEditor config that you can do to force a simple ampersand, but I'm not sure how it will affect other text fields site-wide (which will no longer have their ampersands escaped), so proceed with caution.

Perhaps someone with more CKEditor experience can tell us if there's a way to configure this more narrowly.
> 0 votes

---
Tags: views, 8
---


title: Resolve composer update drupal/core 8.6

text:
# Question
Title: Resolve composer update drupal/core 8.6
When i try to run composer update it results to the following problem:

> Your requirements could not be resolved to an installable set of packages.

```
 Problem 1
    - don't install drupal/core 8.6.0|remove drupal/drupal dev-master
    - don't install drupal/core 8.6.0-alpha1|remove drupal/drupal dev-master
    - don't install drupal/core 8.6.0-beta1|remove drupal/drupal dev-master
    - don't install drupal/core 8.6.0-beta2|remove drupal/drupal dev-master
    - don't install drupal/core 8.6.0-rc1|remove drupal/drupal dev-master
    - don't install drupal/core 8.6.1|remove drupal/drupal dev-master
    - don't install drupal/core 8.6.10|remove drupal/drupal dev-master
    - don't install drupal/core 8.6.2|remove drupal/drupal dev-master
    - don't install drupal/core 8.6.3|remove drupal/drupal dev-master
    - don't install drupal/core 8.6.4|remove drupal/drupal dev-master
    - don't install drupal/core 8.6.5|remove drupal/drupal dev-master
    - don't install drupal/core 8.6.6|remove drupal/drupal dev-master
    - don't install drupal/core 8.6.7|remove drupal/drupal dev-master
    - don't install drupal/core 8.6.8|remove drupal/drupal dev-master
    - don't install drupal/core 8.6.9|remove drupal/drupal dev-master
    - don't install drupal/core 8.6.x-dev|remove drupal/drupal dev-master
    - don't install drupal/core 8.7.x-dev|remove drupal/drupal dev-master
    - don't install drupal/core 8.8.x-dev|remove drupal/drupal dev-master
    - remove drupal/drupal dev-master|remove drupal/core 8.6.10
    - Installation request for drupal/drupal dev-master -> satisfiable by drupal/drupal[dev-master].
    - Installation request for drupal/core ~8.6 -> satisfiable by drupal/core[8.6.0, 8.6.0-alpha1, 8.6.0-beta1, 8.6.0-beta2, 8.6.0-rc1, 8.6.1, 8.6.10, 8.6.2, 8.6.3, 8.6.4, 8.6.5, 8.6.6, 8.6.7, 8.6.8, 8.6.9, 8.6.x-dev, 8.7.x-dev, 8.8.x-dev].

```

I have tried many suggestions to try and resolve this problem but no luck. I don't know where my problem is. Also when i try to update on another computer or server it doesn't give me this problem. I don't know what i am missing.

So if anyone can help me out with this it would be much appreciated

This is my composer file:

```
{
    "name": "drupal/drupal",
    "description": "Drupal is an open source content management platform powering millions of websites and applications.",
    "type": "project",
    "license": "GPL-2.0+",
    "require": {
        "drupal/core": "^8.6.0",
        "composer/installers": "^1.0.24",
        "wikimedia/composer-merge-plugin": "~1.4",
        "drupal/console": "~1.0",
        "drupal/metatag": "^1.2",
        "drupal/pathauto": "^1.0",
        "drupal/google_analytics": "^2.1",
        "drupal/country": "1.x-dev",
        "drupal/webform": "5.x-dev",
        "drupal/geolocation": "^1.10",
        "drupal/twig_tweak": "^1.8",
        "solarium/solarium": "^3.8",
        "drupal/redirect": "^1.0@beta",
        "drupal/search_api_solr": "^1.2",
        "tinify/tinify": "1.4.*",
        "drupal/tinypng": "^1.0@alpha",
        "drupal/IMCE": "^1.6",
        "drupal/editor_advanced_link": "^1.4",
        "drupal/captcha": "^1.0@beta",
        "drupal/recaptcha": "^2.2",
        "drupal/swiftmailer": "^1.0@beta",
        "drupal/xmlsitemap": "1.x-dev"
    },
    "minimum-stability": "dev",
    "prefer-stable": true,
    "config": {
        "preferred-install": "dist",
        "autoloader-suffix": "Drupal8"
    },
    "extra": {
        "_readme": [
            "By default Drupal loads the autoloader from ./vendor/autoload.php.",
            "To change the autoloader you can edit ./autoload.php.",
            "This file specifies the packages.drupal.org repository.",
            "You can read more about this composer repository at:",
            "https://www.drupal.org/node/2718229"
        ],
        "merge-plugin": {
            "include": [
                "core/composer.json"
            ],
            "recurse": false,
            "replace": false,
            "merge-extra": false
        },
        "installer-paths": {
            "core": ["type:drupal-core"],
            "modules/contrib/{$name}": ["type:drupal-module"],
            "profiles/contrib/{$name}": ["type:drupal-profile"],
            "themes/contrib/{$name}": ["type:drupal-theme"],
            "drush/contrib/{$name}": ["type:drupal-drush"],
            "modules/custom/{$name}": ["type:drupal-custom-module"],
            "themes/custom/{$name}": ["type:drupal-custom-theme"]
        }
    },
    "autoload": {
        "psr-4": {
            "Drupal\\Core\\Composer\\": "core/lib/Drupal/Core/Composer"
        }
    },
    "scripts": {
        "pre-autoload-dump": "Drupal\\Core\\Composer\\Composer::preAutoloadDump",
        "post-autoload-dump": [
          "Drupal\\Core\\Composer\\Composer::ensureHtaccess"
        ],
        "post-package-install": "Drupal\\Core\\Composer\\Composer::vendorTestCodeCleanup",
        "post-package-update": "Drupal\\Core\\Composer\\Composer::vendorTestCodeCleanup"
    },
    "repositories": [
        {
            "type": "composer",
            "url": "https://packages.drupal.org/8"
        }
    ]
}

```

# Answer
The use of the wikimedia merge plugin is deprecated. Remove the drupal core composer include from the merge plugin section:

```
"merge-plugin": {
        "include": [
            "core/composer.json" <-- Remove
        ],
        "recurse": false,
        "replace": false,
        "merge-extra": false
    }

```

Then delete de vendor folder and composer.lock file and run:

```
composer update drupal/core --with-dependencies

```

Also note the "name" entry on your composer.json file. The distribution drupal/drupal is for code contribution not site building and can lead to future problems.
> 1 votes

---
Tags: composer
---


title: Export Broken Links records as CSV/XLS

text:
# Question
Title: Export Broken Links records as CSV/XLS
In Drupal 8 I can see the list of broken links at `Administration->Configuration->System->Broken Link`.
It is showing thousands of records with pagination.

I'm using Broken Link Module.

Is there any way we can export the entire record as a CSV or XLS file?

# Answer
> 2 votes
The Broken Link module seems to have views support, so you can use the Views Data Export module and a View of the data to export it.

If you'd prefer to go directly to the database, the module stores information in a table called `broken_link` so you can query that and use tools to move database results into a csv/excel if you'd like.

---
Tags: 8, importing-exporting
---


title: Cookie sharing on multidomain site

text:
# Question
Title: Cookie sharing on multidomain site
Can somebody please clarify, that cookie sharing in Drupal 8 is just possible for sub domains siblings of the same parent domain.

Before this was discussed here: Multi-domain cookie \- unfortunately just in a sub domain context.

To use the administration session of domain1.com on domain2.com is NOT possible due to security reasons (browser specific).

Or in other words: To be able to use the drupal8 administration area of content that is separated into 3 top level domains via the the "domain module" you must login 3 times.

Am I correct?

# Answer
This is not really a Drupal question, but a browser question.

The cookies a browser has for example.com will never be sent to example.org.

You can look at other ways to create federated login, but they are not simple.

To log in and administer 3 separate top level domains you either must log in 3 separate times or use some other form of federated login.
> 4 votes

---
Tags: 8, domain-access, cookies
---


# Question
Title: Building a non-config, programmatically-created, semi-dynamic, semi-manual menu
We have a custom entity called "Topic". With this entity, users can build topics and reference other content to "belong" to the topic. We also have a requirement where, whenever a user creates a topic, a menu is also created for it. When content is added to the topic, a link is automatically added to the menu pointing to that content.

The workflow is like:

1. User creates a topic.
2. User references a bunch of arbitrary content to the topic.
3. User saves topic.
4. Menu associated with topic automatically adds links to added content.
5. (optional) User adds more links to menu, not necessarily for topic content.

Now this menu currently couldn't be a custom-built block, as we also have a requirement where users should be able to to add menu links like a regular menu. But the downside to using menus is that they're config - they need to be exported. Otherwise, a deploy without the config would wipe out all the created menus.

Is there a way to create a menu without making them config? Is there a better approach to this problem?

# Answer
Without delving too much into the specifics of your complex configuration management, I'd venture to say that you should use Drupal 8's built-in configuration sync to export config to YAML and commit it to your version control repository (`git` or what-have-you) so that you can deploy your config along with your code.

Then, you can use the Config Filter, Config Split, and Config Ignore contrib modules to split off certain configuration from the sync directory into separate directories that can be used or ignored in different environments.

**NOTE:** If your users are all adding content in the production environment, you'll need to make sure your lower environments always have the latest config before deploying to a higher environment. This would be the case even if you didn't use config sync; it will just be a different workflow (i.e., you'll need to `drush cex` the latest config from Prod and `drush cim` it into your Dev environment, rather than grabbing a fresh sqldump from Prod.)

More info: https://www.o8.agency/blog/tips-dev-team-using-config-split-and-config-ignore-fine-tune-your-configuration-management

There's work underway to integrate some of the functionality provided by Config Filter and Config Split into Drupal 8 core. This is the way things are headed, so there's really no downside to config export anymore if you do it correctly.

Admittedly, setting it up can be a pain, but it's a different pain (and, I think, a *less painful* pain) than keeping all your config in the database and trying to keep that in sync across your local, dev, stage, and prod environments.
> 0 votes

---
Tags: 8, entities, navigation, configuration
---


# Question
Title: prevent user creating a duplicate node title
how to prevent user creating a duplicate node title for a content type?

I already try uniqueness module (https://drupal.org/project/uniqueness) but it's only list out the duplicate content title but not return any error message when user save the new content. Any suggestion module or code? :)

# Answer
> 1 votes
You can try the Unique field module.

> This module performs additional validation when a node is created or updated by a user to require that a node's title, author, language, and CCK fields are unique within a given context.

I have not tested it yet, but it seems promising.

# Answer
> 0 votes
We can think of two coding approaches:

1. Use hook\_node\_validate()
2. Call '#validate' in form alter

We should not validate inside hook\_node\_insert() or, hook\_node\_presave()

You can make use of code like below:

```

  $type = 'Content_Type_Machine_Name_You_Want_To_Validate_For';

  if (YOUR_CONDITION_FOR_CONTENT_TYPE_CHECK) {
    $query = db_select('node', 'n');
    $node_title_exists =  $query->fields('n', array('nid'))
      ->condition('n.type', $type, '=')
      ->condition('n.title', 'SUBMITTED_NODE_TITLE', '=')
      ->execute()
      ->fetchField();
    if ($node_title_exists) {
      // WRITE form_set_error();
    }
  }

```

Hope it helps

# Answer
> 0 votes
What you are looking for is node title validation https://www.drupal.org/project/node\_title\_validation

---
Tags: nodes
---


# Question
Title: Making title unique using hook_entity_bundle_field_info_alter()
`hook_node_validate()` is replaced by `hook_entity_bundle_field_info_alter()` in Drupal 8.

I need to validate the **node title** whether the same **title** is used in any other node. Title field should be unique for me.

How can I define that in `hook_entity_bundle_field_info_alter()`? When I print something in this hook. It didn't called when I save the node.

```
function my_module_entity_bundle_field_info_alter(&$fields, \Drupal\Core\Entity\EntityTypeInterface $entity_type, $bundle) {
  if ($entity_type->id() == 'node') {
    dpm($entity_type);
  }
}

```

What am I doing wrong?

# Answer
> 2 votes
This hook only runs with a cold cache. In Drupal 8 validation is done with plugins.

When this hook runs for the node entity type, you will have an array of fields, one of which is title. You need to define a new validation constraint plugin. Model it on the unique feed title or unique username one and that way you'll only have to write one method and a property or two. Take note of your plugin's ID. When you're in that hook, call addConstraint on the title field, passing your plugin ID.

I have a feeling there's another hook too, maybe hook\_entity\_base\_field\_info\_alter, but I could be wrong there. If you don't see title in the field list, check the api docs for a hook with base field in the name

# Answer
> 0 votes
You can check too node title validation https://www.drupal.org/project/node\_title\_validation

This module do this, you can see the way or reuse de module.

---
Tags: hooks, 8
---


title: How to add currency field?

text:
# Question
Title: How to add currency field?
With respect to the question, can anyone suggest a remedy for the same. How can I create a field for currency(with selecting currency and text field to enter the amount) considering the fact that there are multiple currencies.

I have tried adding prefix but it can input only a single value(for example $ or pound etc). I have also tried the currency module but it gives a single page with multiple currencies.

# Answer
> 0 votes
So to add a decimal field.

* edit your content type.
* manage fields
* add new field
* select Decimal from the Field Type dropdown, click the 'Save' button
* Change 'Scale' to 2. These are the cents, 'Save field settings' button.
* In the Prefix field add '$' and save settings.

# Answer
> 0 votes
You should install module 'currency', add a field of type Entity reference, and choose the 'currency' as the referred type.

---
Tags: 7, entities, i18n-l10n
---


# Question
Title: How to modify the D7 user login page html to remove the register and new password options for non-admins?
So, I'm maintaining a Drupal 7 site for which we recently switched the users over to SSO through a third-party OAuth provider. The implementation isn't fancy, but added a login link to what I assume is the standard login page with a tabs for "registration, login, and password reset."

What I would like to do is remove the menu options altogether for regular users, keeping just the OAuth login link and some additional text to inform users of new registration procedures. For admins, I would like to preserve the regular name and password based login options.

I am aware of the Tab Tamer module, but I'd like a little more granular control. I believe I need to approach this with hook targeting the login block, but I haven't found any examples on how to control what HTML in the block itself.

So, how to do modify the login block's HTML to remove the extra tabs for regular users, but preserve it for admin users?

# Answer
> 1 votes
I don't think you've thought this through. The standard login page (`/user/login`) only shows the login form when a user is *not yet logged in*. So if you want the ability for admin users to see the usual options on that page, you will need to show them to all users -- since you don't know whether or not the user is an admin *before* they log in. If a user is already logged in (whether through OAuth or standard login) they will not be prompted to log in again.

If, instead, you want to modify the user login options for *all* users, this can be accomplshed via `hook_form_alter()` in a custom module, replacing `MODULENAME` with the name of your module in the hook implementation:

```
function MODULENAME_form_alter(&$form, $form_state, $form_id) {
  if ($form_id == 'user_login_block' || $form_id == 'user_login') {
    // Your code to modify the form goes here
    $form['some_text'] = [
      '#markup' => '<p>Some text to inform users of new registration procedures</p>',
    ];
  }
}

```

**EDIT:** If you have never made a Drupal module before, don't be intimidated! The type of thing you're trying to do can be accomplished with a very small module.

Keep in mind that the Drupal Form API is basically just a bunch of PHP arrays.

To add markup to a form array, use the `#markup` form element as I've shown im my example above.

To remove an element from a form array, you can `unset()` that value before the array is rendered. For example:

```
<?php
unset($form['buttons']['preview']);
?>

```

I'm not sure what form elements you'll want to remove, but this technique should help.

This stuff is well documented on Drupal.org and all over this forum.

---
Tags: 7, theming, users, blocks
---


# Question
Title: How do I create a grouped exposed filter on a block?
I have both a "Galery" content type and a "Galery category" taxonomy. The taxonomy only has two terms, 'Video' and 'Photo' (picture).

When I create a Galery content type, I need to choose the galery category.

I created a view that would display an exposed form, that would allow the user to either pick one of the 2 available categories. A colleague helped me setting up a grouped search and customizing it. Here is how it looks:

However, when testing it, we realized nothing was displayed. Moreover, the `<Any>` choice does display everything, so I think I've wrongly set something.

If this helps, I'm using "better exposed form" with the "autosubmit" and "use ajax" functions enabled.

What is happening and how should I fix it?

Thank you in advance

# Answer
> 1 votes
Without trying to recreate your grouped search, I think it might be a logic error where your search will show all the results for Label `<Photo>` is one of "Photo" taxonomy term AND Label `<Video>` is one of "Video" taxonomy term.

What happens if you combine both of them into one item, where Label `<Type>` is one of "Photo" OR "Video" taxonomy terms? (If necessary, you can allow users to search both terms at once by allowing multiple selections on the single exposed taxonomy filter.)

# Answer
> 2 votes
In your view, make sure your exposed filter is not the gallery type field itself, but 'Has taxonomy term' filter with the taxonomy group vocabulary selected and then set the exposed grouped filters the same way.

---
Tags: views, 8
---


title: Change order item title in cart

text:
# Question
Title: Change order item title in cart
I would like to update the title of a order item before it's put in the cart to add some extra dynamic info for the user. I tried this but nothing changes.

In the onCartEntityAdd function:

```
$item = $event->getOrderItem();

// Some code to check that its the item I wanted then:

$newTitle = $item->getTitle() . ' - some extra info';
$item->setTitle($newTitle);

```

setTitle call does not seem to do anything, the title in the cart is still just the product name. The `getTitle()` call works though.

Thanks for any info.

# Answer
The problem is probably that you don't save the order item after updating the title.

Add `$item->save();` at the end of your code and it should work.
> 0 votes

---
Tags: 8, commerce
---


# Question
Title: Form state cache breaks dependency injection
I have a class that `extends FormBase` and there are 6 services that are injected into the class via Dependency Injection (DI). My problem is when I submit the form it says to a class property that normally should be injected, it's `NULL` and can't be called the `load()` function on `NULL`. However when I debug, I clearly see all the dependencies are injected to the class and saved to the properties, but until the execution reaches the validation/submit function somehow it became all property to `NULL`. Why does this happen? How can I use DI in the form validation/submit phase? I'm really thinking if this class is not a deserialized cached version...
Extra info this form also has an ajax function where the DI works fine.

I went a bit deeper into the system, after the classfinder creates my form with the injected things and saved into this place: `$form_state->getBuildInfo()['callback_object']`, I found it out the problem is the cache. (`/core/lib/Drupal/Core/Form/FormCache.php:149`)

```
  protected function loadCachedFormState($form_build_id, FormStateInterface $form_state) {
    if ($stored_form_state = $this->keyValueExpirableFactory->get('form_state')->get($form_build_id)) {
      // Re-populate $form_state for subsequent rebuilds.
      $form_state->setFormState($stored_form_state);

      // If the original form is contained in include files, load the files.
      // @see \Drupal\Core\Form\FormStateInterface::loadInclude()
      $build_info = $form_state->getBuildInfo();

```

The system loads the formstate from the cache with the following lines, the `$stored_form_state` contains the cached state, without any dependencies, and the `$form_state->setFormState($stored_form_state);` line overwrites my formstate which contains the right properties with the DI classes... And that's a problem.

# Answer
Haha, I've fount it finally. The problem was the properties were private. And the serialization trait wasn't able to save the values and when it loaded back it became null.
> 4 votes

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


# Question
Title: Composer installation of drupal console missing functions
I've been attempting to install drupal console for the first time ever. I was looking for a means of creating boiler plate modules, blocks etc.

My issue is when I have finished the installation process, the following list of functions seems incomplete according to everything I have read online. Incomplete because there is only one generate function and nothing to generate blocks, modules etc:

```
Available commands:
  about                        Displays basic information about Drupal Console project
  chain                        Chain command execution
  check                        System requirement checker
  exec                         Execute an external command.
  help                         Displays help for a command
  init                         Copy configuration files.
  list                         Lists all available commands
  server (serve,rs)            Runs PHP built-in web server
 database
  database:add (dba)           Add a database to settings.php
  database:client (dbc)        Launch a DB client if it's available
  database:connect (dbco,sqlc) Shows DB connection
  database:query (dbq,sqlq)    Executes a SQL statement directly as argument
  database:restore (dbr)       Restore structure and contents of a database.
 debug
  debug:chain (dch)            List available chain files.
  debug:dotenv                 Debug Dotenv debug values.
  debug:settings (dse)         List user Drupal Console settings.
  debug:site (dsi)             List all known local and remote sites.
  debug:update:composer (duc)  Displays current updates available from the composer file
 develop
  develop:contribute           Download Drupal + Drupal Console to contribute.
 docker
  docker:init                  Create a docker-compose.yml file
 dotenv
  dotenv:init                  Add support and required config to work with an .env file
 generate
  generate:site:alias (gsa)    Generates a site alias.
 quick
  quick:start                  Download, install and serve a new Drupal project
 settings
  settings:set                 Change a specific setting value in DrupalConsole config file
 site
  site:install (si)            Install a Drupal project
  site:new                     Download a new Drupal project

```

I used the following command:

```
sudo composer global require drupal/console:@stable

```

**Can anyone pleas advice me on how I can get a more complete list of functions?**

UPDATE:

I don't know if this error showing as the first output when *drupal* is executed in my terminal, has anything to do with my issue:

```
 [ERROR] Class Drupal\Core\DrupalKernel does not exist.

```

So far my attempts to google that error have turned up no solutions.

# Answer
> 2 votes
I'm having the same issue. Per some other posts, I've tried starting fresh

1. Deleted drupal/console from composer.json (in docroot)
2. Deleted composer.lock
3. Ran `composer require drupal/console:~1.0 --prefer-dist --optimize-autoloader`
4. Ran `composer update drupal/console --with-dependencies`

`vendor/drupal/console/bin/drupal` shows I've got 1.9.3, but the only generate command I get from list is gsa as shown in sisko's post. I get the same thing in both Drupal 8.5 and Drupal 8.7.

# Answer
> 1 votes
Drupal console is installed on a per Drupal project basis. Install it locally, not globally

```
cd my_drupal_project
composer require drupal/console

# run it from your vendor folder
vendor/drupal/console/bin/drupal site:status

```

If you are using Linux or OSX, you can add this line to your `~/.bashrc` or `~/.bash_profile` file

```
alias drupal="/var/www/my_drupal_project/vendor/bin/drupal"

```

The above alias is just an example - you will need to adjust the exact directory path that the alias points to.

---
Tags: 8, console
---


# Question
Title: Why do I get Template "@bartik/block" is not defined?
So I've created a small subtheme called `bartik_graphql`. It just overrides the 'Powered by Drupal' block. Besides it's `bartik_graphql.info.yml` file it has a `templates` directory containing one file `block--bartik-graphql-powered.html.twig`.

Contents of `block--bartik-graphql-powered.html.twig`:

```
{#graphql
query {
  admin:userById(id: "1") {
    name
  }
}
#}

{% extends "@bartik/block" %}

{% block content %}
  <div{{ content_attributes.addClass('content') }}>
    {{ content }} and some guy named {{ graphql.data.admin.name }}
  </div>
{% endblock %}

```

I've enabled my subtheme and set it to default. However I receive the following error:

> Twig\Error\LoaderError: Template "@bartik/block" is not defined. in Twig\Loader\ChainLoader-\>getCacheKey() (line 122 of web/core/themes/bartik/templates/page.html.twig).

What I expect to happen is have my subtheme's template override what is used by default to display the 'Powered by Drupal' message.

Drupal: 8.7.8
PHP: 7.2.17

Am I using extends wrong here?

# Answer
> 1 votes
I didn't know of Twig namespacing just until now. But what always worked for extends and includes is to point to the template you want to extend/include directly, with the path starting from Drupal web root. So in your case it needs to say:

```
{% extends "core/themes/bartik/templates/block.html.twig" %}

```

You could also try the following which seems to follow theme inheritance but only up to the final base theme (which would be Classy).

```
{% extends "@block/block.html.twig" %}

```

---
Tags: 8, theming
---


title: Different shipping $ for west coast

text:
# Question
Title: Different shipping $ for west coast
Let me just preface this by saying I know nothing of Drupal. I am a wordpress developer but my company just inherited 2 drupal sites from a company we recently purchased. I am using Drupal 6.25. I have 2 classes of products that I need to change shipping for. It's free for US east coast and $199 for US west coast. There was a generic free shipping already set up and working but I need to change for the shipping increases. I tried using the flat rate and conditions but I kept getting "Invalid option selected. Recalculate shipping quotes to continue". I set up west coast fine. I did 2 groupings - a main AND group with 2 OR groups in that - 'or' for the shipping states and 'or' for the 2 product classes. I disabled the previous free shipping and the west coast works fine. I set up a separate shipping for east coast just like the west coast but opposite states. It works fine if I disable the West Coast. So, obviously I am doing something that is conflicting when both are enabled.

Any and all advice is greatly appreciated!

# Answer
> 0 votes
This is not an answer, just advice: Drupal 6 has been unsupported since February of 2016 - close to 4 years now. I strongly suggest you spend your efforts upgrading to Drupal 7 right now, if nothing else because of all the security fixes (which are super important on an e-commerce site!).

The D6 -\> D7 upgrade is relatively easy to do for most sites. I do not recommend going directly to Drupal 8 right now because that will be very long and painful process especially if you have little Drupal experience. If you want to move to D8, it would probably be easier to rebuild the site from scratch.

---
Tags: 6, ubercart
---


title: CKeditor adds extra <p> tags

text:
# Question
Title: CKeditor adds extra <p> tags
CKeditor adds many `<p>&nbsp</p>` tags for all new lines when editing as HTML source. I found a discussion:

http://drupal.org/node/669114

But I don't understand, how to fix it. If anybody fixed this, please, tell me, what should I write in CKeditor config file.

# Answer
> 6 votes
You need to set ckeditor configuration setting

```
config.enterMode

```

to proper value

(1) The default creates a paragraph element each time the "enter" key is pressed:

```
config.enterMode = CKEDITOR.ENTER_P; // inserts <p></p>

```

(2) You can choose to create a "div" element instead of a paragraph:

```
config.enterMode = CKEDITOR.ENTER_DIV; // inserts <div></div>

```
* The setting that you are looking for *

(3) If you prefer to not wrap the text in anything, you can choose to insert a line break tag:

```
config.enterMode = CKEDITOR.ENTER_BR; // inserts <br />

```

The application developer indicates that using the ENTER\_BR setting is not recommended. http://docs.cksource.com/ckeditor\_api/symbols/CKEDITOR.config.html#.enterMode

There are three more settings that are somewhat related to this subject:

```
config.fillEmptyBlocks
config.forceEnterMode
config.ignoreEmptyParagraph

```

A complete list of the available configuration options can be found here: http://docs.cksource.com/ckeditor\_api/symbols/CKEDITOR.config.html

# Answer
> 4 votes
The answers on this question are correct, but they don't explain how to implement this in a Drupal-way:

If your ckeditor is printing this:

```
<p> </p>

```

You indeed need to change the configuration of ckeditor to stop filling empty blocks: So `config.fillEmptyBlocks = false;` is correct, but you need to tell Ckeditor's implementation that in to Drupal.

You can do this by writing a `hook_editor_js_settings_alter` as follows:

```
/**
 * Implements hook_editor_js_settings_alter().
 */
function HOOK_editor_js_settings_alter(array &$settings) {
  // inspect which settings the editor currently has
  // kint($settings['editor']['formats']['basic_html']['editorSettings']);
  $settings['editor']['formats']['basic_html']['editorSettings']['fillEmptyBlocks'] = false;
}

```

This will force CKeditor to output instead:

```
<p></p>

```

Which means you could target and hide them with CSS as follows:

```
p:empty {
  display: none;
}

```

# Answer
> 0 votes
Most of the writers at my work use MS Word to write articles and then they paste it into the CKEditor WYSIWYG. If you install and enable the Ckeditor Paragraph Paste Fix module it will remove the the `<p>&nbsp</p>` in real time.

# Answer
> 0 votes
I believe you are talking about the "Enter mode" in CKEditor setting. You got `<p>` everytime you use "Enter". You can change the "Enter mode" from `<p>` to `<br>` with the following steps.

1. go to "Configuration \> CKEditor"
2. edit a input format (if you use Full, edit the Full input format)
3. under "Cleanup and Output" setting, change the "`<p>`" to "`<br>`" on "Enter mode".
Done

# Answer
> 0 votes
In the **"Advanced options"** section of CKEditor profile add this:

```
config.fillEmptyBlocks = false;

```

---
Tags: 7, wysiwyg
---


# Question
Title: Odd problems with Drupal 8.7.7 and drupal/jsonapi 2.4.0
I share a release branch with a team of developers and I am the only one having this problem locally (see below).

```
$ git reset --hard origin/2019-Oct-R2
HEAD is now at 8e5cec59b1 WWW-1599 update spoke service definition and update jsonapi module
$ git status
On branch 2019-Oct-R2
Your branch is up to date with 'origin/2019-Oct-R2'.

nothing to commit, working tree clean

```

At this point I am on the latest release branch with no tracked or untracked files (same as my colleagues), I then try this:

```
$ composer update nothing
Gathering patches for root package.
> DrupalProject\composer\ScriptHandler::checkComposerVersion
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Conclusion: remove drupal/core 8.7.7
    - Conclusion: don't install drupal/core 8.7.7
    - don't install drupal/core 8.7.7|remove drupal/jsonapi 2.4.0
    - don't install drupal/jsonapi 2.4.0|don't install drupal/core 8.7.7
    - don't install drupal/jsonapi 2.4.0|don't install drupal/core 8.7.7
    - Installation request for drupal/core 8.7.7 -> satisfiable by drupal/core[8.7.7].
    - Installation request for drupal/jsonapi (locked at 2.4.0, required as ^2.4) -> satisfiable by drupal/jsonapi[2.4.0].

```

Can anyone interpret this error message for me?

# Answer
Composer is showing those error messages because you are updating to Drupal 8.7.7 and the JSON:API module is a requirement the composer.json file contains. (That is why the error message says *locked at 2.4.0, required as ^2.4*.)

Since the module is now part of Drupal core (as the project page and the release notes for version 8.x-2.4 say), updating to Drupal 8.7.7 would cause the module version to be updated to 8.7.7. (The version of every Drupal-core module is the Drupal version.) That is not allowed from the composer.json file which, with a restriction like ^2.4, just allows versions that aren't higher than 2.

Editing the composer.json file to accept any version of that module would avoid those error messages.
There would still be the problem of having two versions of the module installed in two different directories. I would rather uninstall the module before updating Drupal, but I am not sure how it would possible to preserve the module settings.
> 1 votes

---
Tags: 8, composer
---


# Question
Title: How to know add/edit page in hook_form_alter?
I want to know whether form is add/edit in hook\_form\_alter. In Drupal 7 we can get all these in hook\_form\_alter.

I tried like this in D7:

```
function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
  // Check pages(s) , don't use $_GET.
    if (strpos($form['#action'], '/add/') !== FALSE) {
      $page = 'add';
    }
    if (strpos($form['#action'], '/edit') !== FALSE) {
      $page = 'edit';
    }
}

```

Here I am getting add/edit in D7. Whereas in D8 I am not getting any it in $form\['#actions'\]. And i don't want to use $\_GET. Is there any way to check add/edit page in hook\_form\_alter.

# Answer
> 9 votes
In D8 you can get the operation of an entity form with the form object:

```
function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
  if ($form_state->getFormObject()->getOperation() == 'edit') {
    $page = 'edit';
  }
}

```

# Answer
> 10 votes
If you want to check for being on 'add' form, it is also possible to check that the entity is new, i.e.

```
function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
  if ($form_state->getFormObject() instanceof EntityForm) {
    $entity = $form_state->getFormObject()->getEntity()
    if ($entity->isNew()) {
      //your code
    }
  }
}

```

# Answer
> 1 votes
AFAIK you should always check the form\_id and not using `$form['#action']`.

```
function MODULE_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  if ($form_id == 'your_form_id') {
    // your code
  }
}

```

I'm not sure of the node edit/add form ids, you can use `dpm($form_id)` if you devel module or just use `print_r($form_id)` to find the `form_id`.

# Answer
> 0 votes
You can also tell by the $form\_id which is already present in the hook\_form\_alter.

$form\_ids for nodes usually look like this:

* node add = node\_NODE\_TYPE\_form
* node edit = node\_NODE\_TYPE\_edit\_form

So just use conditional logic for what you need and this is faster then using other methods listed in this.

---
Tags: 8, entities
---


# Question
Title: Modify the error message about the maximum upload file size
I would like to modify the default error message for the maximum upload file size, but I can't find the configuration.
I looked at webform general settings, individual settings, and media file settings, but I found nothing about it. Forum issues only talk about configuration of the maximum file size, not about customization of the error message.

Can anyone help me?

# Answer
> 0 votes
As far as I know, there is not a way to add a validation handler for the file field type in general. You'll need to set a hook form alter and add a custom form validate handler for the edit forms, webforms, etc that you want to override.

Refer to: How do I add a custom validation handler to an existing form/field?

Alternatively, if your site is a multilingual site configured for internationalization, you can probably override the english version of the message in the. po file. I would advise against installing and enabling internationalization just for this use case, as it adds several pieces of functionality to the site and can bloat your database.

---
Tags: files, status-messages
---