# Question
Title: For content, what are the differences between nodes and terms
I am debating whether to use nodes or terms to store a large amount of content in Drupal.

There are a lot of similarities between nodes and terms in Drupal 8/9:

* Both can add any type of field.
* Both can have URL aliases set automatically via Pathauto.
* Both can have customized metatags via Metatag.
* Both can have comments.
* Both can have the displayed customized with Layout Builder, and both can be themed in the same way with Twig templates.
* Both have content types (nodes have "content types", terms have "vocabularies").

They seem very much alike. So what are the differences between terms and nodes?

# Answer
> 4 votes
# 1 -node VS taxonomy\_terms

both **node** and **taxonomy\_terms** (terms), are a **content entity types** so they both used to store content , but form a semantic point of view :

1. **node ( Content )**: are used to store a content because their **base fields** and related entities are intended for that purpose ex :

* ***created***: when the content has been created?
    * ***changed***: when the content has been changed?
    * ***sticky***: do you want o make this node stick to the top of others?
    * **Authored by**: who writes this content?
    * **Authored on**: when the content has been created?
2. **taxonomy\_terms ( Classification ):** is used to store **classifications** *(grouping content that shares same properties in the same group)* because their **base fields** intended for that purpose ex :

* ***name***: the category group name that will be used to group a set of nodes or other entities.
    * ***URL alias***: a link to a page that will contain all the nodes that belong to this category.
    * also, we can use the taxonomy Hierarchical (tree) structure for a nested classifications

> SO NODE MUST BE USED TO STORE CONTENT AND TAXONOMY TERMS TO STORE CAISIFICATIONS.

---

# 2- Performance problem with node

if you will save a large amount of content as a node you'll have a big performance issue, let's say you have a web service that consumes a thousand of tweets and save them as nodes this will cause a big performance problem because :

when we want to retrieve a node tweet a long database query journey will be traveled :

1. get node basic information (nid, vid..) from the entity type base table: **node** table
2. get node base fields(title,created...) from the **node\_field\_data**
3. get each field from **node\__field\_$fieldName** , let's say we have 10 fields in each field are in a separate table ( 10 tables)

also, another performance problem since any site will have more than 1 node bundle (article, page, news) beside the one that you will add ex (tweet) each SQL query executed against the DB to read data will loop through all these bundle instances (article, page, news) before getting your tweets.

---

# 3- Custom entity type

the best solution if you have a large amount of content :

Creating a **bundle-less entity type** for fast data retrieving without losing the node editing power because you can keep this property:

* content will be translatable.
* content will be revisionable.
* content can be integrated with the view.
* they can be administrated from BO just like a node.
> note: the fast way to generate a custom entity type with Drupal console, using: **generate:entity:content** then set Do you want **this (content) entity to have bundles? (yes/no) \[no\]: \>no**

# Answer
> 4 votes
Nodes are content. Terms are for categorization of content, they are not content themselves.

Terms are part of taxonomies. Taxonomy is the science of classification.

The relation between nodes and taxonomy terms is that you attach taxonomy terms to nodes, to categorize the node. So if you have a blog node, you may have topics or tags, that would be attached to the blog node. You can use that to find all blogs of a certain category, or tagged with a given term. You can think of hashtags on common SNS sites as being like taxonomy terms. When you click on the hashtag, you can see all posts with that hashtag. The hashtag essentially categorizes the post.

You have listed some ways in which nodes and terms share technical implementations, such as having revisions. But how they are used is entirely different.

# Answer
> 1 votes
Here are the differences I have identified between terms and nodes so far.

**Authoring information + promotion options**

* Nodes offer "Authoring information" to change the node author and/or publishing date; taxonomy terms do not. This means that if you want to reference the author of a term, or the publication date, you have to do something like add fields to each vocabulary and roll your own solution, which is a real mess.
* Nodes have a UI option to promote content to the front page and to keep it a sticky at the top of lists. Taxonomy terms don't provide this out-of-the-box, but their display can be customized with Views and they have built-in support for hierarchies, so they don't need *sticky at the top of lists*.

**Hierarchical (tree) structure**

* Taxonomy terms are hierarchical within a vocabulary by default. This can be used to provide a menu automatically with modules like Taxonomy Menu or Hierarchical Taxonomy Menu.
* Nodes can be given a hierarchical structure in a menu (the menu contains the hierarchy), but the nodes themselves cannot be ordered in a hierarchy without some kind of custom system relying on entity references.

**Revisioning**

* Nodes have a revisioning UI and you can easily roll back to previous versions.
* Taxonomy terms have revision tracking enabled by default but there is no UI available yet. This will change someday.

**Menu support on the edit page**

* Nodes can easily be added to a menu on the edit page.
* To add a term to the menu, you have to create the term first and then manually create a link on the menu you want to add the link to.

---
Tags: nodes, taxonomy-terms
---


# Question
Title: How to fix this error in drupal: ajax: ajax.form.ajaxSubmit is not a function
I am creating a form with ajax submission in my Drupal custom form module.

When I click my submit button, I get the following error:

> ajax: ajax.form.ajaxSubmit is not a function.

I am searching some blogs, try something like uninstalling lightbox2 module, color box module, etc. But again the same error is displayed.

How can fix this error?

**Note**: I installed Lightbox first, but after this error I uninstalled it again.

# Answer
> 3 votes
In Drupal 8:

```
   function YOURMODULENAME_page_attachments(array &$attachments) {
      global $base_url;
      $attachments['#attached']['library'][] = 'core/jquery.form';
      $attachments['#attached']['library'][] = 'core/drupal.ajax';
      $attachments['#attached']['library'][] = 'MODUL/login_module';
      $attachments['#attached']['drupalSettings']['LoginModuleBehavior']['base_url'] = $base_url;
    }

```

# Answer
> 1 votes
You'll need to include the Drupal ajax `drupal_add_library('system', 'drupal.ajax');`

# Answer
> 1 votes
For future readers, you may need to include these libraries:

```
drupal_add_library('system', 'jquery.form');
drupal_add_library('system', 'drupal.ajax');

```

For example:

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

  $form['#attached']['library'][] = array('system', 'jquery.form');
  $form['#attached']['library'][] = array('system', 'drupal.ajax');

}

```

# Answer
> 1 votes
**Drupal 8**

Drupal 8 does not include JS-libraries to pages automaticly. So most probably if you meet this error you need to attach 'drupal.ajax' library to your page (or form). Add something like this to your render array:

```
$form['#attached']['library'][] = 'drupal.ajax';

```

# Answer
> 1 votes
### Drupal 8

For people coming from Google and looking for a D8 solutions, try:

```
$form['#attached']['library'][] = 'core/drupal.ajax';

```

# Answer
> 1 votes
I disabled JavaScript aggregation in the performace config and it fixed my issues with this error in Drupal 8.

---
Tags: 7, ajax
---


title: Creating content with a hierarchy

text:
# Question
Title: Creating content with a hierarchy
I want to create hierarchical content in Drupal, and I am trying to decide between nodes and terms.

**What I want to do**

I want to implement books.

Each piece of content may be a book (containing chapters) or a chapter (containing pages) or just a page.

These various pieces of content should be related to each other in a tree (the tree will be stored in a menu).

For nodes, I am thinking of using a single content type that contains an entity reference field (children) to store the hierarchy between books, chapters, and pages.

**Why I am not using the book module**

The navigation links provided by the book module in Drupal 8/9 do not follow the same design patterns as the rest of core (the navigation is not a block, and it's not a menu). Out of the box, you can't even choose where book navigation is displayed (it is displayed on the node's full view mode only). Since the Book module went from 8.0 to 8.8 with basically no changes, it seems to have survived only by preserving compatibility with Drupal's past. Book doesn't even have enough interest to get its own tag here on Drupal Answers.

**Why hierarchical content, not navigation**

In addition to being displayed on the website, all this content needs to be formatted for export as an ebook. I have already written working code for this using twig templates and preprocess functions.

Having the hierarchy in the content makes writing the ebook export a lot easier.

**Terms vs. nodes**

So, I am trying to decide whether to use terms vs. nodes. I already asked a general question about terms vs. nodes for content. The consensus there was "use nodes for content, and terms for organizing the content."

**But which should you use if that organizational hierarchy is part of the content?**

# Answer
> -1 votes
Here's my examination of the advantages and disadvantages of each type.

**Implementing the book as nodes**

* An entity reference field **children** needs to be added to the node content type to store the hierarchical relationship.
* Menus must be created separately that match the hierarchy. Now the hierarchy is stored in two places, in the menu listing the nodes and in the node itself. This duplication of data could be a maintenance issue if people are not careful because now the position must be changed in two places.

**Implementing the book as taxonomy terms**

So if the goal is to have a hierarchical (tree) relationship among content, it seems like terms offer an easier-to-maintain solution than nodes. This is semantically incorrect ("terms" suggests "categories of content," not "content"), but from a technical maintenance standpoint, this way appears easier.

---
Tags: nodes, taxonomy-terms
---


# Question
Title: How to create a eCommerce site products slideshow using views
Environment: D8 with commerce module.

I am working on a eCommerce website. I created a view to display the products as unformatted list. How can I change it to a slider/slideshow view? Each slide should have 5 products info. Each product of the slideshow should contain title, list price, catalog image, short desc.

Current view:

How the view should look like with the slider:

How can I modify the view to make it a slideshow like the above design?

--

Update 1

# Answer
You can use view\_slideshow module

https://www.drupal.org/project/views\_slideshow

Before installing read README.html file present in the module. you can achieve the required output.

If you need more customization in the slider, you can use

https://owlcarousel2.github.io/OwlCarousel2/ also...if above one does not satisfy your requirement.
> 0 votes

---
Tags: views
---


# Question
Title: Why should I not put content in the development environment?
I've previously been told that I should not put content on Pantheon in the development environment.

The reason was not explained.

Can anyone think of any reason that this should be advised?

I can see that pulling/pushing a lot of content form the /files directory could be and issue but is there any other reason that anyone can think of?

# Answer
I think that either what you were told was not explained correctly, or that you misunderstood.

You can put content on development environments. And you should, to test.

But that content won't be migrated to production. If you want that content on production, you'll need to create it on production. Or, you can create a migration strategy (using the Migrate UI for example) to migrate content between environments. But this generally takes a good bit of work, and isn't usually done.
> 1 votes

---
Tags: migrations
---


# Question
Title: How can I track how embedded media is used across my site?
My site uses the core Media module, Entity Embed, and LinkIt to reference media and other entities in various ways.

I want to keep track of which media is embedded on which nodes.

I tried adding an entity reference field to media on my content types, but this means that I have to add the media twice: to the field where I actually embed the media and to the entity reference field to track it.

Is there a better way?

# Answer
> 3 votes
First, there is a core issue to eventually get this into core.

Now, the best way is to use the Entity Usage module, which can handle tracking of media and many other cases.

Hats off to the module maintainers-- this is all I needed to do to implement my use case:

1. Download the module with composer.
2. Enable the module.
3. Go to `/admin/config/entity-usage/settings` and check **Media** under **Enabled local tasks**.

---
Tags: nodes, media
---


title: How can show pdf preview first image?

text:
# Question
Title: How can show pdf preview first image?
Hope you can help me.

I use drupal 8.

I want pdf preview like this http://prntscr.com/j08ljo.

Need uploud pdf file in node and showing just first image in front page.

I check use module pdfpreview https://www.drupal.org/project/pdfpreview

Have with tutorial and dependence. Setup ImageMagick and configured it in image toolkit. Sent in server files with imagemagick and write path.

"Path to the package executables" ... http://prntscr.com/j08ogh

After this showing in display manage full content "pdf preview" http://prntscr.com/j08r9i  But nothing happened. I hear about "may be i need install for other way imagemagick"

Can you help me?

Thanks for your future answers.

# Answer
You have to firstly install imagemagick in your operating system. for Ubuntu please follow below procedure:-

(1)https://medium.com/@sanjaywrites/install-latest-version-of-imagemagick-in-ubuntu-16-04-c406ddea1973

(2) https://www.enovate.co.uk/blog/2015/12/16/how-to-install-imagemagick-from-source-on-ubuntu-14.04

For window download imagemagic exe file. https://imagemagick.org/script/download.php

once your Operating System have magicmagick then install these module pdfpreview https://www.drupal.org/project/pdfpreview

and do a needful change as shown in image

and on your view do a needful change as shown in image
> 0 votes

---
Tags: 8, theming
---


# Question
Title: How can I design the standard user login form with twig?
I want to **change the labels** "*Username*" and "*Password*" and **delete** "*Create new account*" link of the standard login form of Drupal 8. Is it possible to do this with twig?

# Answer
> 3 votes
I found the solution how to **add user and password placeholders** an **modify user and password labels**:

```
function THEMENAME_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  if ($form_id == 'user_login_form' ) {
    // Add placeholders.
    $form['name']['#attributes']['placeholder'] = t('User Placeholder Text Here');
    $form['pass']['#attributes']['placeholder'] = t('Password Placeholder Text Here');

    // Labels
    $form['name']['#title'] = t('User Label Here');
    $form['pass']['#title'] = t('Password Label Here');

    //Submit Value
    $form['actions']['submit']['#value'] = t('Submit Button Text Here');
  }
}

