# Question
Title: using several fields from another node using entity reference -- how?
I'm trying to learn about basic drupal concepts while planning out my site. I'm trying to figure out the drupal way to accomplish things. Actually I'd also like language to describe what functionality I'm looking for and whether it can be done through the Drupal 8 GUI or requires some module.

I've created two content types BOOK and AUTHOR. Both have about 5 fields.

I want to have a third content type called BOOK REVIEW.

When you input data in the form for BOOK REVIEW, I am using an entity reference field which autocompletes in the form display. In the form display for BOOKREVIEW, I want to type in the name of the AUTHOR (Charles Dickens) and then drupal will offer me the choice I want from an AUTHOR node. AUTHORNAME is one field in the AUTHOR content type.

Here's what I don't understand.

When I am creating/editing a BOOKREVIEW, I want a way to display not only the AUTHORNAME field, but also pull data for 2 or 3 other fields in the same Charles Dickens node for AUTHOR (such as NATIONALITY or YEAR OF DEATH). So in the form display for BOOKREVIEW, I would have no reason to input YEAR OF DEATH or NATIONALITY. Yet I don't know how to put data from thee fields in the BOOKREVIEW display. I would just expect it to be called and available for the display as a result of having already input CHARLES DICKENS in the form display for BOOKREVIEW.

Initially I thought I need to establish a RELATIONSHIP between one BOOKREVIEW node and one AUTHOR mode. But relationships seems to have to do with VIEWS only, and I'm not really interested in making a view. (A view is a way of display more than more than one nodes of a content type, and I am only interested in producing a display for one node. Or am I wrong?

What would be the best way to accomplish this task of invoking additional fields from a single AUTHOR mode by simply creating a content reference for AUTHORNAME?

**EDIT:** My primary purpose is to produce a site with articles/blogposts, etc. I'd like multiple ways to sort nodes, plus having books and authors separate simplify the process for users of creating reviews. It's not a primary goal, but keeping these things separate make it easier to create alternate ways to browse reviews. –

# Answer
Once you have connected your Book node with the Author node via an entity reference field, you can display any subset of the Author node within the Book node without additional modules:

1. Create a custom display mode. (Structure \>\> Display modes \>\> View mode)
2. Enable that display mode for Author and configure the fields that you wish to display. (Structure \>\> Content Types \>\> Author \>\> Manage Display)
3. Configure the entity reference field in Book to display as Rendered Entity and set it to use the view mode created above. (Structure \>\> Content Types \>\> Book \>\> Manage Display) Format: Rendered Entity; Format Setting: mode created in step 1.
> 0 votes

---
Tags: 8, nodes
---


# Question
Title: Is there a good way to inspect objects whose type is derived from the EntityDrupalWrapper class?
I'm sure this question applies to other complex object types, but `EntityDrupalWrapper` is the one I'm currently working with. This is the type of object returned by `entity_metadata_wrapper()` (and probably others).

When using code like the following:

```
$order_wrapper = entity_metadata_wrapper('commerce_order', $order_object);
dpm($order_wrapper);

```

the output from Devel is none too helpful:

It doesn't show what you'd expect to see for a call to `dpm()` with, for example, a `stdClass` object.

A similar call to `dvm()` does print the object, but in a manner I'm not familiar with, and it's not very readable.

I've tried `debug()` and it produces a PHP user notice that looks something like this:

Incidentally the HTML output contained in that warning is the same output that `dvm()` prints to the screen.

How can I inspect these types of objects (preferably with Krumo), so I can see what properties are available? Or am I stuck using `dvm()`?

# Answer
Use dpm($wrapper-\>getPropertyInfo());

It's in the docs.
> 38 votes

# Answer
I had been playing with EntityDrupalWrapper objects. debug() usually returns the output that may have prepared by \__toString()

I iterated EntityDrupalWrapper object using foreach and it helped to list down the name of properties.

```
foreach($order_wrapper as $name => $obj){
  debug($name);
  debug(get_class($obj)); //EntityValueWrapper
}

```

Here `$obj` is an object of type `EntityValueWrapper`

$obj can be read by $obj-\>value() and can be write by $obj-\>set('value');

EDIT:

If you have created your wrapper without passing second param
i.e. entity\_metadata\_wrapper('commerce\_order');
then set and value methods will throw exception as they are not implemented.
> 4 votes

# Answer
I wound up writing my own little widget to unroll the wrapper:

```
function _wrapper_debug($w) {
  $values = array();
  foreach ($w->getPropertyInfo() as $key => $val) {
    $values[$key] = $w->$key->value();
  }
  return $values;
}

dpm(_wrapper_debug($some_object_wrapper));

```

Hope someone finds it useful.
> 4 votes

# Answer
The Inspect module provides a nice structural view of the data you want to debug.

> Get instructive and well formatted variable dumps, deep stack traces, and execution time profiles - to database log (Reports / Recent log messages), to file or to screen.
> 3 votes

# Answer
If you want to inspect the original object that is "powering" the wrapper, try:

```
dpm($wrapper->raw())

```

This works well for me.
> 3 votes

# Answer
There is a devel patch the enables Krumo to show all private and protected properties.

Here is the thread on drupal.org

I've found this patch very helpful.
> 2 votes

# Answer
Use the drupal cli

```
$ drupal debug:entity
// Displays current events

```
> 0 votes

---
Tags: entities, debugging
---


# Question
Title: Why multilevel dynamic local tasks doesn't work?
I want to have tabs, but since they need to be dynamic I am making use of local tasks. In the class extending `DeriverBase` I have written the following function:

```
public function getDerivativeDefinitions($base_plugin_definition) {
    $this->derivatives = array();
    foreach ($this->moduleFormatManager->getDefinitions() as $key => $definition) {
      $this->derivatives[$key]['title'] = $definition['title'];
      $this->derivatives[$key]['route_parameters'] = array('module_format' => $key);
      $this->derivatives[$key]['route_name'] = 'module.format_configure_' . $key;
      if($key == 'xyz') {
        $key = 'newkey';
      $this->derivatives[$key]['title'] = 'newkey';
      $this->derivatives[$key]['route_name'] = 'module.newkey';
      $this->derivatives[$key]['parent_id'] = "module.format_configure:xyz";
      }
    }
    foreach ($this->derivatives as &$entry) {
      $entry += $base_plugin_definition;
    }
    return $this->derivatives;
  }

```

In the above code, a tab for each key is being generated: my problem is in the if condition. In the if condition I am trying to generate a sub tab for a particular type of tab by declaring `parent_id`. But the code doesn't work for me.

What changes should I introduce in order to make it work? I used this link to learn about local tasks.

My `module.links.tasks.yml` file looks like this:

```
module.format_configure:
  title: 'Configuration'
  base_route: module.configure
  tab_root_id: module.configure
  deriver: 'path to deriver'

```

All the mentioned routes have been declared in `*.routing.yml` file.

# Answer
You said your file is called `module.links.tasks.yml`. The correct filename is `module.links.task.yml` (note links word is pluralized, but task is not).
> 1 votes

---
Tags: 8, routes
---


# Question
Title: Can't install modules from UI when site placed in subdirectory
I have Drupal 8 installed in a subfolder (`www.example.com/drupal`), and I have my root `.htaccess` configured to mask the subfolder (i.e. the URLs resolve to `www.example.com`; `/drupal` does not appear in the URLs).

Everything works great except when I try to install new modules I get a 403 error. I see in the URL for `authorize.php` that `/drupal` now appears in the URL. Where I would expect `www.example.com/core/authorize.php/`, I instead see `www.example.com/drupal/core/authorize.php/`. I imagine this is the reason for the 403?

What additional modifications do I have to make to `/drupal/.htaccess` in order to get access to the `/core` files required to install new modules?

Here's what's in my document root `.htaccess`:

```
RewriteEngine On
RewriteCond %{REQUEST_URI} !drupal/
RewriteRule (.*) /drupal/$1 [L]

```

And the only modification to `/drupal/.htaccess` is to uncomment the subdirectory per the instructions in the file:

```
# Modify the RewriteBase if you are using Drupal in a subdirectory or in a
# VirtualDocumentRoot and the rewrite rules are not working properly.
# For example if your site is at http://example.com/drupal uncomment and
# modify the following line:
RewriteBase /drupal

```

# Answer
> 0 votes
You have to uncomment this line.

```
  # Modify the RewriteBase if you are using Drupal in a subdirectory or in a
  # VirtualDocumentRoot and the rewrite rules are not working properly.
  # For example if your site is at http://example.com/drupal uncomment and
  # modify the following line:
  # RewriteBase /drupal

```

Another option is to update module using drush.

```
drush up

```

---
Tags: 8, installation, .htaccess
---


# Question
Title: Alter a view to show the first N results
I created a view via the view user interface. From a custom module, I want alter the view for display the n firsts results depending of some user parameters.

I don't find how I can do that with views alter hook functions. For example, via the pre execute view alter hook, I can get the query substructure. How can I configure this structure for not display all results by display only the first N results?

The "limit" value define the value in the current page with the current "level" of pager (10 results of the 27 results are displayed in pager 1, 10 results of the 27 results are displayed in pager 2 and 7 results of the 27 results are displayed in pager 3). The "limit" doesn't define the total number o, f the result query.

Thanks to Kevin answer, I tried this code.

```
function mycustommodule_views_query_alter(ViewExecutable $view, \Drupal\views\Plugin\views\query\QueryPluginBase $query){

    if($views->id() == "mycustomview"){
        $view->query->setLimit(7);
        $view->query->setOffset(5);
        $view->save();

        // I try also ..
        // $query->setLimit(7);
        // $query->setOffset(5);
    }
}

```

My view in the view page doesn't change and displays 10 results (number total of nodes). How can I set Limit and/or Offset and 'save' the change from the hook view query alter?

After Rémy's answer, I tried this code.

```
function mymodule_views_query_alter(\Drupal\views\ViewExecutable $view, \Drupal\views\Plugin\views\query\QueryPluginBase $query){

    if($views->id() == "mycustomview"){
        $query->setLimit(3);
        ksm("Hey ! I pass here !"); // log function
    }
}

```

in drupal/modules/custom/mymodule/mymodule.module file

OR

in in drupal/modules/custom/mymodule/mymodule.views\_execute.inc file

and I clear caches with "drush cr"

=\> My view page display my log ("Hey ! I pass here !"), BUT, my view always display ALL result :/ Its crazy ! x)

# Answer
You need to alter the pager, see ViewExecutable:initPager(), so right now only this code works (seems confusing ..):

```
function mycustommodule_views_query_alter(\Drupal\views\ViewExecutable $view, \Drupal\views\Plugin\views\query\QueryPluginBase $query){
    if($view->id() == 'mycustomview'){
        $view->setOffset(5);
        $view->getPager()->setItemsPerPage(7);
    }
}

```

> Is that code touched only the first time ? (After running drush cr)

If so - move the method in a file called **mycustommodule.views\_execution.inc**. It won't work on every request inside *mycustommodule.module* file. see here!

