# Question
Title: Views block doesn't appear on page if only media-type content is selected
I've created a view block that has a contextual filter with a Content ID from URL. The view is only to appear on my content types if the `field_aside_content` has any data in it.
This field is just a paragraph reference type to a selected number of custom paragraphs that are to appear in the aside region of my page.

My problem is if I only select a media paragraph type in this content, the block doesn't display on the page. If I then select a paragraph type that is text-based, then the block displays both the media and text content. If I remove the image, the text shows fine on its own.

What I've noticed is that the only time this block doesn't seem to show up on the page is when I select a media-type of paragraph.
My image, video, map and slider paragraph types won't show up on their own unless they're accompanied by some sort of text-based paragraph type or if a menu or some other block is already in the aside that this block shows up in.

It's weird too because if I check the preview of the page when I'm editing the view, it shows the media content showing up, it just doesn't seem to actually show on the published page.

Does anyone have any idea as to what is happening here?

I've also attached a screenshot of my view settings below to show what I've done in case something needs to be tweaked here:

**EDIT:**

My `page.html.twig` file has the following code for the aside:

```
{% set has_aside = page.sidebar|render|striptags|trim %}
  {% if has_aside %}
  {% block sidebar %}
    <div{{ aside_attributes.addClass(aside_classes).setAttribute('id', aside_id) }}>
      {{ page.sidebar }}
    </div>
  {% endblock %}
  {% endif %}

```

I've noticed that if I remove the `|trim` filter, then the images will show up but the issue that then occurs is that even if my aside doesn't have any content in it, it will still show up on a page that doesn't need it.

# Answer
The `|trim` twig filter in my `page.html.twig` was my problem as to why those blocks weren't appearing. Also, the reason that my aside always shows when that filter is removed was that in dev, it has twig debug on spitting code in that section. When twig debug is off on my production server, the aside won't appear unless content is in it and all my blocks now appear as well.
> 0 votes

---
Tags: views, 8, blocks
---


title: Get taxonomy name instead of id

text:
# Question
Title: Get taxonomy name instead of id
I set up a search criteria using taxonomy terms to filter content. The taxonomy and filter work great. The problem is the links return like `www.example.com/work?tid=1` but instead I would like the filter links to use the taxonomy term name like `www.example.com/work/logo`. I have tired to set a alias on the terms but it keeps referring to the `tid`. The has taxonomy option only allows you to change the name of the identifier before the ? But the link still shows the `=1` id after the identifier.

# Answer
you can use Pathauto contrib module.

> The Pathauto module automatically generates URL/path aliases for various kinds of content (nodes, taxonomy terms, users) without requiring the user to manually specify the path alias. This allows you to have URL aliases like /category/my-node-title instead of /node/123. The aliases are based upon a "pattern" system that uses tokens which the administrator can change.

https://www.drupal.org/project/pathauto
> 1 votes

# Answer
You're probably using Content Views type, assuming from what you've written.

You have to introduce the term name into Views if it's not available, which it isn't out of the box if you have Content Views.