```

To remove "*Create new account*" and "*Reset your password*" links, just override **block--user-login-block.html.twig** file. Change

```
{{ content }}

```

to

```
{{ content|without('user_links') }}

```

# Answer
> 2 votes
To remove the "Create new account" function permanently, using Twig or render hooks is not enough: Drupal-savvy visitors may type the correct URL directly in their browsers. There are bots that attempt to create accounts automatically.

To remove the "*Create new account*" link **AND** disable account creation, go to Administration » Configuration » People and find the option "Who can register accounts?". Set it to "Administrators only".

# Answer
> 1 votes
@leymannx and @Gogowitsch have answered the original question quite admirably. However, OP has added another question in the comments:

> I want to place a custom register link somewhere else and just remove the standard login form link. I don't want to hide it with css

Since OP wants to change not only the login form, but also the URL, the Login Switch contributed module might be just what they are looking for.

> **Login Switch**
>
> This module will allow you to change the default login URL and disable the normal /user/login route built into core. Hackers today know all the usual entry points for the common CMS systems so the first step to securing your site it is to change the entry they know about.

This could be used in combination with the `hook_form_alter()` of the `$form_id == 'user_login_form'` recommended in the comments above.

# Answer
> 0 votes
Yes, you change the labels "Username" and "Password" by using stringoverrides module https://www.drupal.org/project/stringoverrides or you will able to hide or delete "Create new account" using twig and css.

---
Tags: theming
---


# Question
Title: Call to a member function getRoles() on array while using loadByProperties()
I am trying to check if the email provided by a user using a custom webform is already associated with an account on my site. In the case it's used, I want to get the roles of the account using that email.

I am using the following code.

```
$email = "someone@example.com";

// Loads existing Drupal user object by given email.
// Note that first matching user is returned. Email address and account name
// are unique so there can be only 'zero' or 'one' matching user when
// loading users by these properties.

// Load entities by other than entity ID.
$users = \Drupal::entityTypeManager()
  ->getStorage('user')
  ->loadByProperties(['mail' => $email]);