> **Also** make sure *Disable SQL rewriting* is not set in the view used !

For more information see the issue I addressed regarding this on d.o.
> 5 votes

# Answer
If I understand the question correctly, you might want to try using setLimit and setOffset on the $query object passed to hook\_views\_query\_alter():

https://api.drupal.org/api/drupal/core%21modules%21views%21src%21Plugin%21views%21query%21QueryPluginBase.php/function/QueryPluginBase%3A%3AsetLimit/8.2.x

https://api.drupal.org/api/drupal/core%21modules%21views%21src%21Plugin%21views%21query%21QueryPluginBase.php/function/QueryPluginBase%3A%3AsetOffset/8.2.x

Since it is dynamic per user, you might have caching considerations... I think this should be early enough in the process to change it to what you want.
> 0 votes

# Answer
You can try the **hook\_views\_pre\_execute**

```
function mycustommodule_views_pre_execute(\Drupal\views\ViewExecutable $view) {
  if ($view->id() == "mycustomview") {
    $query = $view->query;
    $query->setLimit(7);
    $query->setOffset(5);
  }
}

```

I think your problem is a **filter** not **limit** (If I understood correctly). If you want to add filter like 'WHERE' in sql follow this page : https://api.drupal.org/api/drupal/core!modules!views!views.api.php/function/hook\_views\_query\_alter/8.2.x
> 0 votes

# Answer
I was having a similar issue, here is what worked for me. Hope it helps someone.

```
function mymodule_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
      if ($view->storage->get('id') === 'viewid' && $view->current_display === 'displayid'){
          $query->setLimit(1);
  }
}

```
> 0 votes

---
Tags: 8, hooks, views
---


# Question
Title: Complex where condition with entity field query (D8)
Is there a method similar to the D7 dynamic query where method to allow us to use arbitrary snippets of SQL to restrict the result set?

Take the following MYSQL query as an example:

```
SELECT id, publish_date
FROM teaching_period
WHERE publish_date IS NULL OR UNIX_TIMESTAMP(STR_TO_DATE(CONCAT(publish_date, ' 23:59:59'), '%Y-%m-%d %H:%i:%s')) > UNIX_TIMESTAMP(CURRENT_TIMESTAMP)
ORDER BY created DESC
LIMIT 0, 1

```

How can I create the where statement in this query using the D8 entity query API? Is it even possible?

# Answer
> 2 votes
No, in general, it is not. Entity query is *not* an SQL-query replacement, it designed to also work with other storage backends, so you can not use 100% of the SQL features.

If you need that, you have to implement your own SQL query.

That said, I don't quite understand why your special SQL logic is even necessary, date fields can be queried natively, e.g. publish\_date \> :date should just work, as long as you provide the date in the correct format as and timezone input.

See How to do a date range entityQuery with a Date only field in Drupal 8?

---
Tags: 8, entities, database
---


# Question
Title: Can we delete the older version jquery libraries from jquery_update module?
The recent version of jquery\_update module has 1.10 version of jquery library. And it also has older versions in it. Can we delete these older version files from the module? Will there be any problem if i delete them from the module directly?

# Answer
You can delete them, as long as nothing is trying to use them, but they'll be restored when the module is updated.

They're only a few hundred kb between them, common sense might suggest to leave them where they are.
> 2 votes

---
Tags: javascript
---


# Question
Title: How to use the Elements module to make $form['element'] = array( '#type' => 'number' );
As Drupal 7, core field doesn't support HTML 5 form elements.

How can I use the Elements module from Form API to make the it works below?

```
$form['element'] = array(   '#type' => 'number' );

```

# Answer
Have a quick look at the code of the elements module.

The number field is defined like this:

```
  $types['numberfield'] = array(
    '#input' => TRUE,
    '#step' => 1,
    '#process' => array('ajax_process_form'),
    '#element_validate' => array('elements_validate_number'),
    '#theme' => 'numberfield',
    '#theme_wrappers' => array('form_element'),
  );

```

So you should use `'#type' => 'numberfield'` instead.
> 1 votes

---
Tags: 7, forms
---


# Question
Title: How to provide custom template declared inside my theme .theme file as variable inside page twig template
In my theme, I implemented HOOK\_theme to declare custom twig template. How can I provide/preprocess this template as variable ready to to output inside my page.twig.html template ?

# Answer
> 2 votes
Presume you have something like:

```
HOOK_theme($existing, $type, $theme, $path) {
  return [
    // mycustomtheme.html.twig
    'mycustomtheme' => [
      'variables' => [
        'var1' => NULL,
        'var2' => NULL,
        'var3' => NULL,
      ],
    ],
  ];
}

```

You can preprocess the `page.html.twig` theme and add your theme output as a variable:

```
function HOOK_preprocess_page(&$variables) {
  $var1 = 'foo';
  $var2 = 'bar';
  $var3 = 'baz';
  $variables['content']['customcontent'] = [
    '#theme' => 'mycustomtheme',
    '#var1' => $var1,
    '#var2' => $var2,
    '#var3' => $var3,
  ];
}

```

And then you should be able to print it on `page.html.twig`:

```
{{ content.customcontent }}

```

---
Tags: theming, 8
---


# Question
Title: 8 - Ajax form not rebuild once submitted
I have an issue with a custom form in Drupal 8, using Ajax.

Let me explain. I have two select fields, and when you choose an option in the first one, an Ajax request will get options for the second one. When you submit the form, it will redirect you to a specific page. All of this works well.

The issue is when you get redirect to a page, and you hit the previous page button of your browser. By default, you get the first option of the first field, and the first option of the second field, but in this specific case, you get the option you previously selected for the first field, but the second select doesn't get the good values, as the Ajax request does not get fired.

---

**Exemple :**

When you choose "Option A" in the first field, you get "Value A.1" and "Value A.2" in the second field, if you choose "Option B", you get "Value B.1", etc...

For exemple, if you submit the form with "Option C" and "Value C.3", you get redirected to a page, and if you go back to the previous page in your browser, you'll have "Option C" selected, but with the values of "Option A" in the second field ("Value A.1", "Value A.2", ...), and if you submit, you get this error

> An illegal choice has been detected. Please contact the site administrator.

---

I surely miss something with the rebuild of the form, but I can"t find any solutions.

Here's my code :

```
<?php

namespace Drupal\chdou_intuitive_search\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ReplaceCommand;

/**
 * Class DefaultForm.
 *
 * @package Drupal\chdou_intuitive_search\Form
 */
class DefaultForm extends FormBase {

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'default_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {

    $form['i_wish'] = [
      '#type' => 'select',
      '#title' => $this->t('Je souhaite'),
      '#options' => [
        'appointment' => $this->t('prendre rendez-vous'),
        'doctor' => $this->t('rechercher un médecin'),
        'help' => $this->t('une aide ou un soutien')
      ],
      '#default_value' => 'appointment',
      '#required' => true,
      '#multiple' => false,
      '#size' => false,
      '#ajax' => [
        'callback' => '::getOptions',
        'event' => 'change',
        'wrapper' => 'what',
      ]
    ];

    $parent = $form_state->getValue('i_wish');
    if (empty($parent)) {
      $parent = $form['i_wish']['#default_value'];
    }
    $form['what'] = [
      '#prefix' => '<div id="what">',
      '#suffix' => '</div>',
      '#type' => 'select',
      '#title' => $whatLabel,
      '#options' => $this->getOptionsBySelection($parent),
      '#default_value' => key($this->getOptionsBySelection($parent)),
      '#required' => true,
      '#multiple' => false,
      '#size' => false,
    ];

    $form['submit'] = [
      '#prefix' => '<div class="form-actions">',
      '#suffix' => '</div>',
      '#type' => 'submit',
      '#value' => $this->t('Search'),
      '#attributes' => [
        'class' => [
          'button',
        ],
      ],
    ];

    return $form;

  }

  /**
   * Ajax callback for the "Je souhaite" dropdown
   */
  public function getOptions(array &$form, FormStateInterface $form_state) {
    return $form['what'];
  }

  /**
   * Returns list of options that correspond to the "Je souhaite" selected option
   */
  public function getOptionsBySelection($parent) {
    switch ($parent) {
      case 'appointment':
        $terms = $this->getAppointmentOptions();
        break;
      case 'doctor':
        $terms = $this->getDoctorOptions();
        break;
      case 'help':
        $terms = array(
          '140' => 'Je suis patient',
          '141' => 'Je suis aidant',
          '142' => 'Pour un proche',
        );
        break;
      default:
        break;
    }
    return $terms;
  }

  /**
   * Returns list of care_sheet_consultation taxonomy tree
   */
  public function getAppointmentOptions() {
    // ...
  }

  /**
   * Returns list of :
   *   - care_sheet_consultation
   *   - care_sheet_hospitalization
   *   - care_sheet_medical_techno
   * taxonomy trees
   */
  public function getDoctorOptions() {
    // ...
  }

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

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {

    // CHOIX : Je souhaite prendre rendez-vous
    if ($form_state->getValue('i_wish') == 'appointment') {
      $form_state->setRedirect('entity.taxonomy_term.canonical', [
        'taxonomy_term' => $form_state->getValue('what')
      ]);
    }

    // CHOIX : Je souhaite rechercher un médecin
    else if ($form_state->getValue('i_wish') == 'doctor') {
      $form_state->setRedirect('entity.node.canonical', [
        'node' => '29', // i.e. page Annuaire
        'service' => $form_state->getValue('what')
      ]);
    }

    // CHOIX : Je souhaite une aide ou un soutien
    else if ($form_state->getValue('i_wish') == 'help') {
      $form_state->setRedirect('entity.node.canonical', [
        'node' => $form_state->getValue('what')
      ]);
    }

  }

}

```

# Answer
Thank's to @ivan-jaros's link, I managed to make it work (partially).

I added a wrapper to the form.

```
$form['#prefix'] = '<div id="intuitive-search-ajax-wrapper">';
$form['#suffix'] = '</div>';

```

and in my callback function, I called the entire form instead of just the second field

```
public function getOptions(array &$form, FormStateInterface $form_state) {
    return $form;
}

```

It works in every browser, **excepts Firefox**. It may be because of the browser-side caching system, but Firefox does not reload the page when hitting the back button, so the form keep the same values. That causes the "*illegal choice has been detected*" error.

**EDIT :** I managed to make it work simply by adding `'#validated' => true` to my dynamic field. See this thread for more information.
> 0 votes

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


title: CSV import to content type

text:
# Question
Title: CSV import to content type
While migrating from csv file to content type in Drupal 8 , fields like Geolocation and Address are of type field collections, so for mapping those fields am using migrate source csv and migrate plus modules in Drupal 8.

is there any other method to do without any mapping ?

# Answer
Use this module for migrating from csv.

https://www.drupal.org/project/migrate\_source\_csv
> 0 votes

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


# Question
Title: How to represent media as individual entities?
I need some architectural advice please.

I'm building a Drupal 8 site for the first time and I need to represent audio and video media on the site.