You do that by adding a Relationship to the Field that references that taxonomy. Once you add the Relationship you will have the Taxonomy term: Name option under Filters, expose it, set its `Filter identifier` to your preferred word (I'm guessing `work` is the name of your field) and when used the link will be something like:

`www.example.com/your-views-page-path?yourtagidentifier=events`

for example:

`www.example.com/content?work=logo`

To customize the link further you can use an additional module: Query Parameters To URL to get:

`www.example.com/content/work/logo`

Views URL alias module might also be relevant.
> 1 votes

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


title: Node creation button/ link

text:
# Question
Title: Node creation button/ link
I'm new to Drupal 8.

I need to let users to create new node of some content type by pressing a button or custom link. In Drupal 7 I could achieve this by *Rules* and *Rules link* modules but I can't figure out how to do it in D8.

Let's assume I have a content type where all fields have default values and I want to create new node of this content type just by pressing a custom button.

How can I get this working in D8? Any tips?

# Answer
> 1 votes
Add a link for the route `node.add` in Twig:

```
<a href="{{ path('node.add', {'node_type': 'page'}) }}">{{ 'Add content of type "Basic Page"'|t }}</a>

```

# Answer
> 0 votes
If you set Permissions for the particular user Role to Create new nodes of a certain type, then simply linking them to the Node add page for that type is enough:

`node/add/article`

Because you have set the default value of each Field on your Content type, the Fields will already be prepopulated with the same default value.

The user will see the Create form, then just click on the Save button at the end.

To skip the Create form and automatically create the node with the default values you'll have to set up Rules with some custom components, or help convert the Rules link module to D8: https://www.drupal.org/project/rules\_link/issues/2619740

If you need to prepopulate the fields with different default values you can use the Prepopulate module.

---
Tags: 8, rules
---


# Question
Title: Editing Image of Media Type Image in Drupal
I'm having an issue with an Image field that I've set up under a Media Type. I'm able to create nodes, upload images or select images from the media browser just fine, but if I need to edit the node and change the photo, when I save it I get the following warning and my image disappears:

User warning: Missing file with ID image/jpeg. in Drupal\image\Plugin\Field\FieldType\ImageItem-\>preSave() (line 327 of core/modules/image/src/Plugin/Field/FieldType/ImageItem.php).

The only way I seem to get it working again is to completely delete the node and recreate a new one.

I have other fields set up the same way with normal content types and it works fine. Is there something I'm missing?

I'm using Drupal 8.5.3

# Answer
Check your Field Mapping for the Media type you created. Set them all to - Skip field - and you should be able to edit the media content without errors.
> 1 votes

---
Tags: theming
---


title: Returned content not displaying

text:
# Question
Title: Returned content not displaying
I have created a custom page which has a db query to return content, which is using the pagerdefault extender on a Drupal 7 install.

However when I return the content the pager shows but not the content. This is the code after the query:

```
$content = array();
foreach ($result AS $events)
{
    $content[] = '<div class=\'event\'>' . $events->type . ' - ' . $events->nid . ' - ' . $events->tutorial_start . $events->event_start . '</div>';
}
$build += $content;
$build['pager'] = array(
    '#theme' => 'pager',
    '#weight' => 1,
);
return $build;

```

I can see the $content rows if I dsm $build, but not display them on the page. How do I render them on the page?

# Answer
There are two things you should know to make it works:

1. Your query should extend `PagerDefault`.
2. Element inside `content` should be **Rendered Array**

here is a working example adjust the code to your needs:

```
//- Build array
  $build = array();
  /**
   * @TODO: adjust the query to your needs.
   */
  //- Prepare the Query to Extend PagerDefault
  $query = db_select('node', 'n')->extend('PagerDefault');
  $nids = $query
    ->fields('n', array('nid'))
    ->condition('type', 'page')
    ->condition('status', 1)
    ->execute()
    ->fetchCol();
  if (!empty($nids)) {
    $nodes = node_load_multiple($nids);
    $content = array();
    foreach ($nodes as $event) {
      //- Prepare the content
      $content[] = array(
        '#type'   => 'markup',
        '#markup' => '<div class="event">' . $event->type . ' - ' . $event->nid . '</div>',
      );
    }
    //- Add Content to the build
    $build += $content;
    $build['pager'] = array(
      '#theme'  => 'pager',
      '#weight' => 5,
    );
  }
  return $build;

```
> 0 votes

---
Tags: 7, theming
---


# Question
Title: Problems showing results in custom template .html.twig
I made a module that executes a query and shows the result in a page, the query is executed correctly, but the result is not shown in the template.

I know that the query is executed correctly because I used `var_dump()` to verify that.

This is the code in the controller.

```
public function ahcmembers() {

  $nums = array();
  $query = Drupal::entityQuery('node')
    ->condition('type', 'member')
    ->condition('field_member_type', 'number')
    ->execute();
  if (!empty($query)) {
    foreach ($query as $numId) {
      $num = Node::load($numId);
      $nums[] = $num;
    }
  }
  return array(
    '#theme'  => 'ahcmembers',
    '#titulo' => $this->t('Members'),
    '#nums'   => $nums,
  );
}

```

This is the code in the template:

```
<div>
{% if nums %}
    {% for n in nums %}
        <div>{{ n.get('title').value }}</div>
        <div>{{ n.get('field_member_type').value }}</div>
    {% endfor %}
{% endif %}
</div>

```

# Answer
Implement `hook_theme()` using code similar to the following one.

```
function MYMODULE_theme($existing, $type, $theme, $path) {
  return [
    'ahcmembers' => [
      'template'  => 'ahcmembers',
      'variables' => [
        'nums' => [],
      ],
    ],
  ];
}

```

Create a *ahcmembers.html.twig* template file inside MYMODULE/templates and clear the cache.
> 1 votes

---
Tags: 8, theming
---


title: Emails aren't sent

text:
# Question
Title: Emails aren't sent
I have Drupal Open Social distribution running in Compute Engine on Google Cloud. Compute Engine is essencially a virtual machine, very similar to Amazon EC2.

I have installed the SMTP Authentication module, and am using a google email address to send email, but none of the test emails are working.

Here are the configuration choices for the SMTP Authentication Module:
`Turn this module on or off: on`
`SMTP server: smtp.gmail.com`
`SMTP port: 465`
`Use encrypted protocol: Use SSL`
`Username: The Gmail address`
`Password: The Gmail password`
`E-mail from address: The Gmail address`
`E-mail from name: Default value`
`E-mail address to send a test e-mail to: Second Gmail address`

When clicking `Save configuration` to send the email, Drupal returns the following error message: `Unable to send email. Contact the site administrator if the problem persists.`

How can virtual machine and Drupal be configured to send email?

# Answer
> 1 votes
Google will be blocked your application, check this note:

> If you are using a program that Google does not consider secure, your usage will be blocked unless you enable less secure applications (a security setting that Google does not recommend). For more information see this link to determine the best approach for your mail client or application

https://www.digitalocean.com/community/tutorials/how-to-use-google-s-smtp-server

---
Tags: emails
---


title: Migrate from Ubercart 3 to Commerce

text:
# Question
Title: Migrate from Ubercart 3 to Commerce
I have been trying to understand how to accomplish this for quite some time. And I'm not getting anywhere. The info I'm finding seems a bit dated.

Can anyone tell me where to start to get this accomplished?

I am looking to migrate only products. Nothing else. The new site will be a fresh start other than product/inventory. And with some 1500 products, I really need a migration process.

Is there a template for Commerce Ubercart Migration that I am missing?

Thanks.

# Answer
Our official migration path lives in Commerce Migrate and contains migrations for Commerce 1.x, Ubercart 2.x (D6) and Ubercart 3.x (D7). Improvements are released monthly.
> 3 votes

---
Tags: commerce, migrations
---


# Question
Title: How to enable or disable the "Add to Cart" button for products based on the role of the store owner?
I have Drupal 8 and Commerce 2. I created a "Merchant" and "Premium Merchant" role. By default, users who create a store have the "Merchant" role.

What I am trying to do is the following.

* If the user has the "Merchant" role, the "Add to Cart" button on his products is deactivated for all users and visitors
* If the user has the "Premium Merchant" role, the "Add to Cart" button on his products is activated for all users and visitors

How do I activate or deactivate the "Add to cart" button of a store's products according to the role of the store owner?

The Rules module is of no use because it has been in development for several years and is still not usable.

To summarize, the rule should be:

* If the shop owner has the role "Premium Merchant", the products of his stores are purchasable
* If the shop owner has the role "Merchant", the products of his stores are not purchasable

I also installed the Commerce Add To Cart Link module, which may be useful in my use case.

### Option 1

In template files, may have conditions like the following.

```
{% if logged_in %}
...
{% else %}
...
{% endif %}

```

I discover programming. Can we write the rules of my questions in a template file?

```
<div{{ attributes }}>
  <a href="{{ url }}" class="add-to-cart-link" data-variation="{{ product_variation.id }}">{{ 'Add to cart'|t }}</a>
</div>

```

https://twig.symfony.com/doc/2.x/tags/if.html

### Option 2

I'm trying to create a custom module, but I do not know how to do it.

commerce\_add\_to\_cart\_access.info.yml
```
name: 'Commerce Add To Cart Access'
type: module
description: "Commerce Add To Cart Access for working with the commerce cart module."
# core: 8.x
package: Commerce
dependencies:
  - commerce:commerce_cart
  - commerce:commerce_product

# Information added by Drupal.org packaging script on 2018-10-25
version: '8.x-1.0'
core: '8.x'
project: 'commerce_add_to_cart_link'
datestamp: 1524519795

```
commerce\_add\_to\_cart\_access.module
```
<?php

/**
 * @file
 * Hook implementations of commerce_add_to_cart_access module.
 */

use Drupal\commerce_product\Entity\ProductType;
use Drupal\commerce_product\Entity\ProductVariationType;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Url;

/**
 * Implements ????? for commerce_product_variation.
 */
function ????? {
  /** @var \Drupal\commerce_store\CurrentStoreInterface $current_store */
  $current_store = \Drupal::service('commerce_store.current_store');
  $owner = $current_store->getStore()->getOwner();
  $build['add_to_cart_link']['#access'] = $owner->hasRole('premium_merchant');
  $form['access_denied'] = ['#markup' => t('No online sales'),];
}

```

# Answer
> 5 votes
I think the function you need is: `MYMODULE_form_commerce_order_item_add_to_cart_form_alter()` source

I have a similar setup, but I am using the Variation Cart Form module, so some of the details are different. In my case I'm using HOOK\_preprocess\_commerce\_product\_variation() function.

In either case, I recommend using the preprocess function AND a custom template. The preprocess can run some logic and pass a variable to the template, which is where you decide what to display. I find working with templates easier than render arrays.

In your case, the .module file could have:

```
function MODULE_form_commerce_order_item_add_to_cart_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  // Your original code to get store owner.
  $current_store = \Drupal::service('commerce_store.current_store');
  $owner = $current_store->getStore()->getOwner();
  // Default behavior is to disable add-to-cart button.
  $store_open = FALSE;
  if ($owner->hasRole('premium_merchant')) {
    // Only enable button if logic passes.
    $store_open = TRUE;
  }
  // Pass variable to the form.
  // Not sure this is correct in the case of a form.
  $form['store_open'] = $store_open;
}

```

And in the template you could have the logic you referenced above:

```
{% if store_open %}
  add to cart
{% else %}
  product unavailable
{% endif %}

```

FWIW, there may be other ways to solve this, which don't rely on the store owner's role. You could create a global variable, true/false, to run this check. In my case, I have a field on the products, so that some can be available to purchase and others not.

**EDIT**: the absolute easiest way is to avoid the template, as it's a relatively simple form element in this case. You can totally overwrite the form:

```
function MODULE_form_commerce_order_item_add_to_cart_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  // Your original code to get store owner.
  $current_store = \Drupal::service('commerce_store.current_store');
  $owner = $current_store->getStore()->getOwner();
  if (!$owner->hasRole('premium_merchant')) {
    // Overwrite the whole form markup!
    $form = ['#markup' => 'Not available for purchase'];
  }
}

```

To clarify, you don't need to `return $form` in this case, because the function is passing the form by reference, i.e. `&$form`.

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


# Question
Title: How to download a file from a system folder when a link is clicked?
I have a file("abc.csv") that is stored in the local system (for example: /var/a). I need to download the file when I hit a link in a Drupal site.

# Answer
Drupal comes with options to define where the website media/files are stored. You can find it under Configuration \> Media \> File system (`/admin/config/media/file-system`).

You can assign a folder on the local system/server that serves as a Public files folder, and another folder that serves as a Private files folder.

Public files can be accessed by anonymous users (if they know the link), but Private files can't be downloaded even if you know the link to them if you don't have the appropriate user role that has access to the file (through Drupal Permissions, and of course if your server setup is properly secured).

Both options are tightly connected with the server permissions configuration. It's very important to configure your Drupal installation with secure server user folders and files ownership and permissions. If you have a "leaky" configuration your website can be hacked easily. Read more about folders and files permissions: Securing file permissions and ownership.

That is why it isn't a good idea to allow your Drupal website to link to just any file on the server/local system, and instead Drupal gives you one location to store all of the files you might need to display/link on your website.

It is possible to configure your Drupal installation to use the `/var/a` folder to store the Public files, but it requires expert server administration knowledge to make it work and make it secure.

Usually the Public files folder is held in the location: `/sites/default/files` (this is relative to the Drupal root installation folder, it is inside the Drupal folder).

If you upload a file to a Drupal Field and you don't define any custom options, or if you directly upload your files to that location you can link to the file with this path:

`/sites/default/files/abc.csv`

The full link would be:

`<a href="/sites/default/files/abc.csv">Download my File</a>`

Drupal keeps a record of files uploaded through Files API, and you can use Views to create lists of files, that display file names, links to download, and even other file information. That is a very handy way to automatically create links to files, if you have a lot of them.
> 1 votes

---
Tags: files, media
---


# Question
Title: Independent search box for views taxonomy page
I'm using the "taxonomy term" view.

I would like to have a search form box independent of this page, which I will place for example in my navbar, allowing me to search among the terms of taxonomy, with autocompletion, and thus leading to the page of the corresponding term.

For example:

I have as taxonomy terms: tag1, tag2, tag3.

I'm on my home page, I type in the search form "tag2", I arrive on the page "tag2" with all the nodes having the tag "tag2", sort according to the criteria of the view.

I tried to create a separate block with views, but I do not get results.

I also tried to add a block to the "taxonomy term" view, but that does not work either.

Do you know how to do it ?

# Answer
> 0 votes
The quickest way to do it is by modifying the existing `Taxonomy term` View. It's good practice to Duplicate/Clone that View and work on the second instance, disable the original, so you always have the original for reference if you ever need it.

What you want is to:

1. add the Taxonomy term Filter to that View Page display, you can use the `Content: Has taxonomy term` Filter, choose your relevant Vocabulary and `Autocomplete`
2. Expose it,
3. then under Advanced Views options (third column) set `Exposed form in block:` to `Yes`
4. Save the Views
5. Go to Blocks configuration and add the newly created Block `Exposed form: clone_of_taxonomy_term-page` (it may be named differently for you) and add it to a Region of your choice

This Block (which is essentially a search form for Taxonomy term Views) will be visible on all pages of your website (unless you restrict the Block Visibility). You can be on your homepage, for example, and start typing a tag name, you will get the autocomplete suggestion list, and after you choose one and search for it you will be taken to the `/taxonomy/term/all?tid=tagname` page that will show nodes for that tag.

You can adjust the Views to get the path to read `/taxonomy/term/[tid]` after using that exposed search block (to get all the features of the original Taxonomy term views such as Title showing the tag name) but it requires some playing with it, maybe a different combination of Filter and Contextual filters.

# Answer
> 0 votes
You can achieve this in Drupal 7 and 8 using a mixture of modules such as:

Search API

> This module provides a framework for easily creating searches on any entity known to Drupal, using any kind of search engine. For site administrators, it is a great alternative to other search solutions, since it already incorporates facetting support and the ability to use the Views module for displaying search results, filters, etc. Also, with the Apache Solr integration, a high-performance search engine is available for this module.

Then you can use: Search API Autocomplete to accomplish the auto complete functionality you require

> The Search API Autocomplete module in action. This module provides autocomplete functionality for Search API searches.

And all of this is managed and is customizable via Views module and having a Search API Server that indexes what you want (Here are taxonomy terms for your case)

If you want to make it easier setting things up you can try Search API Pages

> This module is for creating simple search pages for the Search API project, not using Views or any other modules. They can be used when a view would be unnecessarily slow or complex, or for quickly testing out functionality. They also provide search blocks for starting a search from anywhere on the site.

---
Tags: 8, views
---


# Question
Title: Module compatibility between major Drupal versions
I am planning to use Drift chat on Drupal website, which is built in Drupal 7.

I could see Drift modules only for Drupal 8? Will this work with Drupal 7 as well?

# Answer
> 3 votes
> Will this work with Drupal 7 as well?

Nope. D7 and D8 are vastly different under the hood; therefore, there is no backward and no forward compatibility across Core versions. If there are none for D7 you will have to build one or upgrade your site to D8 if you see fit.

---
Tags: 7
---


# Question
Title: Naming conventions in Media entity vs File entity
The Media Library experimental module in core introduces a generic media type "file", while File entity calls the same thing "document". For comparison, the other bundle names are consistent between the two: image, audio, video.

**Why did Media Library in core decide to change the naming and precedence set by the File entity module in contrib?** I'm trying to wrap my head around the domain model here, to ensure I'm thinking about a Media Library in the correct way. From an end-user perspective, an *image* and a *video* are both *files* whereas a *document* is neither an image or video, so the delineation in File entity aligns better with reality.

This decision affects modules in the contrib space that want to build features around the emerging Media functionality in core, so an understanding of the domain model and intended usage will help build things up correctly, instead of taking things in parallel and incorrect directions.

# Answer
> 5 votes
After a bit of reading around, it seems that the core Media module was never adapted/updated from the File Entity module; it was a port of the Media Entity module (which didn't have its origins in File Entity either). See Bring Media entity module to core as Media module for the full details.

The "file" media type did have its origins in a plugin named "Document", provided by the Media entity document module, which provided the same basic functionality as File Entity's "document". So there may have been some crossover in their evolutions somewhere along the line.

But even so, reading through the proposal to Add "File" MediaSource plugin, it becomes clear that there was no intention to port the "document" type over in its previous form, rather just to use it as a starting point for the generic file type. From comment 24 on that issue, in response to a previous query of *I'm wondering whether file should be document instead? File seems really generic as image is also a file*:

> 26-1: As commented with @dawehner on the sprint, the idea is that the Image handler extends this plugin, so this name is probably the most appropriate in this case. A "Document" plugin can be created also extending "File", if needed to expose specific UI improvements for documents.

---
Tags: 8, media
---


# Question
Title: How to link to Entityform submissions page?
I am using an Entityform in a block to enable site users to submit enquiries to owners of holiday cottages. I need to be able to allow owners to view those enquiries.

Each holiday cottage has its own page and the Entityform appears on each of those pages.

I have created a submission reports view that will list the enquiries for a specific property.

I have also used Views to create a block to appear on the page of each holiday cottage, visible only to the logged-in owner of that cottage, containing a link for the owner to click on to “View enquiries”.

My problem is what link should I use to display the submissions? I have tried the link "entityform\_types/manage/accommodation\_contact/submissions” to be found under the ‘FORM SUBMISSIONS’ tab, but without success.

I have also read through all the documentation for Entityform that I can find as well as all issues relating to submissions here.

Any help or guidance would be much appreciated.

# Answer
> 1 votes
Entitform module comes with pre-built Views that list the Submissions. It is called Entityforms (Entityform Submission) and you can access the Page through

`/entityform-submissions/submissions/accommodation_contact/list`

or the Table where you can see submissions directly:

`/entityform-submissions/submissions/accommodation_contact/table`

Display one of these links in the Block you created for your owners:

`<a class="button" href="/entityform-submissions/submissions/accommodation_contact/table">View submissions</a>`

These Pages use the access permission `View any entityform submission` so allow your owners role this.

---
Tags: entities
---


# Question
Title: How do I programmatically add text to a page?
I am starting to write my first drupal module, but I need help on how to add content / text / data to the screen? I was able to add tabs and a url with hook menu, but I am unsure of how one goes about adding data you want to put there. If I wanted to say "hello world", what function / hook do I use to do that?

```
function sky_view_menu(){
    $items = [];
    $items['admin/skyview'] = array(
        'title' => 'Skyview Settings',
        'type' => MENU_NORMAL_ITEM,
        'access callback' => TRUE,
    );
    $items['admin/skyview/tab1'] = array(
        'title' => 'Skyview',
        'type' => MENU_DEFAULT_LOCAL_TASK,
        'access callback' => TRUE,
        'weight' => 0,
    );
    $items['admin/skyview/tab2'] = array(
        'title' => 'test1',
        'type' => MENU_LOCAL_TASK,
        'access callback' => TRUE,
        'weight' => 1,
    );
    $items['admin/skyview/tab3'] = array(
        'title' => 'test2',
        'type' => MENU_LOCAL_TASK,
        'access callback' => TRUE,
        'weight' => 2,
    );
    return $items;
}

```

# Answer
> 1 votes
You're looking for the `page callback`, which is:

> The function to call to display a web page when the user visits the path. If omitted, the parent menu item's callback will be used instead.

For example:

```
function sky_view_menu() {
  $items['admin/skyview'] = array(
    'title' => 'Skyview Settings',
    'type' => MENU_NORMAL_ITEM,
    'access callback' => TRUE,
    'page callback' => 'MYMODULE_skyview_admin_page',
  );

  $items['admin/skyview/tab1'] = array(
    'title' => 'Skyview',
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'access callback' => TRUE,
    'weight' => 0,
    'page callback' => 'MYMODULE_skyview_admin_tab_1',
  );
  ...
  return $items;
}

function MYMODULE_skyview_admin_page() {
  return [
    '#markup' => t('Hello world'),
  ];
}

function MYMODULE_skyview_admin_tab_1() {
  return [
    '#markup' => t('Hello tab 1'),
  ];
}

```

The function name itself is arbitrary, but for the sake of sanity it's best to name it as something that represents the route behind it.

---
Tags: 7
---


# Question
Title: Get taxonomy term field from where is attached
I have a taxonomy vocabulary like this:

```
A
|--B(branch_field)
   |-- C(branch_field)

X
|--Y(branch_field)
   |-- Z(branch_field)

```

Each user has a reference to a taxonomy term. I need to create a view where I pass taxonomy term attached to user for filtering data, but I need also to use the taxonomy term field "branch" in the view but I don't manage it.

This is what I see using Devel about user fields:

```
[field_category_user] => Array
            (
                [x-default] => Array
                    (
                        [0] => Array
                            (
                                [target_id] => 39
                            )

                    )

            )

```

Can I expose term field and target id?

# Answer
You can implement hook\_views\_query\_alter()

1. In your view create a filter (not exposed) to field\_category\_user, with default value -1. If field\_category\_user is not aviable you need create a realation to taxonomy.
2. Create a hook\_views\_query\_alter() in file \[module\_name\].views\_execution.inc with some like this:

// Implements hook\_views\_query\_alter().

```
function [module_name]_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
$id = $view->id();

switch ($id) {
    case '[your_view_id]':
        $user = \Drupal\user\Entity\User::load(\Drupal::currentUser()->id());
        $field_category_user = !$user->field_category_user->isEmpty() ? $user->field_category_user->value : null;

        if(!$field_category_user){
            return;
        }

        //Set field_category_user id to where condition
        foreach ($query->where as $key => $item) {
            foreach($item['conditions'] as $items){
                if ($items['field'] == 'field_category_user') { //Verify if field_category_user is the id of filter
                    $query->where[$key]['conditions'][0]['value'] = $field_category_user->id();
                }
            }
        }
    break;
}}

```
> 0 votes

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


# Question
Title: How to insert images into custom block type
This might be a really stupid question because I am overlooking something really simple but here is my issue. I have created a custom block in the custom block library in Drupal 8. I would like to insert images into the block from the images folder in my theme (not upload images using ckeditor).

Normally in Drupal 7 I can manually insert the image using an tag and all is good. In Drupal 8 this method is not working for me. Here is an example of the code that I enter into the source view:

```
<img class="socialmedia" src="/themes/custom/mytheme/images/social_media/facebook.png" />

```

However this does not work - no image is being displayed. I have verified that the path is correct, the spelling is correct, and tried with and without the leading slash. Nothing works.

I found a similar question, but the answers supplied don't address the question as they use php code.

What has changed between Drupal 7 and 8 in this regard? What am I missing?

Thanks

# Answer
> 2 votes
With twig you can use {{ directory }} to point your theme directory.

# Answer
> 0 votes
Use the FormattableMarkup class for this:

```
$image = new FormattableMarkup('<img class="socialmedia" src="@image" />', [
          '@image' => '/themes/custom/mytheme/images/social_media/facebook.png'
        ]);

$block['your_element'] = $image;

```

From the FormattableMarkup docs:

> When cast to a string, this object replaces variable placeholders in the string with the arguments passed in during construction and escapes the values so they can be safely displayed as HTML. See the documentation of \Drupal\Component\Render\FormattableMarkup::placeholderFormat() for details on the supported placeholders and how to use them securely. Incorrect use of this class can result in security vulnerabilities.

---
Tags: 8, blocks, media
---


title: Adding RSS feed view

text:
# Question
Title: Adding RSS feed view
I was trying to add a RSS feed view in Drupal 8. I selected *feed row style* for *Fields*, and clicked on *Save and edit*, but I got this message.

> Row style plugin requires specifying which views fields to use for RSS item.

>

What does this message mean?

# Answer
The error just means that the feed row style require fields, but the view being created doesn't have fields.
The error is confusing, since I can create a view like that and add a feed.

There are two ways for not getting that error: The first one is selecting *Table* as *Display format*, and *Content* as *Feed row style*, in the page to create a new view.

>

In this way, I got the view without errors.

>

The second way is creating a view without telling the Views module to include a feed. It will be created after.

On the page shown to create a view, I don't select *Include an RSS feed*, and I click on *Save and edit*.

>

On the next page, I click on *+Add* and choose *Feed* on the drop-down list that appears. (I cannot show it on the screenshot, but I can choose between *Attachment*, *Block*, *Embed*, *Entity reference*, *Feed*, and *Page*.)

>

On the next page, on the bottom, you will get the following error.

> Display "Feed" uses a path but the path is undefined.

>

Click on *No path is set*, and enter the path you want for the feed.

>

This is close to what the Views module gives you, with an exception: The feed is not attached to any page, since it says *Attached to: **None***.

Click on *None* and select to which pages the feed must be attached.

>
> 3 votes

---
Tags: views, feeds
---


# Question
Title: Set a condition for one field to be unique in all the content types.
I am working with Drupal 8, and have a custom post type called: chapter. This content type is connected with a taxonomy term called: Book.

Now, I have a field called: number, for specifying the chapter one, two or three. **this field should be unique.** For example, if I say chapter 1 I can not repeat it ever again in the same book, but I can upload the chapter 1 for another book. I also can upload all the chapters for the same book in a different order.

So the rule is: Just add a unique chapter number per book.

The final goal is to create a view and be able to order my chapters by the number.

Do I have to use the rules module for that? Or maybe, there is a better approach?.

# Answer
You can implement a custom validation constraint and a hook\_entity\_bundle\_field\_info\_alter to set the new constraint to your field.

Check: https://www.drupal.org/docs/8/api/entity-validation-api/providing-a-custom-validation-constraint
> 3 votes

---
Tags: views, rules
---


# Question
Title: How to add a time picker in datetime form elements
I have made a module that display a form. One of the form elements is a datetime field.

```
$form['FirstDate'] = array(
      '#type' => 'datetime',
      '#title' => t('First date-time'),
      '#id' => 'inputFechaMd',
      '#required' => TRUE,
      '#default_value' => '',
      '#prefix' => '<div class="row"> <div class="col-md-6">',
      '#suffix' => '</div>',
      '#attributes' => array('style' => array('margin-bottom: 1em;'))
    );

```

When the form is displayed It has two fields, one for date and one for time. The date field has a date picker, but the time field hasn't a time picker. I would like to add a time picker for this fields, but I don't know how to do it. Also, I would like to hide seconds and request only hour and minutes.

# Answer
> 2 votes
Your code renders a `time` type input for the second field, which will invoke the standard time widget for browsers that support it (most modern ones do).

For all browsers that I know of, that's a simple input mask and placeholders, not a dropdown picker like the date field. If you need such a picker, you'll have to find and integrate a JS library to get it.

You could do it yourself, but there's a contributed module, Datetime picker, which integrates 3 different time picker libraries so you can choose your favourite. If that doesn't give you exactly what you want, the code should at least give you a good starting point to implement your preferred solution.

In case you still need it, you can remove the seconds from the time input by setting `#date_increment` on the element to 60, which sets the `step` attribute on the element. That causes Chrome at least to only include placeholders for hours and minutes.

---
Tags: 8, forms, datetime
---


# Question
Title: How to change the name of uploaded file in my custom Entity?
I have a custom Content Entity created with

```
public static function baseFieldDefinitions(EntityTypeInterface $entity_type)

```

In the definition, there is a 'file' field:

```
$fields['file1'] = BaseFieldDefinition::create('file')
->setLabel(t('Fichier source'))
->setDescription(t('Source document (can be edited)'))
->setSettings([
'target_type' => 'file',
'file_extensions' => 'doc docx odt pages',
'file_directory' => 'contrats',
])
->setDefaultValue('')
->setDisplayOptions('view', [
'label' => 'above',
'type' => 'string',
'weight' => 7,
])
->setDisplayOptions('form', [
'type' => 'string_textfield',
'weight' => 7,
])
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE)
->setReadOnly(TRUE);

```

And it works fine!
My question is: how can I change the name of an uploaded file?
I guess I should use hook\_entity\_presave.
But how to retrieve file information in hook\_entity\_presave?
Using the comments already given (thanks), I added this:

```
function tempo_entity_presave(EntityInterface $entity)
{
if ($entity->getEntityType()->id() == "amap_contrats") {
$sName  = 'Contrat-'.$entity->typecontrat->target_id.'-'.str_replace("-", "", $entity->datedebutcontrat->value);
$fid1[0]['target_id'];
$fid1 = $entity->get('file1')->target_id;
$file = file_load($fid1);
$sName1 = $sName.'.'.pathinfo($file->filename->value, PATHINFO_EXTENSION);
$result = file_move($file1, $sName1, FILE_EXISTS_REPLACE);
$sName2 = $sName . '.pdf';
$result =file_move($file2, $sName2, FILE_EXISTS_REPLACE);
}
}

```

And now, I get this error:

```
Argument 1 passed to file_move() must implement interface Drupal\file\FileInterface, null given, called in /Applications/MAMP/htdocs/JdP8M3/modules/custom/tempo/tempo.module on line 48 in /Applications/MAMP/htdocs/JdP8M3/core/modules/file/file.module on line 216 #0 /Applications/MAMP/htdocs/JdP8M3/modules/custom/tempo/tempo.module(48): file_move(NULL, 'Contrat-5-20170...', 1)

```

Any idea?

OK, I got it! My mistake: I `load '$file'` and I try to `file_move '$file1'` :-(

# Answer
> 0 votes
Please refer the below articles it will be helpful for you..

How do I change the uploaded file name after the node has been saved?

Changing file name on upload

# Answer
> 0 votes
Being newbie in drupal and spending my three hours to alter the form from function `MY_THEME_form_user_form_alter(&$form, &$form_state, $form_id)`, I was able to achieve what I wanted. I found `setFileUri` and `file_move` helpful altogether. I am just curious about if there is any loophole if I just use this much code. Do I need to do anything else apart form this?

```
  $file_name = "";
  $username = "";
  $fid_0 = 'photo';
  $uid = $form_state->getValue('uid');

  if ($form_state->hasValue('user_picture')) {
    $username = $form_state->getValue('field_username')[0]['value'];

    $fid_0 = $form_state->getValue('user_picture')[0]['fids'][0];
    $file_name = $uid . '-' . strtolower($username) .'-'. $fid_0;
    $file_name = trim(preg_replace("/[^0-9A-Za-z]/", '-', $file_name));
    $file = \Drupal\file\Entity\File::load($fid_0);

    $old_file_name = $file->getFilename();
    $old_file_name = preg_replace('/\\.[^.\\s]{3,4}$/', '', $file->getFilename());

    $new_filename_uri = str_replace($old_file_name, $file_name, $file->getFileUri());

    file_move($file, $new_filename_uri);
    $file->setFilename($file_name);
    $file->setFileUri($new_filename_uri);
    $file->save();
  }

```

---
Tags: 8, entities
---


title: Migration Custom Plugin Return Value

text:
# Question
Title: Migration Custom Plugin Return Value
I have a migration and it is very simple. I have a CSV file of employee number and years of service. I have added the two fields to the users in the system and populate them when the users have been added. I now I have a yearly file to update the years of service value. I created the below Migration to import/update the seniority:

```
id: seniority_import
label: Seniority CSV file import
description: Seniority CSV file import
migration_group: timeoff
migration_tags:
  - seniority_timeoff
langcode: en
status: true
dependencies:
  enforced:
    module:
    - timeoff_seniority
source:
  plugin: csv
  track_changes: true
  path: "/Users/rfulcher/Downloads/Seniority2017-2.csv"
  keys:
    - EMPNO
  column_names:
    0:
      EMPNO: "Employee Number"
    1:
      SENIORITY: "Employee Seniority"
process:
  uid:
    -
      plugin: user_lookup
      source: EMPNO
      value_key: field_employee_id
      entity_type: user
      bundle: 1
      bundle_key: status
      ignore_case: true
    -
      plugin: skip_on_empty
      method: row
      source: uid
      message: 'no empno found'
  field_employee_id: {}
  field_seniority: SENIORITY
destination:
  plugin: entity:user
  overwrite_properties:
    - field_seniority

```

I also create the custom process plugin to lookup the uid of the user using the employee number

```
   <?php

namespace Drupal\timeoff_seniority\Plugin\migrate\process;

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

/**
 * Returns a user if exists.
 *
 * Example:
 *
 * @code
 * process:
 *   field_your_field_name:
 *     -
 *       plugin: your_plugin_name
 *       source: some_source_value
 * @endcode
 *
 *
 * @see \Drupal\migrate\Plugin\MigrateProcessInterface
 *
 * @MigrateProcessPlugin(
 *   id = "user_lookup"
 * )
 */
class UserLookup extends ProcessPluginBase {
  /**
   * {@inheritdoc}
   */
  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {

    $user_uid = $this->getUserByEmpNo($value);

    if ($user_uid == FALSE){
      drush_print('usernotfound for ' . $value . ' returning 0');
      return 0;
    } else {
      drush_print('userfound:'.$user_uid.': for ' . $value);
      return $user_uid;
    }
  }

  protected function getUserByEmpNo($employeenumber) {

    $id = \Drupal::entityQuery('user')
                  ->condition('field_employee_id', $employeenumber)
                  ->execute();
    $users =  \Drupal\user\Entity\User::loadMultiple($id);

    if (!empty($users)) {
      foreach ($users as $user) {
        $update_id = $user->id();
        return $update_id;
      }
    } else {
      return FALSE;
    }
  }

  public function prepareRow($row) {

  }
}

```

The import runs and I find the uid and return the value but it is like the migration ignores it and skips the row.

Am I missing something. I have worked on this way too long and this should be simple but I must not be understanding how this is supposed to work or something. I am totally at a loss.

Simple csv file with just two fields empno, seniority. Nothing fancy. Any help with this would be appreciated, thanks very much.

Thanks

# Answer
> 0 votes
I think the problem might be the `source` on the `skip_on_empty` plugin. It looks like you're trying to refer to the result of the previous plugin to obtain the destination `uid`; I don't think you can do that until after all plugins have run on the field.

Even if you can make that reference, there's a special syntax for referring to destination fields on the source side, which is an @ symbol plus the field name (e.g. `'@uid'`).

A solution that should remove all doubt would be to load the uid in a fake field, and re-use it for the proper destination field. For example:

```
process:
  _uid:
    plugin: user_lookup
    source: EMPNO
    value_key: field_employee_id
    entity_type: user
    bundle: 1
    bundle_key: status
    ignore_case: true
  uid:
    plugin: skip_on_empty
    method: row
    source: '@_uid'
    message: 'no empno found'

```

Of course that might be wrong, and you may just have meant to use `EMPNO` instead of `uid` for the source, in which case you should just fix that and move the `skip_on_empty` plugin so it runs first, saving yourself DB queries with empty conditions.

---
Tags: 8, migrations, plugins
---


# Question
Title: How can I find the image style source from a template file?
Why cannot I use `{{ file_url(node.field_image.0.entity.uri.value) }}` in a view?

>

It does not return */drupal-8.6.1/sites/default/files/2018-10/gen9C52.tmp.jpeg* as I expect.

# Answer
> Why I can't use {{ file\_url(node.field\_image.0.entity.uri.value) }} in my custom view

Simply because your view does not have access to the node variable object.

You can use Image URL Formatter module. Then add your image field and for formatter select Image URL.
> 2 votes

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


# Question
Title: Different registration procedures (with or without approval) for different roles?
I am currently setting up a simple LMS in D8 and would like to create different registration procedures for different kinds of users. In particular:

* There should be a registration page for **simple member profiles**: Only basic user data should be required and the account should be unlocked immediately after registration (and e-mail confirmation).
* There should be a second registration page for **student profiles**: They need to upload a valid student identity card, which is why their registration requires admin approval.

I have already set up different registration profiles/pages for members and students and after registration the correct role is automatically assigned to the new user. So, that is working well already.

However, I need to also set up a different approval process, depending on the registered role and I'm not sure, how to approach this. Note: I really don't want this to be a two-step process, where students register as members first and only then upload the required documents. I need to make this as easy and quick as possible for them, while at the same time allowing for unrestricted member registrations.

Note that I'm working in D8 and I'm hesitant to install the `Rules` module, as there doesn't seem to be a stable version yet. Or is it usable?

Can this be done? Any help?

# Answer
So, first of all, I'd like to refer to my other answer here, it's good to take a look

You are going to be needing to separate webforms, each with its own required fields, then after building our webform, in `Emails \ Handlers` section located at `admin/structure/webform/manage/[WebformName]/handlers`. We are going to enable our custom `webform handler` module.

> One thing that you need to make sure is correct, is the structure of the module folder, so that webform would read it as a `handler`, we assume the module name here is: `webform_handler_user_creation` so the structure would be something like this: `webform_handler_user_creation>src>Plugin>WebformHandler>UserCreationHandler.php` with a `webform_handler_user_creation.info.yml` file in the root of the module directory.

With all that said, here's an example of the module on my github page

So what we need to do first is to make sure we do create our users after saving the webform submission, then load the submission values and use them based on their machine names to fill in our user creation thingy, here's an example code:

```
<?php
namespace Drupal\webform_handler_user_creation\Plugin\WebformHandler;
use Drupal\Core\Form\FormStateInterface;
use Drupal\webform\Plugin\WebformHandlerBase;
use Drupal\webform\WebformSubmissionInterface;
use Drupal\webform\Entity\WebformSubmission;
/**
 * Webform submission action handler.
 *
 * @WebformHandler(
 *   id = "usercreate",
 *   label = @Translation("User Create"),
 *   category = @Translation("Action"),
 *   description = @Translation("Creates a user after submission"),
 *   cardinality = \Drupal\webform\Plugin\WebformHandlerInterface::CARDINALITY_UNLIMITED,
 *   results = \Drupal\webform\Plugin\WebformHandlerInterface::RESULTS_PROCESSED,
 *   submission = \Drupal\webform\Plugin\WebformHandlerInterface::SUBMISSION_OPTIONAL,
 * )
 */
class UserCreationHandler extends WebformHandlerBase {
  /**
   * {@inheritdoc}
   */
  public function postSave(WebformSubmissionInterface $webform_submission, $update = TRUE) {
        $user = \Drupal\user\Entity\User::create();
        $language = \Drupal::languageManager()->getCurrentLanguage()->getId();
        $user_name = $webform_submission->getElementData('user_name');
        // Mandatory user creation settings
        $user->enforceIsNew();
        $user->setPassword('testPassword');
        $user->setEmail('test@example.com');
        $user->setUsername($user_name); // This username must be unique and accept only a-Z,0-9, - _ @ .
        $user->set("langcode", $language);
        // Optional settings
        $user->set("init", 'email');
        $user->set("preferred_langcode", $language);
        $user->set("preferred_admin_langcode", $language);
        $user->activate();
        // Add a custom role
        $user->addRole('CustomRoleName');
        //Save user
        $user->save();

  }
}

```

So based on your use case, you can add the user with a custom role with `$user->addRole('CustomRoleName');` and maybe activate it with `$user->activate();` it or a lot other things. You will be needing two different handlers/module with different concept for each role, one for **simple member profiles** and one for **student profiles**
> 1 votes

---
Tags: 8, users
---


# Question
Title: How to write hook_field_placeholder_info() for the link module?
The contributed project **Field placeholder** lets one use HTML5 placeholder attribute. The project page says:

> By default, this module integrates text, number and mail modules, but any other widget type can be added through `hook_field_placeholder_info()`.

I've tested this with a “Text” field, and it works as advertised.

I want to add `hook_field_placeholder_info()` for the **Link** module.

According to `field_placeholder.api.php`, this hook should return:

> An array whose keys are the widget names and whose value are the widget item where the placeholder will be attached.

So far I've tried this:

```
/**
 * Implements hook_field_placeholder_info().
 */
function mymodule_field_placeholder_info() {
  return array(
    'link_field' => 'value',
  );
}

```

This puts the widget for the placeholder settings on the admin page where one manage the link file, but setting a placeholder value has no effect when I create a new node with a link field.

I believe the problem is “`value`”. According to the documentation, it should be the “widget item where the placeholder will be attached”.

I am not sure what that is. So far I've tried “`value`”, “`link_field`”, “`link`”, and “`url`” (clearing the cache before testing each in turn), but none of these work for the link field.

So: How to write hook\_field\_placeholder\_info() for the link module?

# Answer
> 1 votes
There is a feature request to add support for the link module. Unfortunate that patch has not been committed yet, but you can use/apply the patch in #5 and use

```
/**
 * Implements hook_field_placeholder_info().
 */
function mymodule_field_placeholder_info() {
  return array(
    'link_field' => 'url',
  );
}

```

---
Tags: entities, 7
---


# Question
Title: How do you add an incrementing primary key to an existing table?
I'm working on the contributed Login History module which has an existing table that does not have a primary key. I'd like to add a primary key to the table, but am struggle with the `db_add_field` syntax for upgrades. The existing table is:

```
/**
 * Implements hook_schema().
 */
function login_history_schema() {
  $schema['login_history'] = array(
    'fields' => array(
      'uid' => array(
        'type' => 'int',
        'not null' => TRUE,
        'description' => 'uid of user.',
      ),
      'login' => array(
        'type' => 'int',
        'not null' => TRUE,
        'description' => "Timestamp for user's login.",
      ),
      'hostname' => array(
        'type' => 'varchar',
        'length' => 128,
        'not null' => TRUE,
        'default' => '',
        'description' => "The user's host name.",
      ),
      'one_time' => array(
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
        'size' => 'tiny',
        'description' => 'Indicates whether the login was from a one-time login link (e.g. password reset).',
      ),
      'user_agent' => array(
        'type' => 'varchar',
        'length' => 256,
        'not null' => TRUE,
        'default' => '',
        'description' => 'User agent (i.e. browser) of the device used during the login.',
      ),
    ),
    'indexes' => array(
      'login_history_uid' => array('uid'),
      'login_history_onetime' => array('one_time'),
      'login_history_uid_host' => array('uid', 'hostname'),
    ),
  );
  return $schema;
}

```

And what I *think* should work to add a primary key is a hook\_update like this:

```
/**
 * Add device_id and login_id columns.
 */
function login_history_update_7106() {
  if (!db_field_exists('login_history', 'login_id')) {
    db_add_field(
      'login_history',
      'login_id',
      array(
        'description' => 'The primary identifier for a login.',
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      array('primary key' => array('login_id')));
  }
}

```

However, that results in this error:

```
SQLSTATE[42000]: Syntax error or access violation: 1171 All parts of a PRIMARY KEY must be NOT NULL; if you need NULL in a key, use UNIQUE instead                                                                                [error]

```

I've tried:

* Reading and re-reading the docs for `db_add_field` and `db_change_field`
* Using `db_add_field` to add an empty int field and then using `db_change_field` to make it a serial primary key.
* Using `db_add_field` without the 4th parameter that sets the new primary keys and then trying to use `db_add_primary_key('login_history', array('login_id'))` but that gives an error before the field is even added saying that auto\_increment fields have to be part of a unique key.

I've grepped core and some contrib looking for instances of adding an auto increment primary key and can't find any for Drupal 7.

# Answer
> 5 votes
This actually seems to be an issue in Drupal Core where creating a serial field on an existing table is not possible in MySQL 5.7+ without first creating an int field and converting that to autoincrement (this issue does not show up in MySQL 5.6 and below). Please see https://www.drupal.org/node/2615496 for a patch that fixes this issue for new releases of MySQL. It might be worthwhile to update that patch to be rolled into 8.x so it will allow us to patch 7.x.

# Answer
> 3 votes
I believe the problem here is that db\_add\_field() doesn't insert any data in the new column unless you provide a 'default' or 'initial' key in the spec parameter. But those only take a single value, which is inappropriate for a serial column.

You'll have to accomplish this in a couple of steps: create a new integer field without an index, insert unique data in it (doesn't have to be strictly auto-incremented, but that looks nicer), and then use db\_change\_field() to make it serial (including the necessary index).

If that doesn't work for some reason, you can create the entire table anew with the auto-increment column, then copy the data to the new table so that it generates your primary key data automatically. Depending on how big {login\_history} is, that might be something you do in a batch.

# Answer
> 1 votes
This will add an auto increment PRIMARY field to your table with incremental values againt existin records.

```
/**
 * Add device_id and login_id columns.
 */
function login_history_update_7106() {
  db_query('ALTER TABLE tbl ADD id INT PRIMARY KEY AUTO_INCREMENT');
}

```

# Answer
> 1 votes
The previous answers already describe the reason for the issue - you are not allowed to add a serial field, because db\_add\_field cannot add the index at the same time. The suggested patch is not likely to make it into core in the foreseeable future. That is why you need to add the field as `int` first, and then change it to serial and add the primary key.

Changing the empty `int` field into `serial` will automatically fill it with values, but they may not match the order you expect.

Filling the values may be challenging if you do not have proper unique keys to sort by. Using a temporal table for filling the values with the correct order is a neat trick.

Assuming that you have updated `hook_schema()` with the new serial field and primary key definition, here is a code snippet for D8:

```
use Drupal\Core\Database\Database;

/**
 * Add login_id serial column.
 */
function login_history_update_8106() {
  $db = Database::getConnection();
  $schema = $db->schema();
  $spec = login_history_schema();
  $table_definition = $spec['login_history'];

  if (!$schema->fieldExists('login_history', 'login_id')) {
    // Fill-in the auto-increment values in a temp table.
    $schema->createTable('login_history_tmp', $table_definition);
    $db->query("INSERT INTO {login_history_tmp} (<all fields here except for login_id>)
      SELECT <all fields here except for login_id>
        FROM {login_history}
        ORDER BY created");
    // Rename the temp table as primary.
    $schema->dropTable('login_history');
    $schema->renameTable('login_history_tmp', 'login_history');
  }
}

```

---
Tags: 7, database
---


# Question
Title: How to compare text input with a user password stored in the database?
I've been trying to compare password values using a custom form.

Actually I want to show a **relogin form** after a particular amount of time. So I have created a custom form with two fields – email and password. And now I want to compare the password input from my custom form with the user's password stored in the database. If the passwords are same, then the user will be allowed to access the site agin.

I can't compare the hashed password with the custom form password. I know we can't compare the password values, because the password in the database is hashed.

Is any other way to compare them?

# Answer
The only advisable approach would be to use `user_check_password`:

```
$account = user_load(123);
$valid = user_check_password($password_from_form_submission, $account);
if ($valid) {...}

```

If you desperately need to do it manually, just copy the parts of that function that make sense for your requirements.
> 1 votes

---
Tags: 7, users, forms
---


# Question
Title: DraggableViews not displaying drag-handles
I installed the DraggableViews module on Drupal 8. On one of my views, I replicated the page that I currently use to display the content that I want. I renamed the new page adding "Admin" to the title Then I follow the instructions I found on various places:

1. Change the Admin block Format section and choose Table.
2. Add the field "Draggableviews: Weight" at the Fields section, place it after the "Content: Title" field.Make sure not to check "Exclude from display". Please note that the instructions mention the "Draggableviews: Content" field but I don't have this option (Is there something wrong here?)
3. Add "DraggableViews: Weight" at the Sort criteria section and place it as the first Sort criteria.
4. Save the view.

then I get a page the list all my items, show the weight of each of the items (0 by default) but I can't change the weight and no drag-handles are shown.

Any help?

# Answer
> 1 votes
All "draggable" tables in Drupal have a switch that turns the draggable javascript interface off, and allows you to order the items using a less interactive "ordinary" form with fields to enter weight numbers and a submit button.

There is a link, usually at the top right of the table, that says **Hide row weights** if you have the draggable option turned off, and **Show row weights** if you have it on.

Look for that link, it's probable you just have it turned off.

Once you make the switch it will be "remembered" in a cookie so it will apply for all the draggable tables on the site. Maybe you changed it on some other table, Drupal remembered it, and you're simply seeing the non-draggable case in your draggable views.

I guess this brings up to the surface that "Draggable views" isn't quite an accurate name, because it works even without dragging. Maybe it should be called "Order views" or something similar, but javascript tools usually win that race and this example illustrates it.

I hope this is the issue here. Nothing broken, just a temporary UI blindspot, we've all been there :)

---
Tags: views, 8
---


# Question
Title: how rewrite pagination URL views for SEO?
i am trying to rewrite the views url pagination :

> /mypath/cat?page=1

to

> /mypath/cat/1 or \> /mypath/cat/page/1 or /mypath/cat-1

**cat is a taxonomy term.**

I have tried to rewrite url with Drupal\seo\PathProcessor but without really success...

> Code for rewrite /mypath/cat?page=1 to /mypath/cat-1 :

```
    public function processInbound($path, Request $request) {

        $page = \Drupal::request()->query->get('page');

        if($path == '/mypath/cat' && $page>0) {
            \Drupal::request()->query->set('page', $page);
            return $path.'-'.$page;
        }

        return $path;
    }

    public function processOutbound($path, &$options = [], Request $request = NULL, BubbleableMetadata $bubbleable_metadata = NULL) {
        return $path;
    }

```

This ll redirect to **/mypath/cat-1?page=1.**

That broke the views filter too, it's normal.

i can alter the views filter for remove the "-" but how remove the ?page=1 from the uri ?

This is the right way for alter the url views pagination ?

# Answer
In Drupal 7 you can use Query Parameters To URL but the D8 port needs more work. Maybe you can help with that in the course of the work for your current project?

It's similar with Clean Pagination that cleans up the pagination specifically, D8 needs more work.

In the meantime maybe you can replace some of the exposed Views filters with contextual ones, they take arguments separated with `/`.

With a Contextual filter you can display a Summary of taxonomy term names at the top of your views (or any region for that matter) instead of an exposed filter with the term names. That way you would see a list of terms as links at the top of your Views, and the links paths would look like `mypath/cat`.

Pagination would still add `?page=1` so you'd have `mypath/cat?page=1` unless you get the Clean Pagination running.
> 2 votes

---
Tags: views, 8, uri, paging
---


# Question
Title: How do I order a search query by best match?
I am using the following code.

```
$query = \Drupal::entityQuery('node');
  $query->condition('status', 1);
  $query->condition('type', 'article');
  for ($i = 0; $i < count($split_keys); $i++){
  $group = $query->orConditionGroup()
  ->condition('title', '%'.$keys.'%' ,'LIKE')
  ->condition('body', '%'.$keys.'%' ,'LIKE')
  ->condition('title', '%'.$split_keys[$i].'%' ,'LIKE')
  ->condition('body', '%'.$split_keys[$i].'%' ,'LIKE');
  }
  $query->range(10,20);
  $query->addExpression('CASE WHEN title like %'.$key.'% THEN 0
       WHEN title like %'.$split_keys[$i].'% THEN 1
       WHEN body like %'.$keys.'% THEN 2
       WHEN body like %'.$split_keys[$i].'% THEN 3
       ELSE 4 END', 'order_col');
  $query->sort('order_col', 'ASC');
  $entity_search = $query->condition($group)->execute();

```

I am trying to sort by best match, but I get the following error.

> Call to undefined method Drupal\Core\Entity\Query\Sql\Query::addExpression()

How can I fix the code?

# Answer
> 1 votes
An entity query can't have arbitrary expressions added to it. To proceed with your current approach you'll need to execute a raw query against the database.

But to address your actual question, *How to create search query in Drupal 8 order by best match*, the answer is to use the Search API module:

> This module provides a framework for easily creating searches on any entity known to Drupal, using any kind of search engine. For site administrators, it is a great alternative to other search solutions, since it already incorporates facetting support and the ability to use the Views module for displaying search results, filters, etc. Also, with the Apache Solr integration, a high-performance search engine is available for this module.

In my experience the Solr integration is excellent, but if you don't have a Solr server handy, you can always fall back on the included database backend module. I would imagine that the results you get using search API will be better than any query you can put together yourself in any short amount of time.

---
Tags: 8, database
---


# Question
Title: How to render two views in the same twig template
I want to render two views in the same twig template, but only one of them is rendered, and the second is always override with the same content as the first one.
I have a content type 'contacts' and when its nodes are displayed (full view) I want to render two views in the same page after the node fields. I use a twig template node--contacts.html.twig :

```
.....  node fields twig template ....
{{ viewCalls }}
....
{{ viewAppointments }}
....

```

And my `function my_theme_preprocess_node(&$variables)` in my .theme file:

```
....
$view = \Drupal\views\Views::getView('view_calls');
$view->setDisplay('default');
$view->setArguments(array($variables['node']->id()));
$view->setOffset(0);
$view->execute();
$variables['viewCalls'] = $view->render();

$view2 = \Drupal\views\Views::getView('view_appointments');
$view2->setDisplay('default');
$view2->setArguments(array($variables['node']->id()));
$view2->setOffset(0);
$view2->execute();
$variables['viewAppointments'] = $view2->render();
.....

```

As I said, the second view always shows the same content as the first. If I reverse the order of rendering, then the content is reverse too, and the one which is first rendered is the only one I see, and always two times. It is as `{{ viewCalls }}` and `{{ viewAppointments }}` always get the same content.

# Answer
The reason you get the same content is due to the `#cache` property of the render array you get when you call the `render()` method.

Most specifically, by calling `setOffset()` earlier in your code, you are implicitly setting a cache key on the render array, (see here):

> ```
> $this->element['#cache']['keys'][] = 'offset:' . $offset;
>
> ```

This cache key setting, in combination with the `#theme` property of the render array (`views_view`), which is the same for both views, will result in getting a cached version of the first one when including the second one, since the \[`#theme`\] + \[`#cache`\]\[keys\] combination is identical for both views.

To work around that you could:

1. Remove caching completely for these views, or
2. Avoid using `setOffset()`, or
3. Add more specific keys to the cache so that you have a different cache for each view. E.g.

```
$variables['viewCalls']['#cache']['keys'] =
  array_merge(
    $variables['viewCalls']['#cache']['keys'],
    array('viewCalls')
  );
...
$variables['viewAppointments']['#cache']['keys'] =
  array_merge(
    $variables['viewAppointments']['#cache']['keys'],
    array('viewAppointments')
  );

```

I tested your case using the 3. option and it worked as expected, I think before resolving to using another module, you could try sticking to your original code and appropriately modifying the `#cache` property of both render arrays.

Good luck!
> 10 votes

# Answer
Render two views in the same Twig template with the render element `view`:

```
$variables['viewCalls'] = [
  '#type' => 'view',
  '#name' => 'view_calls',
  '#display_id' => 'default',
  '#arguments' => [$variables['node']->id()],
];

$variables['viewAppointments'] = [
  '#type' => 'view',
  '#name' => 'view_appointments',
  '#display_id' => 'default',
  '#arguments' => [$variables['node']->id()],
];

```
> 4 votes

# Answer
There's at least one typo in your code. Remove the space in `$variables['viewAppointments ']`.

---

Alternatively you could also use Twig Tweak. Which will provide you a function you can use to place views directly in your templates.

```
{{ drupal_view('who_s_new', 'block_1', arg_1, arg_2, arg_3) }}`

```

> Twig Tweak is a small module which provides a Twig extension with some useful functions and filters that can improve development experience.

Read the full guide on Twig Tweak and Views.

> Twig Tweak's `drupal_view()` method provide's access to embed views within any Twig code, including dynamically from within each row of another view. This feature provides an alternate method to accomplish the nesting provided by the Views field view module.
> 3 votes

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


# Question
Title: User should not be allowed to edit language
I have a question regarding this. I have a Multilingual site in drupal 8 and i want to disable the edit language for user, so they can´t change the language, if they have chosen one or redirect them, if they are trying. Of course if you are administrator, you should be able to change their languages and my own.

Any modules, which can do this or configuration somewhere in the i18 module? Or does this require a custom made module?

Thank you for your time.

# Answer
There are options under `Configuration » Regional and language » Languages » Detection and selection` where you can set the **User** Detection method to be the first one, or maybe the only one, that determines which language to display the site in.

This way the logged in users would only be able to see the site in the language chosen in their profiles.

To prevent them from changing it try Language access.
> 0 votes

---
Tags: i18n-l10n
---


title: How to display a button with “markup”?

text:
# Question
Title: How to display a button with “markup”?
I created a custom module and in the code below the button is not rendered, there is only the text :

```
$form = ['#markup' => '<button type="button" class="btn btn-success" disabled="disabled">Product unavailable</button>'];

```

How to display the button?

```
<?php

/**
 * @file
 * Hook implementations of commerce_add_to_cart_access module.
 */

use Drupal\commerce_product\Entity\ProductType;
use Drupal\commerce_product\Entity\ProductVariationType;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Url;

function commerce_add_to_cart_access_form_commerce_order_item_add_to_cart_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  // Your original code to get store owner.
  $current_store = \Drupal::service('commerce_store.current_store');
  $owner = $current_store->getStore()->getOwner();
  if (!$owner->hasRole('marchand_premium')) {
    // Overwrite the whole form markup!
    $form = ['#markup' => '<button type="button" class="btn btn-success" disabled="disabled">Product unavailable</button>'];
  }
}

```

# Answer
> 10 votes
You can use the inline\_template to solve the problem:

```
// Delete the other button.
unset($form);
$form['submit'] = [
  '#type' => 'inline_template',
  '#template' => '<button type="button" class="btn btn-success" disabled="disabled">Product unavailable</button>',
];

```

# Answer
> 1 votes
I don't know much about `commerce`, but I think you need to output a render array rather than actual HTML.

So replace `$form = ['#markup' ...` with something like the following:

```
// Add the new button to the form
$form['button'] = [
  '#type' => 'button',
  '#value' => t('Product unavailable'),
  '#attributes' => [
    'class' => ['btn', 'btn-success'],
    'disabled' => 'disabled'
  ],
];

```

See this link for what you can render with Drupal https://api.drupal.org/api/drupal/namespace/Drupal%21Core%21Render%21Element/8.5.x

---
Tags: 8, theming, forms, commerce, bootstrap-theme
---


# Question
Title: Confused about Owl carousel with Paragraph
I'm very new to Drupal and not (yet) familiar with the terms and namings.

I came across a web site in Drupal 8 that uses Paragraph. I'm trying to reproduce the slideshow that apparently uses Owl carousel. But I'm confused about how they made that slider:

(These images slide from right to left)

In the Inspector, the code shows that Owl carousel used in the div wrapper and each item. But there is no owl included in the template twig file.

Inspector screenshot:

Template twig file:

```
     <div class="our_partners_area bg_gary py-70 pb_0">
        <div class="container">
           <div class="our_partners_h wow fadeInUp">
              <h1>{{content.field_title.0}}</h1>
              <p>{{content.field_description.0}}</p>
           </div>
           <!--#Start assets/images start -->
           <div class="partners wow fadeInUp">

       {% for item in paragraph.field_client_image %}
         <div class="item">
           <img src="{{ file_url(item.entity.uri.value) }}" alt="">
           </div>
        {% endfor %}

     </div>
     <!--#End assets/images -->
 <div class="bottom-partner wow fadeInRight text-center" style="visibility: visible; animation-name: fadeInRight;">
              <a id="#services" href="{{ content.field_button.0['#url'] }}" class="btn btn-default  wow fadeInUp  js-scroll-trigger" data-wow-delay=" 0.5s"
              style="visibility: visible; animation-delay:  0.5s; animation-name: fadeInUp;"><span class="skew_14">{{ content.field_button.0['#title'] }} </span></a>
           </div>
        </div>
     </div>

```

I assume the below code generates the classes `owl-item`, `owl-item cloned`:

```
{% for item in paragraph.field_client_image %}
     <div class="item">
       <img src="{{ file_url(item.entity.uri.value) }}" alt="">
         </div>
{% endfor %}

```

Anyone can enlighten my candle?

PS: I have access to all templates files and even have access to the site: no Owl carousel module installed but the libraries is present.

Thanks for your time.

# Answer
> 2 votes
You have to separate between two components:
A) Markup generated on server-side by Drupal, which is used as base structure for Owl carousel.
B) Markup modified by Owl in the client's browser.

Drupal render's something like

```
<div class="partners wow fadeInUp">
  <!-- the for loop renders one <div><img></div> per paragraph on server side -->
  {% for item in paragraph.field_client_image %}
    <div class="item">
      <img src="{{ file_url(item.entity.uri.value) }}" alt="">
    </div>
  {% endfor %}
</div>

```

The code above is not really depending or specific for Owl carousel.

The thing transforms it to a carousel is a JS call similar to

```
$(document).ready(function(){
  $(".partners").owlCarousel();
});

```

somewhere else in a JS file of your theme or a module. This is the "magic" that transforms the server-rendered HTML to something like your screenshot is showing (adding additional `<div>`s, classes and styles)

---
Tags: 8, theming, paragraphs
---


# Question
Title: Storage API stream wrappers Traffic Usage
In my Drupal 7 Project I have configured Storage API stream wrappers in order to save all public and private files over ftp server.

everything works well and files in public and private are copied into ftp server correctly.

Imagine that my base server is domain.com and my ftp server is ftp.com

As you know, public files will be shown with direct link to the source for example

```
http://ftpdomain.com/public-file.png

```

and private files are not shown with direct links for example

```
http://domain.com/system/storage/serve/private-file.rar

```

Now my question is: when a user try to download private-file.rar via above link, what happens really? is private file from ftp server being copied to the main server temp folder at first and then download starts? Or private-file.rar is downloaded directly from ftp server to the client machine despite the URL starts with "http://domain.com/.... "

It is very important for me because of shared server rules in file download limitations , I have to purchase one **PHP host** for running Drupal script and one **download host** for placing files folder in order to run a Drupal project commerce file shop.

I want to be sure, download traffic only relate to download server not PHP server.

Thanks a lot for your guidance.

# Answer
If you look into the Drupal core's routing config, you can find the controller responsible for delivering private files. It's abstracted through the `BinaryFileResponse` object, but you can see in its `sendContent` method how the data is prepared for delivery.

It uses PHP's `stream_copy_to_stream` function to copy from your input stream (your private path) to the `php://output` stream, the HTTP body delivered via PHP/web server.
> 1 votes

---
Tags: stream-wrappers
---