// if 'One' user has been found matching the given email.
if (!empty($users)) {

    // Set the disabled roles.
    $disabled_roles = array ("administrator", "content_approver");

    // Loop through all roles the user has.
    // The following is the line causing the error (line 74).
    foreach ($users->getRoles() as $role) {
        // Check if the user has one or more disabled role.
        if (array_key_exists($role, $disabled_roles)) {

           // Extra codes goes here.

        }
    }

```

I get the following error.

> Error: Call to a member function getRoles() on array in Drupal\custom\_module\Controller\EmailCheckController-\>EmailCheck() (line 74 of /home/users/public\_html/example.com/web/modules/custom/custom\_module/src/Controller/EmailCheckController.php)

What is wrong with my code? How can I get the roles of the user accounts I load?

# Answer
> 4 votes
`EntityStorageInterface::loadByProperties()` returns an array of objects, and it returns an array regardless of the number of results. Even if you have one result (which I am guessing is what you're expecting) you get an array back.

You can't call `getRoles()` on an array. You'll need to get the objects from the array before you do that. For example, on `EntityStorageBase::loadByProperties` a commenter uses `$first_match = reset($entities);`.

---
Tags: 8, users
---


# Question
Title: Custom tokens breaking on node save with "node entity cannot have a URI" error
I'm getting a crash on node save when my node contains a custom token. I'm using the Token Filter module to display tokens in node content.

To make the tokens I followed this tutorial, which is similar to the Token documentation.

Now, with Drupal 8.8, when I save a new node that contains one of my custom tokens, I get a WSOD with this error:

> Drupal\Core\Entity\EntityStorageException: The "node" entity cannot have a URI as it does not have an ID in Drupal\Core\Entity\Sql\SqlContentEntityStorage-\>save() (line 846 of core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php).

But the real error appears to be from token:

```
Drupal\Core\Utility\Token->generate('ebook', Array, Array, Array, Object) (Line: 196)
Drupal\Core\Utility\Token->replace('
Test [ebook:custom-type] 2

', Array, Array, Object) (Line: 130)
Drupal\token_filter\Plugin\Filter\TokenFilter->process('
Test [ebook:custom-type] 2

', 'ja') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 100)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. Support for this callback implementation is deprecated in 8.8.0 and will be removed in Drupal 9.0.0. See https://www.drupal.org/node/2966725', 'silenced_deprecation', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 781)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 372)

```

Weirdly, if I remove the token from the body field when I save the node, the node saves properly-- and then I can edit the node and add the token back in without any error. The error only occurs when the node is saved and it has a token in it.

Drupal tokens like `[site:name]` work fine; it's just my custom token that causes an error.

Here's the relevant code:

```
/**
 * Implements hook_token_info().
 */
function MYMODULE_token_info() {

  $ebook_type = [
    'name' => t('Custom Tokens'),
    'description' => t('Tokens to make upgrading to D9 harder.'),
  ];

  $ebook['custom-type'] = [
    'name' => t("Custom type"),
    'description' => t('Apples or oranges'),
  ];

  return [
    'types' => ['ebook' => $ebook_type],
    'tokens' => ['ebook' => $ebook],
  ];

}

/**
 * Implements hook_tokens().
 */
function MYMODULE_tokens($type, $tokens, array $data, array $options, \Drupal\Core\Render\BubbleableMetadata $bubbleable_metadata) {

  $replacements = [];

  if ($type == 'ebook' && !empty($data['node'])) {
    foreach ($tokens as $name => $original) {
      switch ($name) {
        case 'custom-type':
          $replacements[$original] = MYMODULE_token_set_custom_type($data['node']);
          break;
      }
    }
  return $replacements;
}

function MYMODULE_token_set_custom_type($node) {
  $alias = $node->toURL()->toString();
  preg_match('(/.*/)', $alias, $matches);
  if ($matches[0] == '/apples/') {
    return "Apples";
  }
  else {
    return "Oranges";
  }
}

```

How do I resolve this?

# Answer
> 1 votes
If the token is being generated before the node has been saved, this will cause a WSOD, since no URI can be created for the node. Entity URIs require an entity ID to built the path to the entity.

As such, I'd change your code to:

```
function MYMODULE_token_set_custom_type($node) {
  if ($alias = $node->toURL()->toString()) {
    preg_match('(/.*/)', $alias, $matches);
    if ($matches[0] == '/apples/') {
      return "Apples";
    }
    else {
      return "Oranges";
    }
  }
}

```

# Answer
> 1 votes
Further debugging and the comment from 4k4 and the answer from Jaypan provided the hints I needed to solve this.

First, although this was caused by the token, it was also caused by the following call in `hook_node_presave()`:

```
function MYMODULE_node_presave(NodeInterface $entity) {

      $processed_display = \Drupal::service('renderer')->renderPlain($myspecialviewmode_render);
      $entity->set('field_text_main_display', $processed_display);
      $entity->field_text_main_display->format = 'processed';

```

It wasn't the token or this hook by themselves that was causing the issue, but their presence together.

To fix this, I rewrote my token to not rely on the URL at all.

---
Tags: tokens
---


# Question
Title: How can I show anonymous users their own content?
I've tried to reach this with views and https://www.drupal.org/project/session\_node\_access and https://www.drupal.org/project/views\_extras with no luck.

Any suggestions?

# Answer
An anonymous user is a user with `uid=0`. So *all* (repeat *all*) anonymous users have the same `uid` value, and therefor there is no way to do what you are asking for out of the box.

---

There are various techniques you could programmatically do, but of course they all have their limitations.

**Starting an anonymous session**. Here when the node is created you add the Node ID in a `$_SESSION` variable and you can use this to retrieve the Node ID and pass that to the views arguments. Obviously, the limitation is that as soon as you close the browser, the session ends and you can no longer tell if it's the same user. So you have to start the cycle again, create a new node, etc...

**Using cookies** same as above but with cookies. Once cookie expires or it's cleared it's over.

**Using IP** You would save the IP as a field in the Node and you can query the DB to retrieve the Node that belongs to that IP. Obviously, the limitation here is if the user's IP changes it ends here.

**Combination of all 3** Lastly, you could do all 3, have the other 2 as possible backups.
> 1 votes

---
Tags: views, 8, users
---


# Question
Title: Why does my admin page appear corrupted after using Backup and Migrate?
I recently restored a site backup using the Backup and Migrate plugin. Now my admin toolbar looks like this.

Flushing cache does nothing. How can I fix this?

# Answer
> 1 votes
If you forget to preserve the file permissions when restoring a backup, you'll run into this. Make sure you use tar's `p` flag when you extract the backup file. Run `drush ws` to see watchdog error logs and you'll find permission errors like this:

```
------ -------------- ------ ---------- ---------------------------------------------------------------------------------------------------------------------
  ID     Date           Type   Severity   Message
 ------ -------------- ------ ---------- ---------------------------------------------------------------------------------------------------------------------
  3436   26/May 18:43   php    Warning    User warning: mkdir(): Permission Denied in Drupal\Component\PhpStorage\FileStorage->createDirectory() (line 145 of
                                          /home/public/core/lib/Drupal/Component/PhpStorage/FileStorage.php) #0 /h

```

Fix the file and directory permissions, then rebuild the cache with `drush cr` and you should see:

---
Tags: 8, backups
---


# Question
Title: View only displays nodes that has comments when adding comment count field
On drupal 8 I am facing an issue with views.
I created a view listing all nodes of a certain content type.
I added basic fields, **Title, Date** content was created, and a **read more link**.
The view works fine with these fields, but when i add ***Comment Statistics: Comment count***, all nodes that don't have any comment don't show up in the view.
It only lists nodes that received comments.

Any idea on how to fix this ? Am I doing something wrong ?

Thanks

# Answer
> 1 votes
I think it is you. Unable to re-produce. Here is a example view listing content nodes, two fields and the comments count.

I also exported the example view example view that you can import and test out for yourself.

---
Tags: views, 8
---


title: Why am I forced to log in?

text:
# Question
Title: Why am I forced to log in?
I'm a long-time Drupal 7developer, and tried a Drupal 8 install yesterday for evaluation. I installed a bunch of contrib modules. All seems ok, but when I go to the home page, I'm presented with a login screen. I want anonymous users to be able to see the site, how can I allow this? I don't see any settings to force login, and am not using the shield module.

# Answer
D8 default front page is a view page `admin/structure/views/view/frontpage/edit/page_1`. Views in 7 and 8/9 is quite similar from a end user perspective meaning you should feel right at home. D7 and 8 default front page is /node as you see and normal access permission.
> 0 votes

---
Tags: 8
---


# Question
Title: Add a "Save" action in local task to a node
I would like to add a new action to local task on node. This new action has to save the current node.

I have drupal 8.8.0

I know how to add a new action.

But my question is about how to save the current edit node from it if it's possible.

My goal is to replace the "save" button at the bottom of the node on edit mode

# Answer
> 1 votes
Local tasks are the wrong tool for the job. Local tasks are for providing context-sensitive action links (e.g. Edit, Delete, View) around an item (e.g. node/user). Trying to make a local task become a form submission button would involve all kinds of hacks that probably would be more trouble than its worth.

If the goal is to alter the save button's position for UI concerns, look at using `hook_form_alter` to alter the appearance/positioning of the node form's **Save** button. For example, look at a module like Floating Action Buttons that uses a form alter to place the action buttons in a fixed location.

---
Tags: nodes
---


title: Can't get token replacement to work

text:
# Question
Title: Can't get token replacement to work
I have nearly this exact case but as it applies to Drupal 8: Store token replacement values in the database rather than tokens themselves).

I have a content type 'article' with a 'body' field which has been populated with tokens via the Token Filter module. I believe the code should be something like found here https://www.drupal.org/project/drupal/issues/2043055 but can't get it to work.

```
function MYMODULE_node_presave(Drupal\Core\Entity\EntityInterface $node) {
  if ($node->bundle() == 'article') {
    $body = $node->get('body')->value;
    $token = Drupal::token();
    $body = $token->replace($body);
  }
}

```

Thanks for considering, -c

# Answer
> 3 votes
Although I was unable to actually replace the tokens with the tokens' data in the database, I was able to figure out the ultimate goal which was to replace tokens in the email. This is the basic code (more details at https://www.drupal.org/forum/support/module-development-and-code-questions/2020-05-03/add-save-send-email-button-to-both#comment-13647867).

<pre><code>$node = \Drupal\node\Entity\Node::load($nid);  //load the current node
$token_service = \Drupal::token();  //get the Drupal token service which replaces tokens with tokens' data
$body_field_data = $node->get('body')->value;  //get the "text" (basic data) of the body field
$token_data = array(  //assigns the current node data to the 'node' key in the $data array; the node key is recognized by the Token service
  'node' => $node,
);
$token_options = ['clear' => TRUE];  //part of the Token replacement service; A boolean flag indicating that tokens should be removed from the final text if no replacement value can be generated
$params['body'] = $token_service->replace($body_field_data, $token_data, $token_options);  //sets the 'body' key of the $params array equal to the basic body field data plus replaces the tokens in the body field```
</code></pre>

# Answer
> 0 votes
You need to set the new value on the body, and save it.

```
function MYMODULE_node_presave(Drupal\Core\Entity\EntityInterface $node) {
  if ($node->bundle() == 'article') {
    $body = $node->get('body')->value;
    $token = Drupal::token();
    $body = $token->replace($body);
    $node->set('body', $body);
  }
}

```

---
Tags: 8, hooks, tokens
---


title: Delete 13000 nodes

text:
# Question
Title: Delete 13000 nodes
I have about 13000 nodes to delete in a Drupal 7 site. I have tried the *Views Bulk Operations* module to delete 500 nodes at a time, but it times out. I can only delete 50 nodes at time.

How can I delete more than 50 nodes at time?

# Answer
VBO is the de facto standard for bulk-deleting nodes, there simply isn't a better way to do it.

As VBO processes in batches it only does 1 (or maybe a couple) of nodes at a time. So if you're receiving timeout errors those are related to the deletion of a *single* node, not to the entire batch operation.

The standard resolution to something like this is to increase the PHP max execution time to compensate.
> 18 votes

# Answer
Install Devel. Then go to admin/config/development/generate/content in D7 and select all content type. Check "Delete All content". Enter 0 in "How many nodes would you like to generate? "

Click Generate.

That'll delete all nodes.
> 8 votes

# Answer
Use a VBO and execute it from Drush. I used the following method to delete over 1.5million nodes after scale testing.

1. Create a new view with a page. Set the filters appropriately to display only the type of nodes you'd like to delete.
2. Add a new field: "Bulk operations: Content"
3. Check the box next to "Delete item" under 'Selected bulk operations'.
4. Save the view.
5. Assuming you know how to use Drush, run this command: (Use a linux 'screen' to run uninterrupted for big datasets)

**drush vbo-execute *my\_view* action::views\_bulk\_operations\_delete\_item**

Where, *my\_view* is the machine name of your view

You can also use **drush vbo-list** to display all available views and their bulk operations.

The VBO should now run in the shell, giving you feedback as it goes.
> 5 votes

# Answer
There is a Delete All module out there. It will delete all the nodes and/or users from the site.

It also has Drush support:

Examples:

```
drush delete-all article             Delect all article nodes.
drush delete-all all                 Delete nodes of all types.
drush delete-all --reset             Delete nodes of all types, and reset node, revision and comment counters.
drush delete-all users               Delete users.

```
> 3 votes

# Answer
Use Views Bulk Operations - it was a good idea. But instead of calling operation directly, use batch api. Here you can read shor article about it. Lack of documentation on that part was a known problem.
> 1 votes

# Answer
For deleting nodes in large number(i.e is bulk) like in your case, you could also use Bulk delete module for this.

That will use the Batch API to delete the nodes to avoid timeout or memory issues when deleting thousands of nodes with a single call to node\_delete\_multiple().

Apart from this,you can even try Delete all module for deleting all the nodes of a content type.

Hope this helps.
> 1 votes

# Answer
You can also create batch process for it using BATCH API and in that batch process just do

```
foreach($nodes as $node){ node_delete($node[nid]);}

```

Thats it. You are done here. If you wish to create a drush command for it, you can also create it. For reference please look at this.
> 1 votes

# Answer
If you have reason to do it by code:

```
$query = new EntityFieldQuery();

$query->entityCondition('entity_type', 'node')
  ->propertyOrderBy('nid', 'DESC')
  ->range(1000, 1000);

$result = $query->execute();
node_delete_multiple(array_keys($result['node']));

```

You also have many other available methods to select nodes to delete.
> 1 votes

# Answer
You can take Bobik's advise and feed that as the argument of a 'drush php-eval' if you're really in a pinch, but I would expect that the performance will be similar to that of VBO, while being slightly faster. If performance is really slow, you might wish to take a look at what modules are calling hook\_node\_delete by grepping the codebase for '\_node\_delete(' and then determining whether or not you can disable some of the modules which are using that hook.
> 1 votes

# Answer
On Drupal 8, an other way is to delete multiple entities without loading them all at a time but by chunk.

You can use less memory and have great performance :

```
$nids = \Drupal::entityQuery("node")
  ->condition("type", "my_bundle")
  ->execute();

$storage_handler = \Drupal::entityTypeManager()->getStorage("node");

if (!empty($nids)) {
  foreach (array_chunk($nids, 50) as $chunk) {
    $nodes = $storage_handler->loadMultiple($chunk);
    $storage_handler->delete($nodes);
  }
};

```

For more convenience, you can trigger it inside drush command php-eval :

```
drush php-eval '$nids = \Drupal::entityQuery("node")->condition("type", "my_bundle")->execute(); $storage_handler = \Drupal::entityTypeManager()->getStorage("node"); if (!empty($nids)) {   foreach (array_chunk($nids, 50) as $chunk) { $nodes = $storage_handler->loadMultiple($chunk); $storage_handler->delete($nodes); }};'

```
> 1 votes

---
Tags: nodes
---


title: Pager labels aren't translated

text:
# Question
Title: Pager labels aren't translated
I have a site using Drupal 8.4.1 with all core language modules enabled, 3 active languages, and where English is the default language. The pager labels (e.g. "Last »") for my own views aren't translated, although the string "Last »" is available in the translation page. I can manually translate the pager labels by adding a translation for the whole view and then overriding the pager labels, but I think this isn't the right way to do it because the built-in views (e.g. /admin/content) are translated just fine, without any manual override.

How can pager labels be translated without manually adding the translation?

# Answer
> 0 votes
I have seen this too. Looking thru the code, it appears that the pager templates do have translations set up properly. So in theory, UI translations should work. But they don't.

I haven't tried it but you probably could do this thru the `hook_preprocess_pager__page(&$variables)` function (for full views pages). There seems to be a `$variables['pager']['#tags']` array with the values for pagers. You might be able to do the UI string translation here.

# Answer
> 0 votes
Came here as I didn't found the translation tab you describe. After you have translated your View, or at least the pager buttons, **export config**. Then **import config** in all other environments. Not much manual effort required.

There you can change the labels.

---
Tags: views, 8, i18n-l10n, paging
---


# Question
Title: How to pass field value to referenced node template?
I have content type A. It has field reference to content type B.

I'm rendering referenced node B from content type A twig template like:

```
{{ content.field_referenced_object }}

```

And that works well.

I also render some type A filed inside it's template like:

```
{{ content.field_some }}

```

which also works.

Problem is that I need that `field_some` value to be displayed from referenced object B template instead of object A template, to optimize page markup. How can I pass value from content type A twig template to content type B twig template?

It twig it can be done when including template like:

```
{% include 'template.html' with {'foo': 'bar'} %}

```

But is there some analogy for Drupal 8 theming?

# Answer
> 2 votes
TL,DR: No.

Long version:

Conceptionally entity render arrays are self-contained, cachable units. The Drupal way would be either preprocessing and a custom cache context based on the referencing node, or a views block with a contextual filter.

But IMHO both ways are terrible workarounds, your Twig snippet `{% include ... with ... %}` is the better technique.

---
Tags: 8, theming
---


# Question
Title: Render custom twig in a specific language
I need to specify the language, which the drupal renderer uses, when generating a custom render array.

```
$renderArray = [
    "#theme" => "DNMBE_email",
    "#body" => [
        "#theme" => "DNMBE_emailBody_groupMessage",
        "#author" => $groupMessage->author,
        "#group" => $groupMessage->group,
        "#message" => $groupMessage->message,
    ],
    "#leadin" => $partials->leadin,
    "#leadout" => $partials->leadout,
];

$render = \Drupal
    ::service('renderer')
    ->renderRoot($renderArray);
$html = (string)$render;

```

#theme parameters resolve to twigs, which, among other things, contain `{{ "From"|t }}` markup which is incorrectly rendered as `From`.

I already posted a similar question, which was marked as duplicate, with the answer suggesting using `\Drupal::languageManager()->setConfigOverrideLanguage($language)`. I do not get the expected result.

When using the `t()` function, you can supply as third parameter an array, which can be used to specify the language. The renderer however does not take extra parameters, thus also not passing it to twig.

I verified that /admin/config/regional/translate has got the translated string, case-sensitive. I also use `['#cache']['max-age'] = 0` and I don't "precalc"-store any Drupal objects.

# Answer
> 1 votes
Currently, the only working way seems to be by passing local context - including a langcode in the render array and using `|t([], {'langcode': 'XX'})` resp. `{% trans with {'langcode': 'XX'} %}` as mentioned in https://www.drupal.org/project/drupal/issues/2049241

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


# Question
Title: How to check if custom variation field is null in twig?
I would like to know how to check if a custom variation field has content in a twig template (commerce-product.html.twig with variations injected). I have tried with some filters and conditions but without success. I need to hide some html markup if the field is empty. For example:

```
{% if product.variation_field_mycustomfield is not empty %}
<div class="mycustomclass">My custom field: {{ product.variation_field_mycustomfield }}</div>
{% endif %}

```

My products have some variations that users can select from a list. When this select changes, the product information must change, and some variations of the same product could have this field empty or not.

This question isn't related to only image fields. It's for any kind of field.

# Answer
> 1 votes
1. just vardump() the **product.variation\_field\_mycustomfield** that have an empty field then :
2. then if it is an array :

```
{% if product.variation_field_mycustomfield|length == 0 %}
    <div class="mycustomclass">My custom field: {{ product.variation_field_mycustomfield }}</div>
{% endif %}

```
1. otherwise, if it is not an array and it is no empty but it has default value that is considered as empty:

```
{% if product.variation_field_mycustomfield == 'the vardump output you get at step1' %}
    <div class="mycustomclass">My custom field: {{ product.variation_field_mycustomfield }}</div>
{% endif %}

```

---
Tags: 8, theming, commerce
---


# Question
Title: Setting value of form element from $form_state not working
I need to track previous values of a few form elements on a form to detect when they change to invalidate some other options on the page. Essentially, if the value of these fields change a field that controls pagination should reset.

I'm trying to accomplish this with this:

```
$values = $form_state->getValues();
$form['element1'] = [
      '#type' => 'radios',
      '#title' => $this->t('Element 1'),
      '#options' => [
        // Omitted for brevity
      ],
      '#weight' => '0',
      '#ajax' => [
        'callback' => [$this, 'my_callback'],
        'disable-refocus' => true
      ]
    ];

// dump($values['element1']);
$form['element1_previous'] = [
      '#type' => 'value',
      '#value' => (isset($values['element1'])) ? $values['element1'] : 'none',
    ];

```

No matter what I do the value of `$values['element1_previous`\] is `none`. If I uncomment the `dump()` statement right before it I can see the value of `$values['element1']` changing each time AJAX is submitted so the value is there.

If I do something like:

```
$form['element1_previous'] = [
          '#type' => 'value',
          '#value' => rand()
        ];

```

I can see `$values['element1_previous']` being set to a different integer each AJAX submission. I just can't assign the value of `$form['element1']` to that field.

What am I doing wrong? Is there a better way I could handle this?

# Answer
> 1 votes
This:

```
(isset($values['element1']))

```

will always return TRUE, since the form element exists, and therefore a value is always passed to the submit hander, *even when the value is empty*.

You likely want this:

```
!empty($values['element1'])

```

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


# Question
Title: What's the difference between the two-column layout and two-column bricks layout?
I enabled the experimental Field Layout core module. There are two different two-column layouts available: one called "two column" and another called "two column bricks."

The dialog provides the diagrams below which don't clue me into their meaning. What is the difference between these layouts?

# Answer
> 7 votes
Layouts are defined in the Layout Discovery module and can be used by different layout modules.

The difference between those two layouts is the number of regions, the Two Column Brick layout has three more. See the yaml layout definition:

*/core/modules/layout\_discovery/layout\_discovery.layouts.yml*

```
layout_twocol:
  label: 'Two column'
  path: layouts/twocol
  template: layout--twocol
  library: layout_discovery/twocol
  category: 'Columns: 2'
  default_region: first
  icon_map:
    - [top]
    - [first, second]
    - [bottom]
  regions:
    top:
      label: Top
    first:
      label: First
    second:
      label: Second
    bottom:
      label: Bottom

layout_twocol_bricks:
  label: 'Two column bricks'
  path: layouts/twocol_bricks
  template: layout--twocol-bricks
  library: layout_discovery/twocol_bricks
  category: 'Columns: 2'
  default_region: middle
  icon_map:
    - [top]
    - [first_above, second_above]
    - [middle]
    - [first_below, second_below]
    - [bottom]
  regions:
    top:
      label: Top
    first_above:
      label: 'First above'
    second_above:
      label: 'Second above'
    middle:
      label: Middle
    first_below:
      label: 'First below'
    second_below:
      label: 'Second below'
    bottom:
      label: Bottom

```

---
Tags: 8
---


# Question
Title: Prevent logged in users from seeing other registered users information
I'm using Drupal 8 and I have a security requirement to prevent authenticated users from seeing other authenticated users' profiles.

I have a view which customizes the user profile page of each authenticated user. Each logged in user can see their own profile by accessing the path /user-profile/userId.

Now if the user decided to randomly change the userId in the URL, they cannot access other users' profiles, since, in the view I have set the 'Filter Criteria' to current user. Which works perfectly.

However, if a user decided to randomly change the userId in the path /user/userId they will have access to other users information. What I need to do is to prevent them from accessing /user/userId.

It's important to mention that the users are free to change their own information using the URL /user/userId/edit

Any suggestions?

# Answer
> 3 votes
You should change the permission for authenticated users.

Go to `admin/people/permissions` and under **user** permissions dissallow authenticated users to `View user information`

---
Tags: users
---


# Question
Title: Update some field values after user update own account
On my Drupal 8 project, usernames are only allowed to be emails. For that, on account creation, I am setting the *name* field equal to the *email* field, and users don't have the permission to edit their own usernames.

I am writing the code to update the username when the users change email. This is the code I wrote so far.

```
/**
 * Implements HOOK_user_update().
 * Set Username = mail if mail has been updated by user.
 */
function hook_user_update($account) {
  $current_user = \Drupal\user\Entity\User::load($account->id());
  $original_email = $account->original->get('mail')->value;
  $updated_email = $current_user->get('mail')->value;

  if ($original_email != $updated_email) {
    $current_user->setUsername($updated_email);
    $current_user->save();
  }

}

```

Since the code is saving a user object, the same hook is invoked again when `$current_user` is saved. I also tried with `hook_user_save()` and `hook_user_presave()`, but they don't work until I include `$current_user->save();` in the code.

**Update:**

Using `hook_user_presave()`

```
function custom_module_user_presave($account) {
  $current_user = \Drupal\user\Entity\User::load($account->id());
  $original_email = $account->original->get('mail')->value;
  $updated_email = $current_user->get('mail')->value;

  if ($original_email != $updated_email) {
    $current_user->setUsername($updated_email);
    \Drupal::messenger()->addMessage(t("if"));
  }
  else {
    \Drupal::messenger()->addMessage(t("else"));
  }

```

However, after updating the email and saving an existing user, I always get the message: **else** which means `$original_email != $updated_email` which is logic as the user has not been not saved yet.

any help please ?

# Answer
Drupal core doesn't use any `hook_ENTITY_TYPE_save()` hook and `hook_ENTITY_TYPE_update()` is called after saving in the database an entity that has been updated.
As the documentation says, that hook implementations may not alter the stored entity data. They shouldn't call `save()` on the entity they receive as argument, or that will invoke those hook implementations once again; if then those hook implementations don't check if they have been already invoked (which is the case of most, if not all, the hook implementations) and save again the entity they received as argument, that would cause an infinite loop.

The only hook invoked before the entity is saved is hook\_ENTITY\_TYPE\_presave(), which is invoked either when an entity is created or updated. It's easy to understand in which case the hook is invoked, since in the latter case `$entity->original` will contain the entity before the change.

As side note, the documentation reference to that hook as `hook_ENTITY_TYPE_presave()`; the implementation done from the *mymodule* module for the User entity is `mymodule_user_presave()`. (Replace *ENTITY\_TYPE* with the entity type for which the hook should be invoked, such as *user* for the User entity and *node* for the Node entity.)

As for the used code, that is wrong since:

* There isn't the need to load the account with `\Drupal\user\Entity\User::load($account->id())` because the full User object is already passed to the hook as argument
* Since the hook is invoked whenever a new user is created, or an existing user is updated, the code needs to first verify `$account->original` is defined
* The code is setting the username for `$current_user`, but Drupal core is saving `$account`; since in PHP those are two different objects, the code isn't changing the username for the User object being saved
* `$original_email != $updated_email` is not comparing the changed email with the original email, but it's comparing the email before the User object is edited with the original email (which is still the email before the User object is edited)

I would use the following code.

```
function custom_module_user_presave($account) {
  if (isset($account->original)) {
    $original_email = $account->original->get('mail')->value;
    $updated_email = $account->get('mail')->value;

    if ($original_email != $updated_email) {
      $account->setUsername($updated_email);
    }
  }
}

```

Even better, the code should check the value returned from `$account->isNew()`.

```
function custom_module_user_presave($account) {
  if (!$account->isNew()) {
    $original_email = $account->original->get('mail')->value;
    $updated_email = $account->get('mail')->value;

    if ($original_email != $updated_email) {
      $account->setUsername($updated_email);
    }
  }
}

```
> 2 votes

---
Tags: 8, users
---


# Question
Title: Upload an image to filesystem, rename it and set it as Profile Picture for current user
I have the external link of an image where I am trying to:

1. Upload the image to filesystem.
2. Rename the image.
3. Set the owner of the image to current user.
4. Set the image as Profile Picture for current user.

**So far I have:**

```
$full_name = "John Smith";
$picture_url = "https://scontent.fbey14-1.fna.fbcdn.net/v/t31.0-8/14054356_124897527960923_50194821455451882_o.jpg?_nc_cat=106&_nc_sid=09cbfe&_nc_ohc=P4i5oscJf0IAX_KFCfR&_nc_ht=scontent.fbey14-1.fna&oh=c13b6b2d8712db359f3be5e1ec835340&oe=5EF2B1A4";

// Download the picture to local filesystem.
$profile_pic = system_retrieve_file($picture_url, "public://profile-pictures", TRUE, FILE_EXISTS_REPLACE);

// Get the Profile Pic ID.
$profile_pic_id = $profile_pic->id();

// Load the image.
$picture = \Drupal\file\Entity\File::load($profile_pic_id);

// Rename the image.
$picture->setFilename("$full_name.jpg");
// Set the owner of the profile picture file.
$picture->setOwner($current_user);

// Save the image.
$picture->save();

$current_user->set('user_picture', $profile_pic_id);
$current_user->save();

```

The image is indeed uploaded to filesystem under `public://profile-pictures`, also is successfully set as profile picture of the current user.

and the filename of the image at `/user/*/edit` edit page is set to: **john-smith.jpg**, however, the filename of the image at `public://profile-pictures` is **14054356\_124897527960923\_50194821455451882\_o.jpg** while I am expecting it to be **john-smith.png** !

How to rename the image at the filesystem ?

and does `$picture->setOwner($current_user)` will set the owner of the image to the current user ?

# Answer
I agree with @Clive you can do it that why, and also you can download the image directly with the full\_name.
To do so just change the line:

```
$profile_pic = system_retrieve_file($picture_url, "public://profile-pictures", TRUE, FILE_EXISTS_REPLACE);

```

by

```
$profile_pic = system_retrieve_file($picture_url, "public://profile-pictures/$full_name.jpg", TRUE, FILE_EXISTS_REPLACE);

```

and remove the line:

```
$picture->setFilename("$full_name.jpg");

```
> 3 votes

# Answer
`setFilename` just updates the field value on the file entity, it doesn't move anything on disk. You can do both in one go with `file_move()`:

```
$dest = "public://profile-pictures/$full_name.jpg";
if (file_move($picture, $dest) === FALSE) {
  // Something went wrong.
}

```
> 0 votes

---
Tags: 8, users, files
---


# Question
Title: Add elements to webform dynamically via hook_form_alter
I'm trying to dynamically add multiple toggle fields to a form (in my case webform) via a form-alter-hook.

```
function module_form_alter(&$form, FormStateInterface $form_state, $form_id) {
....
  foreach ($roles as $role) {
    $form['elements'][$role->id()] = array(
      '#type' => 'webform_toggle',
      '#title' => t($role->label()),
      '#default_value' => 0,
      // More webform specific arguments follow here.
      '#webform_id' => "edit_membership_roles--" . $role->id(),
      '#webform_key' => $role->id(),
      '#webform_parent_key' => "",
      '#webform_parent_flexbox' => FALSE,
      '#webform_depth' => 0,
      '#webform_children' => [],
      '#webform_parents' => [$role->id()],
      '#webform_multiple' => FALSE,
      '#webform_composite' => FALSE,
      '#admin_title' => $role->id(),
      '#webform' => "edit_membership_roles",
      '#webform_submission' => NULL,
      '#access' => TRUE,
      '#webform_element' => TRUE,
      '#element_validate' => [],
    );
  }
}

```

This works in a way that the form is displayed correctly, with all dynamically added toggle elements. However, when trying to load the `WebformSubmissionInterface $webform_submission` via `$webform_submission->getData();` in my custom `class FormHandler extends WebformHandlerBase {...}`, the array only contains the elements that I manually added to the webform via the GUI.

I checked the first answer of this question, but my `$form` does not have a `$form['submitted']`

Am I just missing something or does this approach not work at all?

**Update**

I did the same approach with a custom form built with Drupal FormApi and it works. So I must be missing something specific to webforms.

# Answer
Adding elements dynamically via hook form alter does not work because the Webform module can't recognize the new elements. Your best bet is to create a custom webform element.
> 3 votes

# Answer
In first instance I would also go with the suggested approach by @jrockowitz.

However I had a use case where the element was already in use and it couldn't be swapped out with a new element. What we ended up doing was to substitute the element's class with an extended class in a `.module` file:

```
use Drupal\foo\Plugin\WebformElement\CustomWebformToggle;

/**
 * Implements hook_webform_element_info_alter().
 */
function CUSTOM_MODULE_webform_element_info_alter(array &$definitions) {
  // Substitute the original element class with additional functionality.
  $definitions['webform_toggle']['class'] = CustomWebformToggle::class;
}

```

In the extended class I also had to implement `defineDefaultProperties()` for the additional changes in `form()` to take effect.
> 0 votes

---
Tags: hooks, webforms
---


# Question
Title: How can I change the name attribute to "email" in the user login form?
Users do not always login with their Drupal user name but in some projects by email for example.

What would be the Drupalitically correct way in this case to change the "name"-Attribute of the user name login text field in the user login form? For example to change it to "email" so that a HubSpot JS Snippet would recognize login form submissions? How would this be done in both Drupal 7 and Drupal 8?

# Answer
This is a variation of a frequently asked question.

The user login form for Drupal is built using Drupal Form API.

In Drupal 7 core, the user login form is declared in `user.module`:

https://github.com/drupal/drupal/blob/7.x/modules/user/user.module#L2111

```
  // Display login form:
  $form['name'] = array('#type' => 'textfield',
    '#title' => t('Username'),
    '#size' => 60,
    '#maxlength' => USERNAME_MAX_LENGTH,
    '#required' => TRUE,
  );

  $form['name']['#description'] = t('Enter your @s username.', array('@s' => variable_get('site_name', 'Drupal')));
  $form['pass'] = array('#type' => 'password',
    '#title' => t('Password'),
    '#description' => t('Enter the password that accompanies your username.'),
    '#required' => TRUE,
  );
  $form['#validate'] = user_login_default_validators();
  $form['actions'] = array('#type' => 'actions');
  $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Log in'));

```

And in Drupal 8 core, it's declared in `UserLoginForm.php`:

https://github.com/drupal/core/blob/8.8.x/modules/user/src/Form/UserLoginForm.php#L94

```
    // Display login form:
    $form['name'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Username'),
      '#size' => 60,
      '#maxlength' => UserInterface::USERNAME_MAX_LENGTH,
      '#description' => $this->t('Enter your @s username.', ['@s' => $config->get('name')]),
      '#required' => TRUE,
      '#attributes' => [
        'autocorrect' => 'none',
        'autocapitalize' => 'none',
        'spellcheck' => 'false',
        'autofocus' => 'autofocus',
      ],
    ];

    $form['pass'] = [
      '#type' => 'password',
      '#title' => $this->t('Password'),
      '#size' => 60,
      '#description' => $this->t('Enter the password that accompanies your username.'),
      '#required' => TRUE,
    ];

    $form['actions'] = ['#type' => 'actions'];
    $form['actions']['submit'] = ['#type' => 'submit', '#value' => $this->t('Log in')];

```

If you need to customize it, you should *not* edit the code in core. Instead, you should do it using `hook_form_alter()` in a custom module.

This is a classic example of one of the first exercises new developers can do to learn how to build Drupal modules, and a web search should reveal many tutorials.

As @Jaypan pointed out in the comments above, you probably want to change the label on the field (`$form['name']['#title']`) rather than its name.

Here's an example of how to do that with `hook_form_alter()` in Drupal 7:

```
function YOUR_MODULE_NAME_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id=='user_login') {

     // This will change the field label from "Username" to "Email".
     // The t() function marks the string as translatable by Drupal.
     $form['name']['#title'] = t("Email");

  }
}

```

In Drupal 8, it's almost the same, but `$form_state` is now an object and must be type hinted as an instance of `\Drupal\Core\Form\FormStateInterface`:

```
function YOUR_MODULE_NAME_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  if ($form_id=='user_login') {

     // This will change the field label from "Username" to "Email".
     // The t() function marks the string as translatable by Drupal.
     $form['name']['#title'] = t("Email");

  }
}

```
> 2 votes

---
Tags: forms
---


# Question
Title: What is the mechanism behind class comments?
```
 * @QueueWorker(
 *   id = "my_module_image_style",
 *   title = @Translation("Generate image styles"),
 *   cron = {"time" = 60}
 * )

```

And more specifically what is the effect of

```
 cron = {"time" = 60}

```

# Answer
> 3 votes
This is actually called **annotations** which provide metadata about the class, and this **metadata** is gonna be extracted later on with our code to perform a specific logic.

in Drupal context since The **QueueWorker** is just another drupal plugin, so it will be handled using the Plugin Manager which will extract this information from the **Annotations** and use them to build some logic for example in this case:

* **$id:** the unique identification of the QueueWorker plugin type instance.
* **$title:** some drupal method will extract the title from the **Annotation** and use it to set The human-readable title of the plugin.
* **$cron:** another function or same function will extract the cron from the **annotation** and set us How much time Drupal cron should spend on calling. this worker in seconds. Defaults to 15.

and every drupal plugin fllow this logic:

1. the **plugin manager** of this plugin is **Drupal\Core\Queue\QueueWorkerManager** wich will discover the implementations of the annotation class that has been set in `parent:construct()` arg 4 ,wich is : (**\Drupal\Core\Annotation\QueueWorker**) :

```
  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
    parent::__construct('Plugin/QueueWorker', $namespaces, $module_handler, 'Drupal\Core\Queue\QueueWorkerInterface', 'Drupal\Core\Annotation\QueueWorker');

  }

```
2. **@QueueWorker (Annotation class)**: this annotation is an implementation of the **\Drupal\Core\Annotation\QueueWorker** class where @QueueWorker = class name and the annotation attributes = the class properties.
> actually in this class peoperty doc Comment you can find a description of each annotation attribute.

```
   <?php namespace Drupal\Core\Annotation;
    use Drupal\Component\Annotation\Plugin;

  class QueueWorker extends Plugin {

  /**
   * The plugin ID.
   *
   * @var string
   */
  public $id;

  /**
   * The human-readable title of the plugin.
   *
   * @ingroup plugin_translatable
   *
   * @var \Drupal\Core\Annotation\Translation
   */
  public $title;

  /**
   * An associative array containing the optional key:
   *   - time: (optional) How much time Drupal cron should spend on calling
   *     this worker in seconds. Defaults to 15.
   *
   * @var array (optional)
   */
  public $cron;

}

```

# Answer
> 6 votes
The class comments are **Annotations** : What is Annotation mean ?

1. In general according to techopedia.com
> Annotation is a term used in computer programming to refer to documentation and comments that may be found on code logic. Annotation is typically ignored once the code is executed or compiled.
2. In Drupal According to Annotations doc page:
> Annotations for class discovery and metadata description.
> The Drupal plugin system has a set of reusable components that developers can use, override, and extend in their modules. Most of the plugins use annotations, which let classes register themselves as plugins and describe their metadata. (Annotations can also be used for other purposes, though at the moment, Drupal only uses them for the plugin system.)

A lot of frameworks use annotations too like symfony use it in many contexts like creating routes using annotations here.

For the annotation example you put in your question is for **QueueWorker** plugin:

```
cron = {"time" = 60}

```

the definition of cron property `QueueWorker::$cron` according to QueueWorker::$cron it mean:

> **time:** (optional) How much time Drupal cron should spend on calling this worker in seconds. Defaults to 15.

# Answer
> 4 votes
Those are called annotations, and in this context, they are used for plugin discovery.

This:

```
cron = {"time" = 60}

```

Signifies a property of the `QueueWorker` annotation; specifically QueueWorker::$cron, which is:

> How much time Drupal cron should spend on calling this worker in seconds. Defaults to 15.

---
Tags: cron
---


# Question
Title: How do I get the value of a persistent variable with `variable_get()`?
How do I get the value of a persistent variable with `variable_get()`? Does the function save the value on a database table or somewhere else?

# Answer
To get the value use:

```
$valueVar = variable_get('myvar');

```

It is saved on a generic database table called \[prefix\]\_variable, if you are not using prefix, the name of the table is **variable**. Look at: https://www.drupal.org/forum/support/module-development-and-code-questions/2009-05-14/help-which-table-is-the-variable
> 1 votes

# Answer
You can use variable\_set() to set the value and that will store it in the database. e.g.

```
variable_set('myvar',123);

```

Then to retreive it:

```
$myvar = variable_get('myvar');

```

You could create a page with a form to allow CMS users to change the values of your variables. See this for examples: https://api.drupal.org/api/drupal/modules%21system%21system.module/function/system\_settings\_form/7.x
> 0 votes

# Answer
`variable_get()` only retrieves the value of a persistent variable; it doesn't save its value as that is the task for `variable_set()`.

Actually, `variable_get()` gets the persistent variable value from the global `$conf` which is initialized from the following code in `_drupal_bootstrap_variables()`.

```
  global $conf;

  // Initialize the lock system.
  require_once DRUPAL_ROOT . '/' . variable_get('lock_inc', 'includes/lock.inc');
  lock_initialize();

  // Load variables from the database, but do not overwrite variables set in settings.php.
  $conf = variable_initialize(isset($conf) ? $conf : array());

```

The code in `variable_initialize()` first tries to load the persistent variable values from the cache, and then load the values from the database (the *variable* database table).

```
  if ($cached = cache_get('variables', 'cache_bootstrap')) {
    $variables = $cached->data;
  }
  else {
    // Cache miss. Avoid a stampede.
    $name = 'variable_init';
    if (!lock_acquire($name, 1)) {

      // Another request is building the variable cache.
      // Wait, then re-run this function.
      lock_wait($name);
      return variable_initialize($conf);
    }
    else {
      // Proceed with variable rebuild.
      $variables = array_map('unserialize', db_query('SELECT name, value FROM {variable}')
        ->fetchAllKeyed());
      cache_set('variables', $variables, 'cache_bootstrap');
      lock_release($name);
    }
  }
  foreach ($conf as $name => $value) {
    $variables[$name] = $value;
  }
  return $variables;

```

To answer the values of persistent variables can be stored:

* In the global `$conf` initialized in the settings.php file (which means in memory)
* In the cache, which isn't necessarily stored in the database, especially if there are third-party modules that change the cache functions
* In the *variable* database table, when saved using `variable_set()`
> 0 votes

---
Tags: 7, configuration
---


# Question
Title: How can I accurately determine when a customer is on the "Review" step in Commerce?
I've created a custom checkout pane by extending `Drupal\commerce_checkout\Plugin\Commerce\CheckoutPane\CheckoutPaneBase` and added it to the "Order information" step in a checkout flow. This accepts customer data.

The customer then progresses to the "Review" stage to confirm everything is correct. The customer can "Edit" their information if required, going back to the "Order information" step.

Within the custom pane I'm wanting to determine whether it's being displayed in the "Order information" step or the "Review" step.

`getStepId()` always returns what's in the config for the pane. In this case, "Order information".

`$this->order->checkout_step` seems to always return "Review", or maybe it's just reporting the highest step reached in the order thus far.

Is there a Commerce native way of determining the exact step being viewed? Or will I need to check the URL directly?

**Edit:** I've tried checking the route name, but both `/checkout/[id]/order_information` and `/checkout/[id]/review` return `commerce_checkout.form`.

# Answer
> 1 votes
A good place to look for example code related to the checkout form is CheckoutController.php. Its formPage() function ensures the form for the correct checkout page is built by comparing the checkout step requested in the URL to the checkout step the order last advanced to, ensuring the customer isn't trying to directly navigate to a later step than it's entitled to.

You can see that it uses the a route matcher to get the named 'step' parameter from the URL, and you can do the same thing in your own code. Typically you'd inject the route matcher into the checkout pane class, but a quick and dirty solution to fetch the current route matcher from the container is:

```
$container = \Drupal::getContainer();
$route_matcher = $container->get('current_route_match');
$step_id = $route_matcher->getParameter('step');

```

This will functionally do what you've done by looking at the URL directly, to be honest, but it's a bit more structured way of doing so.

# Answer
> 0 votes
Checking the path does work but I'm not it's ideal.

```
$current_uri = \Drupal::request()->getRequestUri();
$path_elements = explode('/', $current_uri);
if (end($path_elements) === 'review') {
  // Do something.
}

```

---
Tags: commerce
---


# Question
Title: How can I determine which module is associated with a field plugin?
I'd like to implement an entity hook, and act on all fields defined by Computed Field FieldType plugins. So I either need a list of all FieldType plugins provided by the module or need to know which fields are associated with it in order to know which fields to work on (or avoid). Is this possible?

I'd rather not hard-code the list of plugins (`computed_string`, `computed_decimal`, etc.) because new ones could be added later, and then the list would have to change.

And I can't use `computed_*` because another module, Computed Field Plugin, defines its own field type with that prefix, and I don't want to touch it.

I was expecting something like FieldDefinitionInterface::`getDefiningModule()`, but that doesn't seem to exist.

*For those interested, I'm working on adding support for computed cardinality.*

# Answer
> 2 votes
The answer to the question title should be straightforward. You can get the extension from plugins via `getProvider()`. So you could make a list of all FieldType plugins or get the provider of a specific field type directly from the plugin defintitions:

```
$module = \Drupal::service('plugin.manager.field.field_type')
  ->getDefinition($field_type)['provider'];

```

For field definitions this is a bit more complicated. Field storages have this method as well, but for configured fields it always returns the module `field`. This is not what you want. But there is a different place. When creating field storages the provider of the field type plugin is stored in the property `module`. So starting from FieldDefinitionInterface you should be able to get the module name:

```
$module = $field_definition->getFieldStorageDefinition()->get('module');

```

---
Tags: 8, plugins, entities
---


title: Migrate users and retain passwords

text:
# Question
Title: Migrate users and retain passwords
I'm transferring 10K users from Drupal 7 to Drupal 8. I want to retain passwords. What I'm trying is

* Dump user records from Drupal 7 as a CSV file
* Dump hashed passwords from MySQL as a CSV file
* Load user records and hashed passwords into a custom program
* In the program, add hashed passwords to the correct user records (match by UID)
* Manipulate user records (consolidate duplicates, combine fields, and more)
* output fixed-up user records (including password hash) to a CSV file
* use this CSV file as input to a custom Drupal 8 module to create users

All of this is easy except creating users in Drupal 8 with their Drupal 7 passwords.

I have tried simply

```
$values = array
[
  'name' => 'test',
  'mail' => 'test@test.com',
  'roles' => [],
  'pass' => $hashed_drupal_7_password,
  'status' => 1,
];
$account = entity_create('user', $values);
$account->save();

```

but of course Drupal 8 assumes the `pass` value is the textual password and rehashes it.

Is there a way to get the already-hashed password into the user account, either during creation or after it is created? If I get them in, will they still work? As you can tell by reading, I'm a neophyte when it comes to passwords, encryption, etc. I've read many posts and articles, but don't recognize an answer to this question.

# Answer
> 7 votes
As @No Sssweat recommend, the D8 Migrate Modules is good way. With your way, you have to add property **pre\_hashed** for field pass.

```
$values = [
  'name' => 'test',
  'mail' => 'test@test.com',
  'roles' => [],
  'pass' => [
    'value' => $hashed_drupal_7_password,
    'pre_hashed' => TRUE,
  ],
  'status' => 1,
];
$account = entity_create('user', $values);
$account->save();

```

You can find this property in FieldType Password

# Answer
> 6 votes
You should use the D8 Migrate Modules to do this, specially for transferring 10K users, unless your current code is using the Batch API. Otherwise, you're going to run into timeouts because it's too big. Also, these migrate modules allow you to transfer from SQL to SQL. No need for CSV file, if you don't want. But you can still do CSV file import with them, if needed.

---

To answer your question programmatically, as far as I know, Drupal API doesn't offer a way to skip the hashing, probably for security reasons.

Since D7 and D8 use the same hashing, after User is created, you have to overwrite it by updating it manually/directly. Add this right after `$account->save();`.

```
// Updates user password
$uid = $account->id();
$query = \Drupal::database()->update('users_fields_data');
$query->fields([
  'pass' => $hashed_drupal_7_password,
]);
$query->condition('uid', $uid);
$query->execute();

```

Flush caches after.

Note: D6 uses different hashing, so this answer wouldn't work in that case.

---
Tags: 8, migrations
---


title: Reverse entity relationship

text:
# Question
Title: Reverse entity relationship
I have several custom content entity types that have relationships to each another. The fields used are defined as base fields and I am using `$fields['FIELD_NAME'] = BaseFieldDefinition::create('entity_reference')`.

Views doesn't currently implement reverse relationships for base fields, which is a feature request.

I need to define the relationship in the module with `EntityViewData::getViewsData()` or `hook_views_data()`.

Using the examples provided, I was able to define a reverse relationship for an entity reference field with cardinality of 1 (where the field is created in the entity's base\_table), but I can't figure out how to do it when the cardinality is higher than 1, or unlimited (where the field is created in a separate table).

None of the examples on the documentation pages (or that I have been able to find googling) defines a relationship between two entities that requires an intermediary table.

Views defines an `EntityReverse` class that I have looked at for ideas. It has a `$first_join` and a `$second_join`. I can confirm that if the field is added to the entity using the normal UI, then the view provides both relationships, to the related entity and the reverse relationship from the related entity.

I am not sure at all how to translate the `EntityReverse` class into a definition I could pass to `getViewsData()`.

And How to do a Reverse Entity Reference? is not the answer.

Does anyone know a solution?

# Answer
After some trial and error, I have been able to find a solution.

In the example code for `hook_views_data()`, there was a relationship example that provided this snippet.

```
// ID of relationship handler plugin to use.
'id' => 'standard',

```

Having already discovered the `EntityReverse` class, I was pretty sure that I would need to use `'id' => 'entity_reverse'`.

The part that tripped me up the most was that I was trying to define the relationship as part of the related entity inside `getViewsData()` in the `ViewsData` class I created for the related entity.

Then it dawned on me that the documentation for `hook_views_data()` says:

> The return value of the `getViewsData()` method on the interface is the same as this hook

It means I can describe views data for any table and not just my entity's tables. Instead of trying to attach this relationship to the related entity, I tried attaching it to the main entity and this worked.

For example,

* *{MAIN ENTITY}* is the entity being related
* *{RELATED ENTITY}* is the entity with a relationship to *{MAIN ENTITY}* where *{RELATED ENTITY}* class has the following fields

```
   $fields['{FIELD NAME}'] = BaseFieldDefinition::create('entity_reference')
     ->setSetting('target_type', '{MAIN ENTITY}')
     ->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) // or a specific number higher than 1

```

The `getViewsData()` method of the `ViewsData class` for *{RELATED ENTITY}* is the following.

```
public function getViewsData() {
  $data = parent::getViewsData();
  $data['{MAIN ENTITY BASE TABLE}']['{useful non-conflicting name - I used the {RELATED ENTITY BASE TABLE}}'] = [
    'title' => t('{some useful title that displays in Add Relationships popup}'),
    'help' => t('{some useful description that displays in Add Relationships popup}'),
    'relationship' => [
      'field_name' => '{name of the field - same as {FIELD_NAME}}',
      'field table' => '{name of intermediary table - it is probably {RELATED ENTITY}__{FIELD NAME}',
      'field field' => '{name of intermediary field - it is probably {FIELD NAME}_target_id',
      'base' => '{RELATED ENTITY BASE TABLE}',
      'base field' => '{RELATED ENTITY ID FIELD}',
      'id' => 'entity_reverse',
      'label' => '{some useful label that displays in Relationship select in various views field settings popups}',
    ],
  ];

  return $data;
}

```
> 8 votes

# Answer
There is a patch to provide reverse relationships by default at https://www.drupal.org/project/drupal/issues/2706431

I've tried it and it works, though before it gets into core it requires a bit more work.
> 0 votes

# Answer
After trying couple of hours, could able to connect custom entity "dashboards" with users table.

First write below code so yours custom entity would be available for view operations.

"dashboards" is the table name of the custom entity.

```
$data['dashboards']['table'][] = [];
$data['dashboards']['table']['group'] = t('Dashboards');
$data['dashboards']['table']['provider'] = 'custom_dashboards';
$data['dashboards']['table']['base'] = array(
  // Identifier (primary) field in this table for Views.
  'field' => 'id',
  // Label in the UI.
  'title' => t('Dashboards'),
  // Longer description in the UI. Required.
  'help' => t('Dashboards table.'),
  'weight' => -10,
);

```

Dashboard table have a user reference column called "uid". So now, make a relation with users table and dashboards table using below code, so a relationship can be added in view to show dashboard data associated with users.

```
  $data['users']['dashboard_data'] = [
    'title' => t('Dashboards content'),
    'help' => t('Relations with dashboards table'),
    'relationship' => [
      // Views name of the table being joined to from foo.
      'base' => 'dashboards_field_data',
      // Database field name in example_table for the join.
      'base field' => 'uid',
      // Real database field name in foo for the join, to override
      // 'unique_dummy_name'.
      'field' => 'uid',
      // ID of relationship handler plugin to use.
      'id' => 'standard',
      'label' => t('Dashboards content'),
    ],
  ];

```

full code given below

```
    public function getViewsData() {
      $data = parent::getViewsData();
      // Additional information for Views integration, such as table joins, can be
     // put here.
     $data['dashboards']['table'][] = [];
     $data['dashboards']['table']['group'] = t('Dashboards');
     $data['dashboards']['table']['provider'] = 'custom_dashboards';
     $data['dashboards']['table']['base'] = array(
     // Identifier (primary) field in this table for Views.
    'field' => 'id',
    // Label in the UI.
    'title' => t('Dashboards'),
    // Longer description in the UI. Required.
    'help' => t('Dashboards table .'),
    'weight' => -10,
);

  $data['users']['dashboard_data'] = [
    'title' => t('Dashboards content'),
    'help' => t('Relations with dashboards table'),
    'relationship' => [
      // Views name of the table being joined to from foo.
      'base' => 'dashboards_field_data',
      // Database field name in example_table for the join.
      'base field' => 'uid',
      // Real database field name in foo for the join, to override
      // 'unique_dummy_name'.
      'field' => 'uid',
      // ID of relationship handler plugin to use.
      'id' => 'standard',
      'label' => t('Dashboards content'),
    ],
  ];

    return $data;
    }

```

Now create a view of user content and add relationship with dashboards content.
> 0 votes

---
Tags: views, 8, entities
---


# Question
Title: Fix for "'csrf_token' URL query argument is invalid" error during logout
I am creating a set of API endpoints for a mobile app using Rest. For User authentication, I am using the default API endpoints supplied by Drupal. That would be

```
/user/logout?_format=json&token=<logout_token obtained from login api response.>

```

I wanted to remove the \_format=json from the URL parameter and so I created a custom route with the existing controller just for this purpose. However, I am getting an error.

```
"'csrf_token' URL query argument is invalid

```

I am not able to figure out how to remove this error. I had added a csrf\_token as an additional parameter with the one I got from successful login. It seems however that the csrf token being validated against is generated somewhere else.

I can remove this error by removing the csrf token entry from the routing file entry but that would be a security violation. How do we fix this error or is there a better way to handle the user logout api endpoint.

# Answer
To get the right **csrf\_token** you should first request `/session/token` this route coming from system.routing.yml so in your controller action add those two things:

1. Get the system **csrf\_token** from `/session/token`
2. Add your csrf token to header request as `X-CSRF-Token`

**Update**: If you are using rest module you should get the csrf token from `/rest/session/token` instead of `/session/token`
> 1 votes

# Answer
You can use POST method on */user/logout* without params and token, the cookie will be deleted so the user will be logged out, but in the server-side Drupal will not destroy the session, so you'll end up by having a lot of unused sessions...

I wonder why do you want to remove the *\_format=json* from the URL ?
> 2 votes

---
Tags: 8, csrf
---


# Question
Title: How do I add CSS classes to all the form elements?
How can I add the same CSS class (*form\__text*) to form elements in Drupal 8?

# Answer
> 0 votes
You can do it using `template_preprocess_form_element` something like:

```
use Drupal\Component\Utility\Html;
function [YOURTHEME]_preprocess_form_element(&$variables) {
  $input_types = ['search', 'textfield', 'password'];
  $type = $variables['element']['#type'] ?? NULL;
  if (in_array($type, $input_types)) {
    $variables['element']['#attributes']['class'][] = Html::cleanCssIdentifier('form__text');
  }
}

```

**Update** If the below doesn’t work try the following using `hook_preprocess`:

```
/**
 * Implements hook_preprocess().
 */
function [YOURTHEME]_preprocess(&$variables, $hook) {
  if ($hook == 'input') {
    $variables['attributes']['class'][] = Html::cleanCssIdentifier('form__text');
  }
}

```

**To exclude submit button ?**
change the condition to `$hook == 'input' && $variables['element']['#type'] !== 'submit'` instead of `$hook == 'input'`

---
Tags: theming, forms
---


# Question
Title: How can I set the site root page to a landing page instead of user login?
I'm using a custom bootstrap 3 theme as my default theme which sets the `user_login` page. When I go to the root of my site, this is the page that appears. How do I change the root of my site to display a page other than `user_login`?

Specifically, we are trying to add a landing page and we would like `https://oursite.com/` to display the landing page instead of the login page (which is also accessible thru `https://oursite.com/user/login`)

All the suggestions I've seen so far just say to create a node and redirect to something like `https://oursite.com/landing`, but we would like `http://oursite.com/` to be the landing page instead of having to redirect to another page.

# Answer
Under /admin/config/system/site-information simply set a default front page which can be a node `/node/123` a Views page `/my-view` or any other custom page `/foobar/landing-page`.

If you leave this empty it falls back to `/user/login` (which when you are logged in redirects to your user page).

To have the "Promoted to front page" setting in nodes respected set the default front page under /admin/config/system/site-information to `/node`. This is the path to the front page View you can edit yourself. This view by default displays node teasers and respects the "Promoted to front page" and "Sticky at top of lists" flags. You can have multiple nodes at the same time to be promoted and/or sticky.
> 2 votes

---
Tags: 7, bootstrap-theme
---


# Question
Title: How to pre-populate a text field when creating a new node?
I am using Drupal 7. I have a Content Type called Request. I have two fields "Manager Name" (type Text) and "Manager Email Address" (type Email). When the user creates a new node of type Request, I want to pre-fill these fields with "Hello World" and "nobody@yahoo.com". Here is what I have tried so far (This is all in mymodule\_form\_node\_form\_alter):

```
$form['field_manager_name']['und']['#default_value'] = "Hello World";
$form['field_manager_name']['und']['#suffix'] = "Enter in the name of your immediate supervisor.";
$form['field_manager_email_address']['und']['#default_value'] = "nobody@yahoo.com";
$form['field_manager_email_address']['und']['#suffix'] = "Enter in the email address of your immediate supervisor.";

```

The two suffixes are working. When I create a new node of type Request, the suffix text appears under the field name, as expected. But the "default\_value" fields are not working. What am I doing wrong?

# Answer
instead of `$form['field_FIELD_NAME']['und']['#default_value']` you should use `$form['field_FIELD_NAME'][LANGUAGE_NONE][0]['value']['#default_value']`
try something like:

```
$form['field_manager_name'][LANGUAGE_NONE][0]['value']['#default_value'] = 'hello world';
$form['field_manager_email_address'][LANGUAGE_NONE][0]['email']['#default_value'] = "nobody@yahoo.com";

```
> 1 votes

---
Tags: 7
---


title: Commerce hook attributes refresh alter

text:
# Question
Title: Commerce hook attributes refresh alter
Commerce 1.x (D7) has a hook `_commerce_cart_attributes_refresh_alter(&$commands, $form, $form_state)` that allows modules to add arbitrary AJAX commands to the array returned from the Add to Cart form attributes refresh. Is there anyway to have something similar in Commerce 2.x (D8)?. I would like to add my custom commands.

# Answer
Drupal 8/9 modules often use events to take the place of alter hooks like this one found in Commerce 1.x on Drupal 7. You have to do a little digging to find the place in the code that executes it, but you can look it up with the following info:

1. An Add to Cart form in Commerce 2.x is an order item add form governed by the "Add to Cart" form mode (a new concept in Drupal 8).
2. Looking at the configuration for the default order item type, you can see that the "Purchased entity" reference field uses a field widget called "Product variation attributes."
3. You can find that widget's definition in the ProductVariationAttributesWidget.php plugin contained in the product module, and its formElement() function shows you that it invokes an ajaxRefresh() function on the object to process the Ajax response when attributes are updated.
4. That class extends ProductVariationWidgetBase where the ajaxRefresh() function is located. You can see that it builds a response array using an Ajax renderer and gives other modules the opportunity to add commands to the response array via the PRODUCT\_VARIATION\_AJAX\_CHANGE event (using a constant defined in the ProductEvents.php class).

If you're still following, the solution then is to create your own event subscriber that subscribes to that event and appends your own commands to the event's $response array. I've created an example module showing how to do this: https://github.com/rszrama/commerce\_example3
> 2 votes

---
Tags: 8, commerce, hooks
---


# Question
Title: How render view with programmatically passed parameters of contextual filter
I am using Drupal 8. Added new view My Vocabulary and created a contextual filter with paragraph ID. Now I need to render the view with passed parameters to contextual filter. What hook to use to solve my problem. Thanks.

# Answer
> 1 votes
Use hook\_views\_pre\_view

```
function mymodule_views_pre_view(\Drupal\views\ViewExecutable $view, $display_id, array &$args) {
  // Modify contextual filters for view_name.
  $paragraph_id = 22;
  if ($view->id() == 'view_name') {
    $args = [$paragraph_id]; // args must be an array.
  }
}

```

---
Tags: 8, hooks
---


# Question
Title: Suggested template file is not working for Custom Search's template
I have installed Custom Search module for my drupal7 setup.

I am trying to modify template files for search-result and search-results.

By default its using template files from contrib module's theme itself which are as follows:

```
sites/all/modules/contrib/custom_search/theme/custom_search-results.tpl.php
sites/all/modules/contrib/custom_search/theme/custom_search-result.tpl.php

```

As per the theme-debug's hook suggestions I have created tpl files and have placed them within my sub-theme's templates directory, which are as follows:

```
sites/all/themes/bootstrap_sub/templates/custom-search-result.tpl.php
sites/all/themes/bootstrap_sub/templates/custom-search-results.tpl.php

```

I have cleared cache for several times, and still it uses template files from the module's theme directory.

Can anyone please help me out with this issue.

Thanks in advance.

# Answer
This is a known issue with the Custom Search module for Drupal 7. Of note from the issue:

> Copy custom\_search/theme/custom\_search-result.tpl.php to your theme location (e.g, sites/themes//templates/search-result.tpl.php), modify accordingly and then refresh your caches.
>
> Tested on the current stable - custom\_search 7.x-1.11

The solution is to rename `custom_search-result.tpl.php` from the module to `search-result.tpl.php` in your theme.
> 1 votes

---
Tags: 7, theming, bootstrap-theme
---


# Question
Title: How should I include <link> or <style> inside <head>?
I'm trying to use a Google font, which requires adding either a `<link>` or `<style>` section inside the `<head>` per the below instructions. I am using a subtheme and can modify the section directly in `html.html.twig`, if that's the right way to do it.

However, I noticed `<head-placeholder>, <css-placeholder>`, and `<jss-placeholder>` inside `<head>` and I am wondering if those are intended to be used to insert code from somewhere else.

What's the best practice for adding to `<head>`?

# Answer
> 7 votes
First, define a library in your theme that links to the font.

`[THEME].libraries.yml`:

```
fonts:
  css:
    theme:
      # Do not include http: or https.
      # Should start with a double slash.
      //fonts.googleapis.com/css?family=Source+Sans+Pro: { type: external }

```

This library is loaded by adding it to the theme's `[THEME].info.yml` file:

```
libraries:
  - [THEME]/fonts

```

# Answer
> 3 votes
1. All CSS library that has been declared in `[THEME].libraries.yml` and loaded by the `[THEME].info.yml` will be injected into the `<css-placeholder>`.
2. All JS library that has been declared in `[THEME].libraries.yml` and has been loaded by the `[THEME].info.yml` will be injected into the `<jss-placeholder>`.
3. All JS library that has been declared in `[THEME].libraries.yml` with `header : true` and loaded by the `[THEME].info.yml` will be injected into the `<head-placeholder>`.

```
    js-header:
      header: true
      js:
        header.js: {}

```

---
Tags: 8, theming
---


# Question
Title: How do I let the module know where the external library is located?
On a fresh installation of Drupal 8, I installed a third-party module that requires an external library. I uploaded the library to the site.

How do I let the module know where the external library is located?

# Answer
The International Phone module's page says that Composer is required to install the module. The module doesn't have a setting page where you can say where the library has been copied, and that is expected, from a module that requires Composer.

Composer is not a tool you normally use on a production server, and using the production server as test server is pretty wrong.

When I have to install Drupal on a shared hosting that doesn't allow me to use SSH, I install Composer on the local computer, I use a Composer template to copy Drupal in a directory and I add the modules I need with `composer require`. I can then use that directory for a local site where I can verify that adding a module, or updating the site, doesn't cause issues.

When a module requires Composer, there aren't other ways to let it know where the libraries from which it depends have been installed.
They are loaded from the *autoload.php* file created from Composer. You could manually create that file, but that would be a bad idea, especially because that file is created basing on some settings present in the *composer.json* file that comes with Drupal core.
> 1 votes

# Answer
Yes, I was told by several individuals that a server was not the place to develop Drupal apps. While clutching their pearls in horror, what they didn't understand is that the server is not a production server, but simply a space I rent on a server to experiment with Drupal.

However, as I have now spent two months reading, studying, and experimenting, I see that Drupal development really has to be done on a PC or similar and then uploaded. It is unfortunate that a server-based system cannot be developed on a server. But it is what it is.

I have therefore made the decision to stop trying to make Drupal work for me. Instead, I am going with HTML5 and JQuery and build my own system. After two months of this, I probably could have already had a working system.
> 0 votes

---
Tags: 8
---


# Question
Title: How do I get the price of a line item for the transactions which are already completed?
There are some transactions which are made using drupal commerce module along with commerce ccavenue module. I have the order ids, transaction ids and list of line items purchased in each of the orders. But the problem is I if a product price is updated in past then I am not able to find the cost of the product in the past order when the product was purchased.

Is there any place where drupal stores product price for a particular order anywhere.

# Answer
> 0 votes
Yes, Commerce Module does store product amount of past order... You can retrieve using below details...

To get full details of order

```
$order = commerce_order_load($order_id);
$view_mode = "administrator";
print entity_view('commerce_order', array($order->order_id => $order), $view_mode, NULL, TRUE);

```

To be more specific

```
  $order = commerce_order_load($order_id);
  foreach ($order->commerce_line_items['und'] as $line) {
    $line_item = commerce_line_item_load($line['line_item_id']);
    drupal_set_message("<pre>" . print_r($line_item,1) . "</pre>");
  }

```

There is no chance it gets new price instead of old price since it gets tracked in `field_data_commerce_unit_price` table in database ... All you need to do is divide by 100 if decimal places are 2 in order line item amount...

# Answer
> 0 votes
I think you can try and use :

https://www.drupal.org/project/commerce\_line\_item\_revision

that could activate the line items you are seeking

---
Tags: commerce
---


title: Is multistep checkout supported?

text:
# Question
Title: Is multistep checkout supported?
I am wondering if Drupal 7 commerce support the multistep checkout via hook or contrib modules, the target was I have products that is subscription based and once user select lets say product a before he can add to cart he needs to select how many months of subscription he wants after selecting that he can then press the select plan then move to another page to select attributes of the product items that is limited to 2 option or more then after he select and continue he will be on the page of customer info and last step was payment,

So basically it's a 4 page process.

Is this achievable? Can I setup the product types to accommodate subscriptions, with attributes?

# Answer
> 1 votes
going to post answers to help people that is having the same issue, I used one of this modules to help me fix the issue I am having :

https://www.drupal.org/project/dc\_co\_pages

hope this can help someone :)

---
Tags: commerce
---