There are probably fields I can use but I'm looking for a solution which will allow each video or audio to be represented as individual entities on the site so I can list one audio/video entity in multiple locations on the site.

Can anyone advice on how best I should implement my media requirements?

# Answer
> 2 votes
There is a module called Media entity. Some more details about it, from its project page:

> Media entity provides a 'base' entity for media. This is a very basic entity which can reference to all kinds of media-objects (local files, YouTube videos, Tweets, Instagram photos, ...). Media entity provides a relation between Drupal and the media resource. You can reference to/use this entity within any other Drupal entity.
>
> This module attempts to provide the base storage component for the Drupal 8 media ecosystem.

I think that it will do what you want.

---
Tags: 8, entities, media
---


# Question
Title: How I update my custom module without uninstall and reinstall it?
I need to add a column in my custom field type. So I written code for adding column in field\_schema function and in functions that display the field. Now, I need to update the module without uninstall and reinstall it. There is a way?

# Answer
Yes, `hook_update_N()` exists for exactly that reason. For example:

```
function MYMODULE_update_7100(&$sandbox) {
  // Perform your update here
}

```

It's worth remembering update hooks should b found in your module's.install file.
> 1 votes

---
Tags: entities
---


# Question
Title: How can I set some checkboxes to selected upon the first loading of the form?
I have a form with checkboxes.

```
$form['my_checkboxes'] = [
    '#type' => 'checkboxes',
    '#options' => ['1' => 'one', '2' => 'two', '3' => 'three'],
];

```

And for example, I want to option '1' is selected upon form was loaded.

Could you clarify me, how can I set some checkboxes to selected upon the first loading of the form ?

Unfortunately, I couldn't find the solution in the examples module.

# Answer
> 2 votes
Use a `#default_value`:

```
$form['my_checkboxes'] = [
  '#type' => 'checkboxes',
  '#options' => ['1' => 'one', '2' => 'two', '3' => 'three'],
  '#default_value' => [1, 2],
];

```

---
Tags: 8, forms
---


# Question
Title: How to show another user the goals I completed?
I have a view that shows the goals (created using the Goals module) I've completed. For this I use the view that comes with the Goals module (and which only shows the Goals completed by the current user).

But I'd like that other users could see that view too whenever other users browse my account. So that another user can see which goals I completed (instead of showing the goals completed by that other user).

So I'm looking for help about:

* placing the view.
* making it visible to other users whenever they browse my profile.

# Answer
> 1 votes
Here is an export of a view, which is an improved version of the view that is included with the Goals module (disclosure: I'm its maintainer):

```
$view = new view();
$view->name = 'goals_completed_by_a_user';
$view->description = 'A block showing goals completed by a user.';
$view->tag = 'Goals';
$view->base_table = 'goals';
$view->human_name = 'Goals Completed by User';
$view->core = 7;
$view->api_version = '3.0';
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */

/* Display: Master */
$handler = $view->new_display('default', 'Master', 'default');
$handler->display->display_options['title'] = 'Your completed goals';
$handler->display->display_options['use_more_always'] = FALSE;
$handler->display->display_options['access']['type'] = 'none';
$handler->display->display_options['cache']['type'] = 'none';
$handler->display->display_options['query']['type'] = 'views_query';
$handler->display->display_options['exposed_form']['type'] = 'basic';
$handler->display->display_options['pager']['type'] = 'none';
$handler->display->display_options['style_plugin'] = 'grid';
$handler->display->display_options['row_plugin'] = 'fields';
/* Relationship: Goal: Goal - completed by users */
$handler->display->display_options['relationships']['goals_completed_goals']['id'] = 'goals_completed_goals';
$handler->display->display_options['relationships']['goals_completed_goals']['table'] = 'goals';
$handler->display->display_options['relationships']['goals_completed_goals']['field'] = 'goals_completed_goals';
/* Field: Goal: URL */
$handler->display->display_options['fields']['url']['id'] = 'url';
$handler->display->display_options['fields']['url']['table'] = 'views_entity_goal';
$handler->display->display_options['fields']['url']['field'] = 'url';
$handler->display->display_options['fields']['url']['exclude'] = TRUE;
$handler->display->display_options['fields']['url']['link_to_entity'] = 0;
/* Field: Goal: Goal Image */
$handler->display->display_options['fields']['goal_img']['id'] = 'goal_img';
$handler->display->display_options['fields']['goal_img']['table'] = 'field_data_goal_img';
$handler->display->display_options['fields']['goal_img']['field'] = 'goal_img';
$handler->display->display_options['fields']['goal_img']['label'] = '';
$handler->display->display_options['fields']['goal_img']['exclude'] = TRUE;
$handler->display->display_options['fields']['goal_img']['element_label_colon'] = FALSE;
$handler->display->display_options['fields']['goal_img']['click_sort_column'] = 'fid';
$handler->display->display_options['fields']['goal_img']['settings'] = array(
  'image_style' => 'goal_image',
  'image_link' => '',
);
/* Field: Goal: Title */
$handler->display->display_options['fields']['title']['id'] = 'title';
$handler->display->display_options['fields']['title']['table'] = 'goals';
$handler->display->display_options['fields']['title']['field'] = 'title';
$handler->display->display_options['fields']['title']['label'] = '';
$handler->display->display_options['fields']['title']['alter']['alter_text'] = TRUE;
$handler->display->display_options['fields']['title']['alter']['text'] = '[title][goal_img]<br/>';
$handler->display->display_options['fields']['title']['alter']['make_link'] = TRUE;
$handler->display->display_options['fields']['title']['alter']['path'] = '[url]';
$handler->display->display_options['fields']['title']['element_label_colon'] = FALSE;
/* Sort criterion: Goal - completed by users: Created */
$handler->display->display_options['sorts']['created']['id'] = 'created';
$handler->display->display_options['sorts']['created']['table'] = 'goals_completed_goals';
$handler->display->display_options['sorts']['created']['field'] = 'created';
$handler->display->display_options['sorts']['created']['relationship'] = 'goals_completed_goals';
/* Contextual filter: Goal - completed by users: User */
$handler->display->display_options['arguments']['uid']['id'] = 'uid';
$handler->display->display_options['arguments']['uid']['table'] = 'goals_completed_goals';
$handler->display->display_options['arguments']['uid']['field'] = 'uid';
$handler->display->display_options['arguments']['uid']['relationship'] = 'goals_completed_goals';
$handler->display->display_options['arguments']['uid']['default_action'] = 'default';
$handler->display->display_options['arguments']['uid']['default_argument_type'] = 'current_user';
$handler->display->display_options['arguments']['uid']['summary']['number_of_records'] = '0';
$handler->display->display_options['arguments']['uid']['summary']['format'] = 'default_summary';
$handler->display->display_options['arguments']['uid']['summary_options']['items_per_page'] = '25';

/* Display: My goals */
$handler = $view->new_display('block', 'My goals', 'block');
$handler->display->display_options['display_description'] = 'Goals completed by the current user';
$handler->display->display_options['defaults']['hide_admin_links'] = FALSE;

/* Display: User's Goals */
$handler = $view->new_display('block', 'User\'s Goals', 'block_1');
$handler->display->display_options['defaults']['title'] = FALSE;
$handler->display->display_options['title'] = 'Goals completed user';
$handler->display->display_options['display_description'] = 'Goals completed by a selected user';
$handler->display->display_options['defaults']['hide_admin_links'] = FALSE;
$handler->display->display_options['defaults']['style_plugin'] = FALSE;
$handler->display->display_options['style_plugin'] = 'table';
$handler->display->display_options['style_options']['columns'] = array(
  'goal_img' => 'goal_img',
  'title' => 'title',
);
$handler->display->display_options['style_options']['default'] = '-1';
$handler->display->display_options['style_options']['info'] = array(
  'goal_img' => array(
    'sortable' => 0,
    'default_sort_order' => 'asc',
    'align' => '',
    'separator' => '',
    'empty_column' => 0,
  ),
  'title' => array(
    'sortable' => 0,
    'default_sort_order' => 'asc',
    'align' => '',
    'separator' => '',
    'empty_column' => 0,
  ),
);
$handler->display->display_options['defaults']['style_options'] = FALSE;
$handler->display->display_options['defaults']['row_plugin'] = FALSE;
$handler->display->display_options['defaults']['row_options'] = FALSE;
$handler->display->display_options['defaults']['fields'] = FALSE;
/* Field: Goal: URL */
$handler->display->display_options['fields']['url']['id'] = 'url';
$handler->display->display_options['fields']['url']['table'] = 'views_entity_goal';
$handler->display->display_options['fields']['url']['field'] = 'url';
$handler->display->display_options['fields']['url']['exclude'] = TRUE;
$handler->display->display_options['fields']['url']['link_to_entity'] = 0;
/* Field: Goal: Goal Image */
$handler->display->display_options['fields']['goal_img']['id'] = 'goal_img';
$handler->display->display_options['fields']['goal_img']['table'] = 'field_data_goal_img';
$handler->display->display_options['fields']['goal_img']['field'] = 'goal_img';
$handler->display->display_options['fields']['goal_img']['label'] = '';
$handler->display->display_options['fields']['goal_img']['exclude'] = TRUE;
$handler->display->display_options['fields']['goal_img']['element_label_colon'] = FALSE;
$handler->display->display_options['fields']['goal_img']['click_sort_column'] = 'fid';
$handler->display->display_options['fields']['goal_img']['settings'] = array(
  'image_style' => 'goal_image',
  'image_link' => '',
);
/* Field: Goal: Title */
$handler->display->display_options['fields']['title']['id'] = 'title';
$handler->display->display_options['fields']['title']['table'] = 'goals';
$handler->display->display_options['fields']['title']['field'] = 'title';
$handler->display->display_options['fields']['title']['label'] = '';
$handler->display->display_options['fields']['title']['alter']['alter_text'] = TRUE;
$handler->display->display_options['fields']['title']['alter']['text'] = '[title][goal_img]<br/>';
$handler->display->display_options['fields']['title']['alter']['make_link'] = TRUE;
$handler->display->display_options['fields']['title']['alter']['path'] = '[url]';
$handler->display->display_options['fields']['title']['element_label_colon'] = FALSE;
$handler->display->display_options['defaults']['arguments'] = FALSE;
/* Contextual filter: Goal - completed by users: User */
$handler->display->display_options['arguments']['uid']['id'] = 'uid';
$handler->display->display_options['arguments']['uid']['table'] = 'goals_completed_goals';
$handler->display->display_options['arguments']['uid']['field'] = 'uid';
$handler->display->display_options['arguments']['uid']['relationship'] = 'goals_completed_goals';
$handler->display->display_options['arguments']['uid']['default_action'] = 'default';
$handler->display->display_options['arguments']['uid']['default_argument_type'] = 'raw';
$handler->display->display_options['arguments']['uid']['default_argument_options']['index'] = '1';
$handler->display->display_options['arguments']['uid']['summary']['number_of_records'] = '0';
$handler->display->display_options['arguments']['uid']['summary']['format'] = 'default_summary';
$handler->display->display_options['arguments']['uid']['summary_options']['items_per_page'] = '25';

```

In this view I've added an extra block named "User's Goals". This extra block has a contextual filter which I configured like so:

* When the filter value is not available: Provide a default value with Type = "Provide raw value from URL" and Path component = "2" (this is what differs from the Views block delivered with the Goals module).
* In the block settings I've adapted the block visibility to only show this block on pages with a path that matches `user/*` ( i.e. when browsing a user's account, as in your question). And of course I've then enabled this extra block also to display it in an appropriate theme region.

**Note**: I've also extended the list of fields shown in the block, by also adding the Goal URL (excluded from display) and Goal title, though that is not really relevant to answer the question here.

# Answer
> 0 votes
1. Create a block display for your view.
2. Place the block on your user page in whatever region you want.
3. Ensure it is accessible to all authenticated users.

---
Tags: views, 7
---


# Question
Title: The pager on a form doesn't update upon first submit of the form
I have a form with filter checkboxes, submit button, results in tableselect and pager.

When I set some checkboxes and press the submit button, a query should be reexecuted, data should be placed into the tableselect and pager should be updated, because new data size can be different with old one.

When I do it the first time, query is executed successfully, tableselect also is updated without problems. But the pager doesn't want to be updated. And to update the pager I have to press the submit button second time. But it occurs only I pressed the submit button after the page with the form has been loaded.

Could you clarify me, how can I update the pager after first submission of the form ?

Here is a fragment of my code with the tableselect and the pager.

```
$q = \Drupal::entityQuery('node');
        $q = $q->condition('type', 'my_node_type')
            ->condition('status', 1);

        $pager_params = [];
        if ($event_types != []){
            $q->condition('field_art_der_veranstaltung', $event_types, 'IN');
        }

        $events = $q->sort('created', 'DESC')->pager(10)->execute();

        $nodes = Node::loadMultiple($events);

        $rows = [];

        foreach($nodes as $node){
            $rows[$node->id()] = [
                'nid' => $node->id(),
                'title' => $node->getTitle(),
            ];
        };

        $form['nodes_container']['nodes'] = [
            '#type' => 'tableselect',
            '#title' => $this->t('Events'),
            '#options' => $rows,
            '#header' => $header,
            '#empty' => $this->t('No events found'),
        ];

        $form['nodes_container']['pager'] = [
            '#type' => 'pager',
        ];

```

# Answer
Seemingly, I have fould the solution. Namely, to avoid it, I set the Element property for the pager explicitely.

Here are fragments of code.

```
$nodes = $q->sort('created', 'DESC')->pager(10, 0)->execute();

/// code here

$form['nodes_container']['pager'] = [
  '#type' => 'pager',
  '#element' => 0,
  '#parameters' => $pager_params,
];

```

Unfortunately, I didn't have a time to debug and find out why it didn't worked before but it works now. Newertheless, it works.
> 1 votes

---
Tags: 8, forms
---


# Question
Title: Need a solution to enter more then 100 PDF (or other) documents to one node
My client wants to be able to enter over 100 PDF and other documents to be downloaded from a single node. There will be several nodes like this each with their own linked files. Most of these are going to be less then 50, but there is a use case for over 100.

Right now they are using a field collection, as the nodes need to be restricted to area, have English and French description fields, and be able to be deactive.

The display of the nodes is ok, its the editing of the node. They are currently using field collections to gather the meta and file information. Then you hit a button to add another item and AJAX fires. It saves the node revision data for the file uploads and creates the next entry entity. Once you get over 70 or so, IE pushes the returned JSON info out as a file for download.

This has to work in IE, as there are other systems the client uses that will only work in IE, and this can not be changed.

I have considered the media browser, but there are limits to that the client does not want.

# Answer
> 0 votes
Without having all of the context here, my initial recommendation would be to consider integrating with a Digital Asset Manager (DAM), where your client can manage their documents much more efficiently, and select/attach which documents are part of individual nodes/entities.

In addition, most DAM solutions will serve your assets for you, so you are able to preserve disk space on the web application machine, while ensuring images are available and served up quickly via the DAM's CDN.

---
Tags: media, files
---


# Question
Title: How to pass an argument to be used in the view called by rules
**Context**: drupal 7, views, Rules, Views\_rules

**Goal**: to send an email to all users that have the same taxonomy-term as the newly posted node

**Possible solutions** known to me:

(1) A Rule calls the view with mailadresses and terms of each user. I would need to evaluate a condition within the view loop, which is possible, using a component of type rule or ruleset that will be executed for each item in the loop. This will be inefficient (give a lot of “skip this”).

(2) Or I could make a view for each term, as proposed in the comments of How to send out email based on matching taxonomy terms in user profiles? However, I would prefer to give my users more flexibility then just a few options.

**Question**: How could I pass the taxonomy-term to be used in the filter-criteria in the view? The view would then only return the records where actually something has to be done (i.e. send a mail to). Is there a way to send an argument when calling the view loop?

# Answer
I found **2 working prototypes.** Each require a taxonomy-list "field of interest" in both user and node.

Users can select multiple items, according to their fields of interest. When registering a new post, the posting user can indicate in which field of interest (one) this post is matching.

**ONE**

using 5 views (one for each term) to select the email adresses of users interested in this "field of interest". In the action I use "switch case" (from conditional\_rules) to select the view corresponding to taxonomy-term of the new node

**TWO**

fetch entity (user) by taxonomy term(field of interest)

loop thru the list of users

**THREE**

Finally I chose to make 5 views and 5 reaction rules, each rule having as condition a particular value of the taxonomie term in the new node en using the relevant view to select the users. No switch case needed.
> 0 votes

---
Tags: views, rules
---


# Question
Title: How to register Post Submit handler for form?
I have a form which I want to modify some of it's data after submission.

I'm using drupal 8.3 and I tried to used `hook_form_alter` and registered my functions to `$form['#submit'][]` and `$form['actions']['submit']['#submit'][]` but none of them working after form submission.

Any help? Thanks.

# Answer
> 0 votes
I added the following snippet in `hook_form_alter`:

```
array_unshift($form['#submit'], 'callback');
foreach ($form['actions'] as $action => $values) {
    if (isset($form['actions'][$action]['#submit']) && is_array($form['actions'][$action]['#submit'])) {
        if (!in_array('callback',$form['actions'][$action]['#submit'])) {
            array_unshift($form['actions'][$action]['#submit'], 'callback');
        }
    }
}

```

This registers to all actions.

# Answer
> 0 votes
you did n't mention you are tring that custom submit handler to core forms or your custom form....

If it is core form use this hook
hook\_form\_FORM\_ID\_alter and replace form id for your form and try to print the form in the hook ....... Echo "pre"; Print\_r($form) ; By printing you can know the structure of the submit button array format......and add ur custom submit handler in the same way and print your function whether it is added or not

If its custom form then add the same in the build form structure submit button code

---
Tags: 8, forms, hooks
---


# Question
Title: How to show titles as plain text on rendered entity reference
By default the titles are showed as links to there node if you choose to display format rendred entity (full).

I want the titles as plain text and not links

# Answer
> 1 votes
If you have display suite. You will need to do this no in the rendered part, you have to do this in the view mode of the content type that you are rendering for instance. I have installed display suite and that helps me to have more control over the layout

* profile product --\> rendering entity from news product displayed as teaser
* news product --\> In news product in the teaser view mode or full mode in your case, in manage display choose the title and select no link.

You need to have applyed a column layout in display suite to see it.

# Answer
> 0 votes
You might try looking in the template of whatever node type you are rendering by entity reference. So if your entity reference points to a content type of "type1", edit the tpl.php file that themes the "type1" content type (this will be different based on whatever version of Drupal you are using). My guess is, that template is probably where the title is being displayed as a link. I usually render my entities via more complex php in the template and using node\_load(), though.

# Answer
> 0 votes
you can create template for your particular content type node--your\_content\_type\_name.tpl.php

1) In this template file you will receive variables for your particular node content like for your title $title

```
 * Available variables:
 * - $title: the (sanitized) title of the node.

    then you can use strip_tags() function for removing link and print this variable where you want.

```

2) you can create view for particular content type listing and where you can easily change you title link to plain text when you all fields for listing.

# Answer
> 0 votes
Hi create new view for that particular content type,in that view edit content title then you will find **Link this field to the original piece of content** un check that check box,if you need theme that template file.

# Answer
> 0 votes
Just an FYI for Drupal 8 and the comments above,

When an entity relation field displays options via a view the view fields are not used, instead it is the entity label https://www.drupal.org/node/2174633 this is still being worked on, a fix is slated for 8.5 so in this case the only way is to disable the link is with the twig files.

---
Tags: entities
---


title: Block caching issue on twig

text:
# Question
Title: Block caching issue on twig
I've created a new custom module and I used `Facebook SDK` to retrieve the latest post from a page. Here is my .module file:

```
function social_theme($existing, $type, $theme, $path){
  return array(
    'block__feed_feed' => array(
    'render element' => 'elements',
    'template' => 'block--instagram-feed',
    'base hook' => 'block'
  )
}
function social_preprocess_block(&$variables){
 if ($variables['elements']['#configuration']['id'] === 'facebook-feed'){
   $fb = new \Facebook\Facebook([
     'app_id' => {$app_id},
     'app_secret' => {$app_secret},
     'default_graph_version' => 'v2.10',
     'default_access_token' => {$app_id}.'|'.{$app_secret},
   ]);

   $request = $fb->request('GET', '/'.{$page_id}.'/posts?fields=created_time,reactions,message,comments{comment_count,like_count},likes&limit=4');
   try {
     $response = $fb->getClient()->sendRequest($request);
   } catch(Facebook\Exceptions\FacebookResponseException $e) {
     echo 'Graph returned an error: ' . $e->getMessage();
     exit;
   } catch(Facebook\Exceptions\FacebookSDKException $e) {
     echo 'Facebook SDK returned an error: ' . $e->getMessage();
     exit;
   }
   $posts = $response->getDecodedBody();
   $facebookposts = [];
   for($c=0 ;$c<$posts_no ;$c++){
     if(isset($posts['data'][$c]['reactions'])){
       $likes_count = count($posts['data'][$c]['reactions']['data']);
     }
     else{
       $likes_count = 0;
     }
     if(isset($posts['data'][$c]['comments'])){
       $comments_count = count($posts['data'][$c]['comments']['data']);
     }
     else{
       $comments_count = 0;
     }
     array_push($facebookposts,['post_text'=>$posts['data'][$c]['message'],'likes_count'=>$likes_count,'comments_count'=>$comments_count]);
   }
   $variables['elements']['#cache']['max-age'] = 0;
   $variables['fbposts'] = $facebookposts;
   $variables['likes_comments'] = $likes_comments;
 }
}

```

and my block plugin code:

```
public function build() {
  \Drupal::service('page_cache_kill_switch')->trigger();
  return array(
    '#markup' => ' ',
    '#cache' => ['max-age' => 0,],
  );
}

```

and this is my block template file:

```
<ul>
{% for post in fbposts %}
 <li>
  <div class="facebook">{{post.post_text}}</div>
    <div class="likes-comments">
     <span id="comments">{{post.comments_count}}</span>
     <span id="likes">{{post.likes_count}}</span>
    </div>
  </li>
 {% endfor %}
</ul>

```

Now my problem is that the code is working perfectly, but when a new post is added it will not change on the website unless I clear the cache!!! I tried to give the block `'#cache' => ['max-age' => 0,]` but it didn't work, I tried `\Drupal::service('page_cache_kill_switch')->trigger();` on the `hook_preprocess_block` but id didn't work too.

What shall I do?

# Answer
You have to render the content `build()` returns:

*block.html.twig:*

```
...

{{ content }}

```

Even if it's only an empty markup string. Otherwise the cache max-age can't bubble up.

A better approach would be to return from `build()` a custom template, which you use for the html markup instead of the block template. See https://www.drupal.org/docs/8/theming/twig/create-custom-twig-templates-from-custom-module

Then you don't need a preprocess hook and caching works with the default block template.
> 2 votes

---
Tags: theming, 8, blocks, caching
---


# Question
Title: Shopping cart form (Commerce Order) add node title
I'm editing the view Shopping cart form (Commerce Order) to add the node's title to the form.

I did the following:

1. Add relationship: Commerce Line item: Product
2. Add relationship: Commerce product: Node referencing products from field\_product
3. Add field: Field: Title and set Relationship to "Node referencing products from field\_product"
4. Added the nodes Title field.

Which gives me the nodes' title, but then I also get every node associated with that product.

My commerce setup is the following:

1. I have a single product called "Voting on a Dog"
2. I created a new content type and referenced the product "Voting for a Dog".
3. I created 12 pieces of content that have the dogs pics, bio etc.

When I go to checkout it shows all the content I created vs just the one I'm checking out with (the node I added to the cart). I removed all the relationships and tried the hook function.

I dumped all the variables from this hook to see if the title was already there since the nid is listed.. but can't find it.

```
function custom_commerce_form_views_form_commerce_cart_form_default_alter(&$form,
&$form_state) {
  dsm($form,'Form');
  dsm($form_state,'Form State');
  }

```

In short, I want to add the nodes title to the Shopping cart view. Below is the view before I start adding relationships.

This is the view after I add the relationships

I just want to add the node's title to the first view without the rest of the nodes showing up.

# Answer
I know this is probably not the correct way, but after trying a views handler, I ran across this and it does work.

```
function custom_commerce_commerce_line_item_type_info_alter(&$line_item_types) {
$line_item_types['product']['callbacks'] = array('title' => '_custom_commerce_commerce_product_line_item_title');

//dsm($line_item_types,'info_alter');
 }

/**
* Returns an appropriate title for this line item for this site
*/
function _custom_commerce_commerce_product_line_item_title($line_item) {
$title_id = $line_item->data['context']['entity']['entity_id'];
$node2 = node_load($title_id);
$line_item=$node2->title;
return $line_item;
}

```
> 0 votes

# Answer
This may not be possible without custom code. The problem here is that the Views relationship you're using is what we call a reverse relationship - it joins the product to nodes that reference *it*, not vice versa like other relationships with join out to referenced entities. When you join out like that, you can easily add a filter based on the delta value of the reference field to limit the number of rows you get, but for the reverse relationship there is no such option.

What you most likely would need is a custom Views handler that knows how to join based on the display context data in a product line item's data array. No such thing exists as far as I know, and it's likely a non-trivial task to make work well.
> 1 votes

---
Tags: commerce
---


title: Remove Workflow from Features

text:
# Question
Title: Remove Workflow from Features
I'm trying to remove a Workflow instance from a Feature. But every time I uncheck the workflow and recreate the feature, the workflow gets deleted.

Now I know that with Views, Panels and other entities, all you have to do is to edit it, and it will be shown as overwritten (meaning it is using the database instead of code from the feature), and you can then safely remove it from the feature.

If I edit and save the workflow, it gives me a Revert link in the workflow menu. Yet if I then remove it from the feature, the workflow still gets deleted.

I've tried exporting the workflow and re-import it after removing, but then is just added with a new id (WID), which opens another can of worms on my site.

When I edit and save the workflow, I see in the workflow table in the db that the exportable status change from 2 to 3. I don't know what all the allowable statuses are. But this might be something to look into.

# Answer
It looks like you've tried alot of possible solutions with mixed success.

A method I'm not certain you've tried is to apply a patch to Features 2.x for Drupal7 that Provides a way to Import Views/true exportables back to the database.

This patch creates a new tab in the Features Admin area called `Import` if you select the items in the selected Feature to import back to the database, it will then attempt to import the exportable back to the database. Unfortunately as some users note in the thread -- you may not receive a confirmation message that it was successful or not. Recent versions of this patch may have addressed this lack of a status message -- I used this module months ago to move about a dozen features out of Features and back into plain/simple database configuration.

There is also discussion in the thread about Drush Ctools Export Bonus. But I found this module difficult to use and produced an error with (i think) field\_group stuff at the time.
> 0 votes

# Answer
It seems to me that Workflow does not work with id's (WID, SID...) but on the machine name when using Features.

After removing Workflow from Features (Which delete the Workflow), I then empty out the db tables for workflow\_states and workflow transitions. And then:

ALTER TABLE tablename AUTO\_INCREMENT = 1

on workflows, workflow\_states and workflow\_transitions tables.

Then I imported the original exported code and all is well.

Just note, I only have one Workflow.
> 0 votes

---
Tags: 7, features, workflows
---


# Question
Title: Custom variable in custom block template
I'm trying to create a block that will pass a variable to its template. For now just some text but it will be an array later.

The default block variables such as label are working but I'm unable to get the value to show up in template.

Any ideas ?

*FrontAppsBlock.php*

```
namespace Drupal\custom_blocks\Plugin\Block;

use Drupal\Core\Block\BlockBase;
use Drupal\Core\Block\BlockPluginInterface;
/**
 * @Block(
 *   id = "front_apps_block",
 *   admin_label = @Translation("Front Apps Block"),
 * )
 */
class FrontAppsBlock extends BlockBase implements BlockPluginInterface {

  public function build() {
    return array(
      '#theme' => 'front_apps_block',
      '#app' => 'test value',
    );
  }

}

```

*custom\_blocks.module*

```
function custom_blocks_theme($existing, $type, $theme, $path) {
  return [
    'front_apps_block' => [
      'variables' => [
        'app' => null
      ]
    ]
  ];
}

```

*block--front-apps-block.html.twig*

```
<p>test: {{ app }}</p>
<p>label: {{ label }}</p>

```

# Answer
After long hours of searching and trying I finally found a solution. Not really sure why but it seems a naming convention has to be respected.

I changed the name of #theme and templates to **start with module name**, here the name is **custom\_blocks**.

*src/Plugin/Block/FrontAppsBlock.php*

```
/**
 * @Block(
 *   id = "front_apps_block",
 *   admin_label = @Translation("Front Apps Block"),
 * )
 */
class FrontAppsBlock extends BlockBase implements BlockPluginInterface {

  public function build() {
    return [
      '#theme' => 'custom_blocks__front_apps',
      '#app' => 'test value',
    ];
  }

}

```

*custom\_blocks.module*

```
function custom_blocks_theme($existing, $type, $theme, $path) {
  return [
    'custom_blocks__front_apps' => [
      'variables' => [
        'app' => null
      ],
    ]
  ];
}

```

*templates/custom-blocks--front-apps.html.twig*

```
<p>Hello: {{ app }}</p>
<p>Base Label: {{ label }}</p>

```
> 6 votes

---
Tags: 8
---


# Question
Title: How to make two date fields related to each other?
H have a content type with a start date and an end date. How can make the

`end date defaut value` adjusting depending on what is entered on the

`start date choosen value`, ensuring that

`end_date always > start_date`?

# Answer
> 1 votes
You can use Date module to create multi date field, Check this article for more information

---
Tags: 7, datetime
---


# Question
Title: Is there a better way to install drush on Bluehost?
I registered Bluehost, because they are recommended by drupal and because I wanted shell access for drush. I tried to install drush, but got some problems. Bluehostforum.com doesn't seem to be online anymore, that's why I'm asking here.

First I had to contact the support to enable the shell access and they did it. Composer was already installed. Then I tried

```
composer require drush/drush

```

and got this error message:

```
[Composer\Downloader\TransportException]
The "https://packagist.org/packages.json" file could not be downloaded: allow_url_fopen must be enabled in php.ini (https:// wrapper is disabled in the server configuration by allow_url_fopen=0 failed to open stream: no suitable wrapper could be found)

```

The used php.ini was somewhere in /opt/cpanel/... and read only. I set PHPRC to use the php.ini in my home directory:

```
php -i | grep php.ini
export PHPRC=/home/mydir/php.ini

```

Now there were extensions missing ('undefined function ...') which I added in php.ini:

```
allow_url_fopen = On
extension = phar.so
extension = json.so
extension = tokenizer.so
extension = ctype.so
extension = iconv.so
extension = simplexml.so

```

Finally drush was working. Is there a better way to do this? I.e. to add all the extensions in one step?

Thank you very much!

# Answer
I found a much simpler and working solution with composer at this links:

https://www.drupal.org/node/2471553

https://github.com/drupal-composer/drupal-project

There was an older composer already installed and read only, so I downloaded a newer one and created an alias in .bashrc:

```
# curl -sS https://getcomposer.org/installer | php
# mv composer.phar ~/bin/composer.phar
# alias composer="php ~/bin/composer.phar"
# composer -V
# composer diagnose
# composer create-project drupal-composer/drupal-project:8.x-dev some-dir --stability dev --no-interaction

```
> 2 votes

# Answer
You can install drush via Homebrew

When you you have `Homebrew` installed you shall prepare for drush by running

`brew install git` and `brew update` After that you can just type

> brew tap homebrew/dupes
>
> brew tap homebrew/versions
>
> brew tap homebrew/php
>
> brew install drush
> 1 votes

---
Tags: drush
---


# Question
Title: How do I use a custom theme in a module?
As I know Drupal 8 removed `theme()`, which is still present in Drupal 7. There is function `hook_theme()` to call and render the theme in a module.

Can anyone help with some of the examples? How do I use a custom theme in my custom module?

# Answer
> 0 votes
It is very easy. You just need use `'#theme'` element in your render array.

For example:

**Drupal 7** has both way:

```
// Render array.
$build['cars_list'] = array(
  '#title' => t('Cars List'),
  '#theme' => 'item_list',
  '#items' => array('Mercedes', 'BMB'),
);
// Ready HTML.
$build['cars_list'] = theme('item_list', array('items' => array('Mercedes', 'BMB')));

```

**Drupal 8** has only one way:

```
// Use render array.
$build['cars_list'] = [
  '#title' => t('Cars List'),
  '#theme' => 'item_list',
  '#items' => ['Mercedes', 'BMB'],
];

```

Actuality you may create a custom theme via hook\_theme() and use it.

---
Tags: theming
---


title: Join variables in twig

text:
# Question
Title: Join variables in twig
I want to join two variables in twig in the *user.html.twig*

```
{{ content.field_firstname }} {{ content.field_lastname }}

```

How can i output them on the same line and add a space between them using twig ?

Everytime i try, they show on two different lines ? and i don't want to use css just for this.

Is there any better way to do this ? Many thanks

# Answer
> 5 votes
{% set full\_name = \[content.field\_firstname ~ ' ' ~ content.field\_lastname\] %}

**Note: We use ~ in twig to concatenate two or more strings instead of "+"**

# Answer
> 2 votes
You might have to dig a little deeper depending on the field type. If you `{{ kint(content) }}` in the template, you should be able to dig down to the actual value.

You might be looking for one of the following:

`{% set full_name = content.field_firstname.value ~ ' ' ~ content.field_lastname.value %}`

`{% set full_name = content.field_firstname.0['#markup'] ~ ' ' ~ content.field_lastname.0['#markup'] %}`

Or something similar.

Without seeing your code/kint output, it's hard to say. But that should get you going in the right direction.

---
Tags: theming
---


# Question
Title: How to show new nodes in a Group node view for users who are not a Group member?
In my Drupal 8,

1. Defined New User Role: Manager
2. Added one user into the role.

I have created a group "Group-x" with corresponding group type "Group-Type-x".

I have updated the permission(view, edit, create) in group type "Advanced outsider permissions" under role Manager.

I can able to create node in group. After creation the node is not listed in the group nodes

While checking it, the user is not a member of the group. If I add the user as a member it works fine.

Since I have some thousands of users, every time I can't add it in the group. Can anyone help me out?

Is there is any possibility to add members dynamically while creating node in the group?

*As you mentioned configured the outsider permission too.*

# Answer
> 0 votes
> ... After creation the node is not listed in the group nodes ... While checking it, the user is not a member of the group. If I add the user as a member it works fine.

I'm reading the above like "***For users who are not a member of the group, I want the nodes to be listed in the group nodes also***". To implement this:

* you need to correctly configure the permissions for what in the Group module is called "**Outsider**".
* you should NOT have to "*add members dynamically while creating node in the group*", as in your question (that's not how the Group module is supposed to work or be used).

And to configure the permissions for *Outsider*, you can use either of those techniques (using `Group-Type-x` to indicate the type of group):

* Grant permissions to group role at `/admin/group/types/manage/Group-Type-x/permissions`, so that a user who is not member of a group, receives the *Outsider* permissions for that group.
* If you need to distinguish between outsiders based on what roles they have in the global scope, then (and only then) you should use the "*Advanced outsider permissions*" page, located at `/admin/group/types/manage/Group-Type-x/permissions/outsider`. There you'll find all roles as defined in `/admin/people/permissions` (= the global scope).

With the above in mind, and looking at your question details, it seems to me that there are 2 possible solutions (depending on how you want it to work):

* ***If*** all outsiders should have similar access ***Then*** Tune the Group permissions at `/admin/group/types/manage/Group-Type-x/permissions`.
* ***If*** outsiders of selected global roles should have specific access ***Then*** Tune the Group permissions at `/admin/group/types/manage/Group-Type-x/permissions/outsider`. Note that the image shown in your question (about "*Advanced outsider permissions*") does not show anything that you already gave some permissions to role "Manager" (there is not even 1 checkmark below role "Manager").

BTW, about your "*If I add the user as a member it works fine.*": that seems to confirm that you correctly configured your permissions for members of the group. But by "adding a user as a member", such user is no longer considered an "Outsider". So you really need to fix your permissions for "Outsider".

PS: If for Anonymous users you want similar access permissions as for "Outsider", then you also need to configure those permissions via `/admin/group/types/manage/Group-Type-x/permissions`.

---
Tags: views, users, group
---


# Question
Title: How to get count on how many times a term is used on a node
I'm about to create a Tag cloud module that shall have a block showing a list of all terms. The most used terms shall be in big text; the terms that not used often shall be in small text, as in the following screenshot.

I want to have a `$count` variable that holds the count of how many times each term is used.

I think that I can do so:

```
$database = \Drupal::database();
$terms_count = $database
->query('SELECT COUNT(tid) FROM {taxonomy_index}')
->execute();

foreach($terms_count as $term_count) {
  print $term_count;
}

```

But it doesn't show anything.

# Answer
> 3 votes
Here's the query you're going for.

```
SELECT count(*) AS count, tid FROM taxonomy_index GROUP BY tid ORDER BY count DESC LIMIT 100;

```

You'll need to use AddExpression to get the count in there.

```
$query = $this->database->select('taxonomy_index', 'ti');
$query->addField('ti', 'tid', 'tid');

$query->addExpression("count(*)", 'count');
$query->groupBy('ti.tid');
$query->orderBy('count', 'DESC');
$query->range(0, 50);

$data = $raw_data = $query->execute()->fetchAll();

```

Here's how you might convert the data to a render array:

```
$term_storage = \Drupal::entityTypeManager()->getStorage('taxonomy_term');

$build = [];
foreach ($data as $count_group) {
  $term = $term_storage->load($count_group->tid);
  $label = $term->label();
  $link = $term->toLink();
  $link->setText($this->t($label . ' (' . $count_group->count . ')'));
  $build[] = $link->toRenderable();
}

return $build;

```

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


# Question
Title: How to create a view displaying fields only from block it was created in (Custom Blocks Types + Paragraphs)
So I'm trying to create a view on a slideshow content type. I want to create multiple slideshows. However, whenever I create a slideshow, I want to run a slideshow that only displays the slides from the paragraphs I created in that specific node.

**NOTE: I don't want to add filters that only show from that specific node ID. I want something that works exactly how field collection views worked in Drupal 7.**

Anyone know of any solutions?

\[**Update**\]

So while I started to go into this, I decided to change route of what I wanted to do. Learning more about how Drupal 8 works, I decided to change from making a slideshow content type to creating a new block type for slideshows. Inside the new block type I am using paragraphs for the slide information.

What I want to do is create a display view for the slides in each block type created (slideshow).

In my views settings I created a context filter by Paragraph ID. It's almost where I want it to be however, my view is only displaying the first item of the paragraph (the first slide fields). Its not until I put, (display all fields inline) does it show my slides. However, this doesn't help me with using flexslider or slideshow. I need them to be separate to have the slideshow work properly.

When I go to my fields tab and I look at my Slides (Paragraph). Under "Multiple Field Settings" it has the checkbock "Display all values in the same row".

I obviously want this unchecked because I need them to be in different rows for the slideshow to cycle though. If I leave it unchecked it only shows the first item in the paragraph.

Lastly, under the checkbox it says "If not checked, each value in this field will create a new row. If using group by, please make sure to group by "Entity ID" for this setting to have any effect."

However, it's not doing that, it just shows the first item and that's it. I'm not using grouped by so the last part shouldn't matter...at least I think it shouldn't.

"Help me, I'm poor"

# Answer
> 0 votes
Apparently I misunderstood. You are building a distribution with one slideshow block that comes pre-positioned in the distribution. Depending on the page you are looking at, that slideshow should display other slides.

Make sure that on your slideshow container entity you have an entity reference field to a node, allowing people to choose on which node page the slideshow should appear.

Then in the view, create a views block. You will need a relationship from the paragraph to the container entity. Then you need a second relationship from the container entity to the node that is referenced via the 'place on this page' field. Then add a contextual filter to see if the id of the 'place on this page node' equals that of the currently viewed node (use the drop down to select the right relationship).

# Answer
> 1 votes
To start, I cannot think of any benefits for creating a block type to act as a container element for slideshows. Especially since you will be using views to create the slideshow. If you like, please write in a comment why you felt it was a good idea. IMO content types make more sense.

The main cause of your problem is probably a misunderstanding of what is happening. A paragraph field on a drupal entity (block, node, whatever) is a one to many relationship. Every paragraph you add to the field will be a separate entity with its own id. If you have a contextual filter on the paragraph id, it does make sense that Drupal only loads one slide. You instruct it to load one id. (In fact I am surprised that you somehow managed to show more).

Normally you would add the reverse relationship (from paragraph item to container entity) and then use a contextual filter on the container entity: I would create a slideshow of paragraph items, add a relationship to the node and then use a contextual filter on node id. Then if I filter on node id 1, I would see all paragraph items linked to node 1.

Since you are now dealing with a block, I think you might be able to build a similar construction (relationship to the block and contextual filter on block id?) But I encourage you to reconsider.

---
Tags: 8, paragraphs, views
---


# Question
Title: Loading a particular plugin definition by ID
I want to load a plugin definition by its string id within a controller extending ControllerBase. What is the relevant service or class I am looking for?

# Answer
> 17 votes
You can use the plugin manager to fetch a plugin. You only need to find the correct plugin manager service:

```
$type = \Drupal::service('plugin.manager.service'); // Fill your own plugin manager service.
$plugin_definition = $type->getDefinition('plugin_id'); // Fill needed plugin id.

```

---
Tags: 8, plugins
---


# Question
Title: Why is migration lookup failing during synchronisation of Group entities?
On the basis of an RSS feed, I am required to create Group entities and Users out of the feed's items.

Each item contains sufficient data:

```
<item>
  <id>123</id>
  <title>An example</title>
  <description>Some <strong>HTML</strong> description.</description>
  <author>John Doe</author>
  <email>john.doe@example.com</email>
  <pub_date>09/19/2017 - 08:30</pub_date>
</item>

```

I am using Core's migration module along with migrate\_plus and migrate\_tools and wrote two migration yml files, one for creating Group entities out of the items and one to generate users out of the author & email fields.

Taken separately, both work fine, that is I am getting Group entities and User entities as expected. The only issue which I can't get my head wrapped around is to set the respective User to be the Group's owner.

Here's the processing part of the Group yml file:

```
process:
  uid:
    plugin: migration_lookup
    migration: migrate_plus.migration.users
    no_stub: true
    source: email
  label: title
  field_description: description
  created:
    plugin: format_date
    from_format: 'm/d/Y - H:i'
    to_format: 'U'
    source: pub_date
  status:
    plugin: default_value
    default_value: 1
  type:
    plugin: default_value
    default_value: my_group_type

migration_dependencies:
  required:
    - migrate_plus.migration.users

```

All fields except for `uid` are set correctly. If I change the user id process part to something static like

```
  uid:
    plugin: default_value
    default_value: 1

```

it works as well and the Group's owner is set to the Super User account. So, I reckon there's something wrong with the migration\_lookup processing part. I have read numerous tutorials on how to use that and it looks fine to me. I also read that migration\_lookup fails silently if there is an error which makes it hard to debug.

Looking at the migration map table in the database it looks fine too:

```
mysql> select * from migrate_map_users limit 1;
+-----------------+----------------------+---------+-------------------+-----------------+---------------+------+
| source_ids_hash | sourceid1            | destid1 | source_row_status | rollback_action | last_imported | hash |
+-----------------+----------------------+---------+-------------------+-----------------+---------------+------+
| 009d...234ef457 | john.doe@example.com |     118 |                 0 |               0 |             0 |      |
+-----------------+----------------------+---------+-------------------+-----------------+---------------+------+
1 row in set (0.00 sec)

```

Due to the migration dependency through

```
migration_dependencies:
  required:
    - migrate_plus.migration.users

```

the User migration should also run first, but it still doesn't work. Even after both migrations have run through, I tried an update migration run, but the Group's owner is never set (stays at being 0/Anonymous).

Is there soemthing wrong with my yml file? Are there other means to connect user and groups?

# Answer
> 0 votes
s/migrate\_plus.migration.users/users/

The "migrate\_plus.migration." is not part of the migration plugin ID - it is only part of the filename for the config entity.

---
Tags: 8, group, migrations
---


title: Add a form to the list output of a view

text:
# Question
Title: Add a form to the list output of a view
Assume that I've created a view that outputs a list of cars. For each car, I display the name and the age of the car. This is all done with the Drupal UI. Now I'd like to add a simple button (*Set as favorite*) at the end of each line that when clicked saves the ID of the chosen car in a user's session variable. So my view table should look like the following:

```
Name Age Button
car1 23  'set as favorite'
car2 10  'set as favorite'

```

I am not asking about the session-variable part, but only how I can alter the view output to add a simple button to each row of the list output (I bet it'll be a form in each row).

I've done a lot of reading and I bet this could be done with `hook_views_data_alter` or some other `hook_views_*` but I'm not proceeding. I've already tried drop-buttons as suggested on Drupal 8 Add custom action buttons to a view, but that does not solve the things I need. I need the car's ID I want to save in a session variable, so basically I need a form functionality.

# Answer
> 0 votes
You probably can do this with just a Global custom text field and some hidden view fields.

E.g.:

* Add car id to the view but exclude from view.
* Move this to the top of the list.
* Add a global custom text field for your Favorite button using the replacement values. Could be something like:

\<a class="btn btn-success" href="/add/favorite/{{ carId }}?destination=/view/cars"\>Add as Favorite\</a\>

Notes:

Classes are bootstrap specific.

Href is the code to set the favorite.

Destination string is Drupal way to circle back to view.

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


title: Install Site: false ignored

text:
# Question
Title: Install Site: false ignored
I am using the DrupalVM '1.8.6' / Vagrant.

In my Config I say

```
install_site: false

```

Still a Drupal site is installed. How can I stop Vagrant from doing this each time I run `vagrant up --provision`.

# Answer
> 1 votes
I always make sure the "build\_xx" properties are false as well. E.g.:

```
build_composer: false
build_makefile: false
build_composer_project: false

```

YMMV

---
Tags: virtual-machine
---


# Question
Title: How to fetch the completed goal as an entity with the Rules module?
Followup question for the question about "How to access fields from a goal when creating a node with Rules?".

I'm trying to create a rule that finds and uses the fields of the goal that triggered the goal completed event. They can be fetched if you know the goal id (as shown in the answer to the previous question). But creating individual rules for each goal is not viable because there are quite a few of them and I'd like administrators to be able to easily add them without having to write new rules.

So how can I create a rule without specifying a Rules Condition to check the id of the goal that was completed?

# Answer
You could use the Views Rules to get this to work. Read on for more details about how to do so ...

### Step 1: Create an appropriate view

Create a view of all goals completed by the current user, sorted (descending) by the date the goal was completed, and a "Rules" display type, in which you use a pager to only show 1 result (i.e. the most recent one ...).

Here is a view (in export format) with (a) a page display (to list all goals completed by the current user) and (b) a Rules display (to only list the most recent completed goal):

```
$view = new view();
$view->name = 'goals_info_about_completed_goals';
$view->description = 'A list of goals completed by a user.';
$view->tag = 'Goals';
$view->base_table = 'goals';
$view->human_name = 'Goals completed by a user';
$view->core = 7;
$view->api_version = '3.0';
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */

/* Display: Master */
$handler = $view->new_display('default', 'Master', 'default');
$handler->display->display_options['title'] = 'Goals completed by a user';
$handler->display->display_options['use_more_always'] = FALSE;
$handler->display->display_options['access']['type'] = 'none';
$handler->display->display_options['cache']['type'] = 'none';
$handler->display->display_options['query']['type'] = 'views_query';
$handler->display->display_options['exposed_form']['type'] = 'basic';
$handler->display->display_options['pager']['type'] = 'none';
$handler->display->display_options['pager']['options']['offset'] = '0';
$handler->display->display_options['style_plugin'] = 'table';
$handler->display->display_options['style_options']['columns'] = array(
  'goal_img' => 'goal_img',
);
$handler->display->display_options['style_options']['default'] = '-1';
$handler->display->display_options['style_options']['info'] = array(
  'goal_img' => array(
    'sortable' => 0,
    'default_sort_order' => 'asc',
    'align' => '',
    'separator' => '',
    'empty_column' => 0,
  ),
);
/* Relationship: Goal: Goal - completed by users */
$handler->display->display_options['relationships']['goals_completed_goals']['id'] = 'goals_completed_goals';
$handler->display->display_options['relationships']['goals_completed_goals']['table'] = 'goals';
$handler->display->display_options['relationships']['goals_completed_goals']['field'] = 'goals_completed_goals';
$handler->display->display_options['relationships']['goals_completed_goals']['label'] = 'Completed goal';
/* Field: Goal: Goal Image */
$handler->display->display_options['fields']['goal_img']['id'] = 'goal_img';
$handler->display->display_options['fields']['goal_img']['table'] = 'field_data_goal_img';
$handler->display->display_options['fields']['goal_img']['field'] = 'goal_img';
$handler->display->display_options['fields']['goal_img']['label'] = 'Goal image';
$handler->display->display_options['fields']['goal_img']['element_label_colon'] = FALSE;
$handler->display->display_options['fields']['goal_img']['click_sort_column'] = 'fid';
$handler->display->display_options['fields']['goal_img']['settings'] = array(
  'image_style' => 'goal_image',
  'image_link' => '',
);
/* Field: Goal: URL */
$handler->display->display_options['fields']['url']['id'] = 'url';
$handler->display->display_options['fields']['url']['table'] = 'views_entity_goal';
$handler->display->display_options['fields']['url']['field'] = 'url';
$handler->display->display_options['fields']['url']['exclude'] = TRUE;
$handler->display->display_options['fields']['url']['link_to_entity'] = 0;
/* Field: Goal: Title */
$handler->display->display_options['fields']['title_1']['id'] = 'title_1';
$handler->display->display_options['fields']['title_1']['table'] = 'goals';
$handler->display->display_options['fields']['title_1']['field'] = 'title';
$handler->display->display_options['fields']['title_1']['alter']['make_link'] = TRUE;
$handler->display->display_options['fields']['title_1']['alter']['path'] = '[url]';
/* Field: Goal: Goal ID */
$handler->display->display_options['fields']['goal_id']['id'] = 'goal_id';
$handler->display->display_options['fields']['goal_id']['table'] = 'goals';
$handler->display->display_options['fields']['goal_id']['field'] = 'goal_id';
/* Field: Goal: User Points */
$handler->display->display_options['fields']['goal_userpoints']['id'] = 'goal_userpoints';
$handler->display->display_options['fields']['goal_userpoints']['table'] = 'field_data_goal_userpoints';
$handler->display->display_options['fields']['goal_userpoints']['field'] = 'goal_userpoints';
$handler->display->display_options['fields']['goal_userpoints']['settings'] = array(
  'thousand_separator' => '',
  'prefix_suffix' => 1,
);
/* Field: Goal: Goal Category */
$handler->display->display_options['fields']['field_goal_category']['id'] = 'field_goal_category';
$handler->display->display_options['fields']['field_goal_category']['table'] = 'field_data_field_goal_category';
$handler->display->display_options['fields']['field_goal_category']['field'] = 'field_goal_category';
/* Field: Goal: Goal Level */
$handler->display->display_options['fields']['field_goal_level']['id'] = 'field_goal_level';
$handler->display->display_options['fields']['field_goal_level']['table'] = 'field_data_field_goal_level';
$handler->display->display_options['fields']['field_goal_level']['field'] = 'field_goal_level';
/* Field: Goal - completed by users: Created */
$handler->display->display_options['fields']['created']['id'] = 'created';
$handler->display->display_options['fields']['created']['table'] = 'goals_completed_goals';
$handler->display->display_options['fields']['created']['field'] = 'created';
$handler->display->display_options['fields']['created']['relationship'] = 'goals_completed_goals';
$handler->display->display_options['fields']['created']['label'] = 'Completion date';
$handler->display->display_options['fields']['created']['date_format'] = 'short';
$handler->display->display_options['fields']['created']['second_date_format'] = 'long';
/* Field: Goal - completed by users: User */
$handler->display->display_options['fields']['uid']['id'] = 'uid';
$handler->display->display_options['fields']['uid']['table'] = 'goals_completed_goals';
$handler->display->display_options['fields']['uid']['field'] = 'uid';
$handler->display->display_options['fields']['uid']['relationship'] = 'goals_completed_goals';
/* Field: Goal - completed by users: Goal */
$handler->display->display_options['fields']['goal_id_1']['id'] = 'goal_id_1';
$handler->display->display_options['fields']['goal_id_1']['table'] = 'goals_completed_goals';
$handler->display->display_options['fields']['goal_id_1']['field'] = 'goal_id';
$handler->display->display_options['fields']['goal_id_1']['relationship'] = 'goals_completed_goals';
/* Field: Goal - completed by users: Goal - completed by users ID */
$handler->display->display_options['fields']['id']['id'] = 'id';
$handler->display->display_options['fields']['id']['table'] = 'goals_completed_goals';
$handler->display->display_options['fields']['id']['field'] = 'id';
$handler->display->display_options['fields']['id']['relationship'] = 'goals_completed_goals';
$handler->display->display_options['fields']['id']['label'] = 'Completed Goal Seqnr';
/* Sort criterion: Goal - completed by users: Created */
$handler->display->display_options['sorts']['created']['id'] = 'created';
$handler->display->display_options['sorts']['created']['table'] = 'goals_completed_goals';
$handler->display->display_options['sorts']['created']['field'] = 'created';
$handler->display->display_options['sorts']['created']['relationship'] = 'goals_completed_goals';
$handler->display->display_options['sorts']['created']['order'] = 'DESC';
/* Contextual filter: Goal - completed by users: User */
$handler->display->display_options['arguments']['uid']['id'] = 'uid';
$handler->display->display_options['arguments']['uid']['table'] = 'goals_completed_goals';
$handler->display->display_options['arguments']['uid']['field'] = 'uid';
$handler->display->display_options['arguments']['uid']['relationship'] = 'goals_completed_goals';
$handler->display->display_options['arguments']['uid']['default_action'] = 'default';
$handler->display->display_options['arguments']['uid']['default_argument_type'] = 'current_user';
$handler->display->display_options['arguments']['uid']['summary']['number_of_records'] = '0';
$handler->display->display_options['arguments']['uid']['summary']['format'] = 'default_summary';
$handler->display->display_options['arguments']['uid']['summary_options']['items_per_page'] = '25';

/* Display: Page */
$handler = $view->new_display('page', 'Page', 'page_1');
$handler->display->display_options['path'] = 'user/%/completed-goals';

/* Display: RulesList */
$handler = $view->new_display('views_rules', 'RulesList', 'views_rules_1');
$handler->display->display_options['pager']['type'] = 'some';
$handler->display->display_options['pager']['options']['items_per_page'] = '1';
$handler->display->display_options['pager']['options']['offset'] = '0';
$handler->display->display_options['defaults']['fields'] = FALSE;
/* Field: Goal: URL */
$handler->display->display_options['fields']['url']['id'] = 'url';
$handler->display->display_options['fields']['url']['table'] = 'views_entity_goal';
$handler->display->display_options['fields']['url']['field'] = 'url';
$handler->display->display_options['fields']['url']['exclude'] = TRUE;
$handler->display->display_options['fields']['url']['link_to_entity'] = 0;
/* Field: Goal: Title */
$handler->display->display_options['fields']['title_1']['id'] = 'title_1';
$handler->display->display_options['fields']['title_1']['table'] = 'goals';
$handler->display->display_options['fields']['title_1']['field'] = 'title';
$handler->display->display_options['fields']['title_1']['alter']['make_link'] = TRUE;
$handler->display->display_options['fields']['title_1']['alter']['path'] = '[url]';
/* Field: Goal: Goal ID */
$handler->display->display_options['fields']['goal_id']['id'] = 'goal_id';
$handler->display->display_options['fields']['goal_id']['table'] = 'goals';
$handler->display->display_options['fields']['goal_id']['field'] = 'goal_id';
$handler->display->display_options['rules_parameter'] = array(
  'uid' => array(
    'enabled' => 1,
    'type' => 'integer',
    'label' => 'Goal completed by user with id',
    'name' => 'goal_completed_by_uid',
  ),
);
$handler->display->display_options['rules_variables'] = array(
  'url' => array(
    'enabled' => 0,
    'rendered' => 0,
    'type' => '',
    'label' => 'URL',
    'name' => 'url',
  ),
  'title_1' => array(
    'enabled' => 1,
    'rendered' => 0,
    'type' => 'text',
    'label' => 'Title',
    'name' => 'goal_title',
  ),
  'goal_id' => array(
    'enabled' => 1,
    'rendered' => 0,
    'type' => 'integer',
    'label' => 'Goal ID',
    'name' => 'goal_id',
  ),
  'field_goal_category' => array(
    'enabled' => 1,
    'rendered' => 0,
    'type' => 'text',
    'label' => 'Goal Category',
    'name' => 'goal_category',
  ),
  'field_goal_level' => array(
    'enabled' => 1,
    'rendered' => 0,
    'type' => 'text',
    'label' => 'Goal Level',
    'name' => 'goal_level',
  ),
  'goal_userpoints' => array(
    'enabled' => 0,
    'rendered' => 0,
    'type' => '',
    'label' => 'User Points',
    'name' => 'goal_userpoints',
  ),
  'uid' => array(
    'enabled' => 1,
    'rendered' => 0,
    'type' => 'integer',
    'label' => 'Id of User completing goal',
    'name' => 'goal_uid',
  ),
);

```

Before trying to import the above view in your own site, make sure to define these custom fields for the goals you configured (these fields are select lists with a single value allowed):

* Goal Category (machine name `field_goal_category`), eg with values such as "Privilege, Contribution, Participation, Moderation, None".
* Goal Level (machine name `field_goal_level`), eg with values such as "Bronze, Silver, Gold, None".

### Step 2: Create a rule that contains a Views loop

Create a rule which contains a "Views loop" as a Rules Action, which is similar to a regular Rules loop, but allows looping over rows of view results. Use the Rules Display type of the view created in the previous step. Obviously, because of the number of results we configured in the Rules display of the view, this list consists of only 1 list item (i.e. related to the most recently completed goal).

* Within that "Views loop", perform a 1st Rules Action to "Fetch an entity by id", and with these additional details:

+ Parameter: Entity type: Goal
    + Identifier: \[goal-id\]
    + Provides variables: Completed goal (goal\_completed)
* Then add a 2nd Rules Action, within that same "Views loop", something like "Show a message on the site", with a message that looks something like so (note the 2 custom fields included, with machine names `field_goal_category` and `field_goal_level`):

> Details about completed goal:
>
> + Goal ID: \[goal-completed:goal-id\]
>     + Goal Title: \[goal-completed:title\]
>     + Goal Category: \[goal-completed:field\_goal\_category\]
>     + Goal Level: \[goal-completed:field\_goal\_level\]

Here is an export of a rule you can use for this (if you have both custom fields defined, you should be able to import this rule in your own site):

```
{ "rules_show_details_about_completed_goal" : {
    "LABEL" : "Show details about completed goal",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "TAGS" : [ "goals" ],
    "REQUIRES" : [ "rules", "goals" ],
    "ON" : { "goal_awarded" : [] },
    "DO" : [
      { "VIEW LOOP" : {
          "VIEW" : "goals_info_about_completed_goals",
          "DISPLAY" : "views_rules_1",
          "USING" : { "goal_completed_by_uid" : [ "awarded-user:uid" ] },
          "ROW VARIABLES" : {
            "goal_title" : { "goal_title" : "Title" },
            "goal_id" : { "goal_id" : "Goal ID" }
          },
          "DO" : [
            { "entity_fetch" : {
                "USING" : { "type" : "goal", "id" : [ "goal-id" ] },
                "PROVIDE" : { "entity_fetched" : { "goal_completed" : "Completed goal" } }
              }
            },
            { "drupal_message" : { "message" : "Details about completed goal:\u003Cbr \/\u003E\u003Cbr \/\u003E\r\n- Goal ID: [goal-completed:goal-id]\u003Cbr \/\u003E\r\n- Goal Title: [goal-completed:title]\u003Cbr \/\u003E\r\n- Goal Category: [goal-completed:field_goal_category]\u003Cbr \/\u003E\r\n- Goal Level: [goal-completed:field_goal_level]\u003Cbr \/\u003E" } }
          ]
        }
      }
    ]
  }
}

```

Here are the "Replacement patterns for Completed goal" that are shown with the Rules Action to Show a message on the site:

```
[goal-completed:title]                  Title               Goal "title" property.
[goal-completed:created]                Created             The date the goal was created.
[goal-completed:changed]                Changed             The date the goal was changed.
[goal-completed:Goal ID]                Label               The human readable label.
[goal-completed:url]                    URL                 The URL of the entity.
[goal-completed:field-goal-description] Goal Description    Field "field_goal_description".
[goal-completed:goal-userpoints]        User Points         Field "goal_userpoints".
[goal-completed:goal-img]               Goal Image          Field "goal_img". The following properties may be appended to the token: file (The image file.)
[goal-completed:field-goal-category]    Goal Category       Field "field_goal_category".
[goal-completed:field-goal-level]       Goal Level          Field "field_goal_level".
[goal-completed:field_goal_description] Goal Description    Long text field.
[goal-completed:goal_userpoints]        User Points         Integer field.
[goal-completed:goal_img]               Goal Image          Image field.
[goal-completed:field_goal_category]    Goal Category       List (text) field.
[goal-completed:field_goal_level]       Goal Level          List (text) field.

```

Obviously, these Replacement patterns have been made available via the Rules Action "Fetch entity by Id" that precedes it. And with that, you have anything available to "*find and use the fields of the goal that triggered the goal completed event*" (as in your question).

### Step 3: Demo

Here is an example of a message shown to a user, after the user completes some goal (if the above view and rule is enabled):

> Details about completed goal:
>
> * Goal ID: 11
> * Goal Title: Citizen Patrol
> * Goal Category: Moderation
> * Goal Level: Bronze

**Note**: For way more details on using Views Rules, refer to ("Option 2" of) my answer to "How to use Rules to send an E-mail after saving a new comment, to users who checked a boolean in their profile?".

PS: this answer applies to D7 ...
> 1 votes

---
Tags: rules, 7
---


# Question
Title: Map or Edit Query String Values in Views?
As part of a port of a non-Drupal site to Drupal, I need to map a url query string to filters.

For example, if I have this query string and slect filter selected on Site A (Non-Drupal)

**Site A**

Value 1 | Value 1

Value 2 | Value 2

Value 3 | Value 3

www.sitea.com/?value=value%1

**Site B:**

Value 1 |1

Value 2 |2

Value 3 |3

www.sitea.com/?value=1

Site A cannot be edited. Is it possible to either edit the values in Site B to match that of site A (within views only, not actual field data) or map the query string, so that Views will see "www.sitea.com/?value=value%1" and display "www.sitea.com/?value=1"

I know I can change the Filter identifier (i.e. ?value) on the filter settings tab but how can I changed the values themselves?

In reality, they are far more complex than this so I'd like to avoid HTACESS.

# Answer
You can use the hook\_views\_pre\_view function in your custom module to change the query parameters using PHP, so a rough untested example of the code could look something like:

```
function MODULE_views_pre_view(&$view) {
  switch ($view->name) {
    case 'YOUR_VIEW_NAME': {
      // change your query strings to
      if ($_GET['value']) {
        $value = $_GET['value'];
        $new_value = substr($value, 0 , 6); // remove the 'value%' from Site A querystring
        $_GET['value'] = $new_value;
      }
      break;
    }
  }
}

```
> 0 votes

# Answer
Use the module Views Contextual Filter Query It will fit your needs.
> -1 votes

---
Tags: 7, views
---


# Question
Title: Can I get dependent services into a custom class without creating a service?
I've got a class hierarchy where I need to be able to instantiate different objects within the hierarchy. Instead of using global functions, I'd like to use injected services from the container via `$this` within those objects.

When researching this, it seems as though the only examples I can find involve creating a service, such as Dependency injection in a custom class. However, I don't need a new service. If I did create one, wouldn't I need to create one for every class within the hierarchy so that they could be instantiated? This seems excessive.

If my parent class implements `ContainerInjectionInterface` and I have a `create()` method to inject the services, can I just instantiate the objects this way, or is it bad practice?

`$thing = OneOfMySubClasses::create(\Drupal::getContainer(), ...);`

# Answer
> 4 votes
Not sure how many classes/services you have, but the main point for having services is to have the dependencies injected. Drupal core alone has probably 100+ services, so I wouldn't worry too much about adding 10 or so more.

Using ContainerInjectionInterface is also fine, if you do that, you can use the class\_resolver service that will take care of doing that, it also accepts both a class implementing that interface as well as a service name.

https://api.drupal.org/api/drupal/core%21lib%21Drupal.php/function/Drupal%3A%3AclassResolver/8.4.x

Depending on how you use/configure/decide which of your classes to you, you could also make a plugin type and make them plugins, e.g. like block plugins or field formatters.

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