# Question
Title: How to create sortable checkboxes using the form API?
I'm using Drupal 7 and I need the ability for the user to choose from a list of options and put those options in order. I am using type checkbox and passing in an array of options to create the list.

I need to be able to check the options needed and sort them.

The form checkbox creation is fairly straightforward, but doesn't appear to have a weight option for the individual checkboxes or really any attributes except value.

Any help would be appreciated. Thank you.

```
$form[$key]['articleFields'] = array(
    '#title' => t('article Fields'),
    '#type' => 'checkboxes',
    '#description' => t('Choose the fields you want selected'),
    '#options' => $articleFields,
    '#default_value' =>$articleFields_checked,

);

```

# Answer
I was able to get this working using a modified version of the code here http://dropbucket.org/node/204

The adjustments I made were to allow my table to be an element on a parent form and to repopulate the from my variables array... //TODO bubble checked boxes to top

```
    $rows = array();
    $row_elements = array();
    $data=array();
    //$shared['articleFields'] values stored in variables table -- loaded in parent form
    //$key is name of my parent form this gets attached to

    $cc=-10; //default weights starting at -10
    //field machine names with titles
    $articleFields = array(
      'title'=>t('Headline'),
      'field_news_categories'=>t('News Categories'),
      'field_text_2'=>t('Subheading'),
      'field_photo_caption_1'=>t('Featured Photo'),
      'body'=>t('Copy'),
      'field_text_4'=>t('Featured Quote'),
      'field_keywords'=>t('Keywords'),
      'field_websites'=>t('Related Links'),
      'field_images'=>t('Additional Images'),
      'field_slideshow'=>t('Slideshow'),
      'field_video'=>t('Video'),
      'scheduler_settings'=>t('Scheduler'),
      'group_alternates'=>t('Alternates'),
      'field_text_1'=>t('Alternate Headline'),
      'field_text_3'=>t('Alternate Subheading'),
      'field_photo_caption_2'=>t('Alternate Photo'),
      'field_longtext_1'=>t('Alternate Copy'),
    );

    foreach ($articleFields as $k =>$v) {
        // Build the table rows.
        $dv="";
        $dv2="";

        //if no values are defined use default weights from -10 up
        if(isset($shared['articleFields']['elements'][$k]['weight'])){
            $dv=$shared['articleFields']['elements'][$k]['weight'];
        }
        else $dv=$cc++;

        //if no value is defined use 0 for enabled value (unchecked)
        if(isset($shared['articleFields']['elements'][$k]['enabled'])){
            $dv2=$shared['articleFields']['elements'][$k]['enabled'];
        }
        else $dv2=0;
        $rows[$k] = array(
            'data' => array(
                // Cell for the cross drag&drop element.
                array('class' => array('entry-cross')),
                // Weight item for the tabledrag.
                array('data' => array(
                        '#type' => 'weight',
                        '#title' => t('Weight'),
                        '#title_display' => 'invisible',
                        '#default_value' => $dv,
                        '#attributes' => array(
                            'class' => array('entry-order-weight'),
                        ),
                    )),
                // Enabled checkbox.
                array('data' => array(
                        '#type' => 'checkbox',
                        '#title' => t('Enable'),
                        '#title_display' => 'invisible',
                        '#default_value' => t($dv2),
                    )),

                // Name textfield.
                array('data' => array(
                        '#type' => 'textfield',
                        '#size' => 50,
                        '#disabled' => TRUE,
                        '#title' => t('Field'),
                        '#title_display' => 'invisible',
                        '#default_value' => t($v),

                    )),

            ),
            'class' => array('draggable'),
        );

        // Build rows of the form elements in the table.
        $row_elements[$k] = array(
            'weight' => &$rows[$k]['data'][1]['data'],
            'enabled' => &$rows[$k]['data'][2]['data'],
            'field' => &$rows[$k]['data'][3]['data'],
        );
    }
     //sort both the rows and the row elements on the weight value

        uasort($rows, function($a, $b) {
            return $a['data'][1]['data']['#default_value'] <=> $b['data'][1]['data']['#default_value'];
        });

        uasort($row_elements, function($a, $b) {
            return $a['weight']['#default_value'] <=> $b['weight']['#default_value'];
        });

    $id=str_replace("shared_", "", $key);
    $id="form-item-shared-".$id."-articleFields";

    // add this to parrent form
    $form[$key]['articleFields'] = array(
        '#prefix'=>'<div class='.$id.'>',
        '#theme' => 'table',
        // The row form elements need to be processed and build,
        // therefore pass them as element children.
        'elements' => $row_elements,
        '#header' => array(
            // We need two empty columns for the weigth field and the cross.
            array('data' => NULL, 'colspan' => 2),
            t('Enabled'),
            t('Field'),
        ),
        '#rows' => $rows,
        '#empty' => t('There are no entries available.'),
        '#attributes' => array('id' => 'entry-order'),
        '#sufix'=>'</div>',
    );
    drupal_add_tabledrag('entry-order', 'order', 'sibling', 'entry-order-weight');

```
> 0 votes

---
Tags: 7, forms
---


# Question
Title: How to load image from Custom Module with javascript?
I'm trying to build a custom module https://github.com/alexseif/drupal\_infinite\_scroll and I need to load the image in the images folder "images/ajax-loader.gif" in the js file alx-infinite-scroll.js

I have this in my js file `drupal_get_path('module', 'alx_infinite_scroll') + '/images/ajax-loader.gif'` I have no clue where to start, any help would be much appreciated and/or link to the relevant documentation if possible.

# Answer
> 3 votes
`drupal_get_path()` is a PHP function so you cannot call it in your JS.

To use the result of that function in your JS you would need to call the function in your PHP and then add the output to the JS on the page. You can use Drupal.settings for this. For example:

```
// Settings to pass to our JS.
$settings = array(
  'loaderImgPath' => drupal_get_path(
    'module',
    'alx_infinite_scroll'
  ) + '/images/ajax-loader.gif',
);
// Add to the JS settings.
drupal_add_js(array('alx_infinite_scroll' => $settings), 'setting');

```

Then you can use something like this in your JS:

```
Drupal.behaviors.alxInfiniteScroll = {
  attach: function (context, settings) {
    var imgPath = settings.alx_infinite_scroll.loaderImgPath;
  }
}

```

I recommend reading some of the documentation on Drupal's JavaScript APIs as it goes over this. For example: https://www.drupal.org/docs/7/api/javascript-api/managing-javascript-in-drupal-7

To do that though you need to add the above PHP code somewhere. In your case you are loading your JS in the info file, which means it will load on every page. I would advise against this unless you actually need your JS to run on all pages, but if you do want it on all pages you could use something like hook\_page\_build().

In that case since you are dealing with the page render array you can use the #attached method of adding JS and JS settings that is referred to on the documentation page I linked above.

---
Tags: 7, javascript
---


# Question
Title: How to call/submit Form from another page in custom module?
I would like to set cron function in my custom module. I have created one form which is called with submit button from UI. Now I would like to submit/call that form from another page (.module file) where I have written my hook\_cron function, how it would be possible?

In Drupal 7, I use

```
$form_state['values'] = "";
drupal_form_submit('customfeedimport_main_pagecallback_submit', $form_state);

```

But I am new to Drupal 8, so how to perform this cron thing in Drupal 8?

Also what should be included in the namespace, use?

# Answer
You can do it with the FormBuilder::submitForm() function.

To register a new user (taken from the docs):

```
// register a new user
$form_state = new FormState();
$values['name'] = 'robo-user';
$values['mail'] = 'robouser@example.com';
$values['pass']['pass1'] = 'password';
$values['pass']['pass2'] = 'password';
$values['op'] = t('Create new account');
$form_state->setValues($values);
\Drupal::formBuilder()->submitForm('user_register_form', $form_state);

```

You might have to include the namespace for the FormState class before this code if not done already.
> 4 votes

---
Tags: 8, hooks
---


title: How to set a menu item active ?

text:
# Question
Title: How to set a menu item active ?
I have a site that has a lot of menus. One of them is the main menu that has few items. These items link to main areas of the site, and each of these main areas has one specific menu. When I'm on a landing page of one of these main areas, the item of it on the main menu is active, but when I'm on an internal page of one of these areas, the item on the main menu is not active.

Is there any way to make it active automatically?

I tried using menu\_position but it seems not be working.

# Answer
Context provides this functionality out of the box.
> 11 votes

# Answer
Their is a lot of ways. I list here only things compatible with D7 and eventually on D6.

**Use a modules**

**Code your stuff**

Their is now a native API menu\_tree\_set\_path to set the path you want to use to calculate the menu active trail.

You can also work in theme\_links but but I recommend to use menu\_tree\_set\_path so other module know what is your active link. The advantage is you can use this function in your theme without creating a module.

Keep in mind, menu\_position has an API to create your custom rules.

**So what should I use???**

It's depend of your need. if you have simple rules like: for this node type/views/taxonomy i want this active menu, context is good.

If you have a good url structure (autopath) than follow your menu structure, menu\_trail\_by\_path will just works without any effort.

I never used menu\_position... so I can very tell.

If you need some special logic, coding your things is certainly faster than creating 40 context or rules...
> 14 votes

# Answer
The easiest way is just to make those menu items of your "internal" pages (subpages belonging to your areas/landing pages) children of landing pages menu items.

Something like:

```
primary links menu
|
+-- landing page 1 menu item
|   |
|   +-- internal page 1 menu item
|   +-- internal page 2 menu item
|
+-- landing page 2 menu item
    |
    +-- internal page 3 menu item
    +-- internal page 4 menu item

```

If you have to keep them in separate menus though, you would probably need to play with theme\_links() to keep proper "active-trail" and/or "active" classes.
> 4 votes

# Answer
Perhaps the Menu Block module would help you.

(In conjunction with the approach that Maciej outlines above).

From the Menu Block project page:

> It provides configurable blocks of menu trees starting with any level of any menu. And more!
>
> So if you’re only using your theme’s Main menu links feature, you can add and configure a “Main menu (levels 2+)” block. That block would appear once you were on one of the Main menu’s pages and would show the menu tree for the 2nd level (and deeper) of your Main menu and would expand as you traversed down the tree. You can also limit the depth of the menu’s tree (e.g. “Main menu (levels 2-3)”) and/or expand all the child sub-menus (e.g. “Main menu (expanded levels 2+)”).
> 2 votes

# Answer
You can also use `hook_translated_menu_link_alter()`. This would be little tricky.

```
/**
 * Implements hook_translated_menu_link_alter()
 */
function Module_translated_menu_link_alter(&$item, $map) {

    if ($item['menu_name'] == 'menu-name') {

        //check first two arg from url
        $path = arg(0)."/".arg(1);

        //add class active-trail if path match
        if (strpos($item['link_path'], $path) !== false) {
            $item['in_active_trail'] = true;

        }

    }
}

```
> 1 votes

---
Tags: 7, routes
---


# Question
Title: "New" Marker for Comments does not vanish
The "New" marker above comments does not vanish in my theme. It is basically vanilla Bartik with some tweaks. The marker is hidden by default and inserted via JS according to this comment in comment.html.twig:

> Hide the "new" indicator by default, let a piece of JavaScript ask the server which comments are new for the user. Rendering the final "new" indicator here would break the render cache.

This seems to be working as the marker is displayed after loading. The problem is that it is always displayed even on repeated views of the article. I have investigated it for some time now. It appears that the AJAX call to /history/NID/read always returns the current timestamp, not the timestamp of the previous view. Returning the timestamp of the current request does not make a lot of sense to me.

Is my analysis correct so far? Should /history/NID/read return the last instead of the current? If that is true, what could be going wrong here?

Thanks in advance,
Eric

# Answer
Trying this out in vanilla Bartik doesnt have issues. I couldn't say for sure without looking at your "modifications". But on digging a little deeper I assume it's one of the following

The reason for your issue is most likely your modifications to node.html.twig(or node--article.html.twig)

1. You would have rendered 'comments' outside of

```
<article{{ attributes}}>
</article>

```

in your template.
2. You would have removed a required attribute "data-history-node-id" from

```
<article>
</article>

```

tags in your template

**Details:**

*/history/NID/read always returns the current timestamp*

The module in question here is the new core 'history' module. The path "/history/NID/read", if you check history.routing.yml, resolves to readNode() in HistoryController In there you can find a call to history\_write($node-\>id()); first and then followed by a call to history\_read($node-\>id()) which would return the current timestamp (because it has just updated it in the previous history\_write line)

According to the function description

> "Marks a node as read by the current user right now."

so it is used to mark a node as read by the user and not to get a node's last read timestamp.

The new marker logic is at core 'comments' module comments/js/comment-new-indicator.js processCommentNewIndicators() function.

The following line will not return a value

```
    var $node = $placeholder.closest('[data-history-node-id]');

```
* if the $placeholder(marker) was not inside tag with attribute "data-history-node-id"
* if the article didn't have the attribute "data-history-node-id". Make sure you don't remove it from your node.html.twig (or equivalent)
> 2 votes

---
Tags: theming, 8, comments
---


# Question
Title: Set a main-menu item as active with custom code
I want to set a menu item of the main menu as active (class="active").

I'm specifically looking for a hook or function, not a contrib module.

I have seen recommendations for Context, and I have looked in the module code, but it uses hooks which I cannot find on the API-Site.

# Answer
> 1 votes
My solution is this:

```
function mymodule_init() {
    $link=menu_link_load(346);
    $link["options"]["attributes"]["class"]="active";
    menu_link_save($link);
}

```

The id 346 is the `mlid` no idea what this mean but I got this id with this little dump:

```
echo('<pre>');
dump(menu_tree_all_data('main-menu'));
echo('</pre>');

```

# Answer
> 2 votes
If you simply want to add the 'active' class to a menu item you could do it in the code before printing the menu. If you want the menu item to also act like an active item you could use menu\_tree\_set\_path() that was supposedly added in Drupal 7.9.

In earlier versions and Drupal 6 I used this:

```
function mymodule_init() {
  $item = menu_get_item($_GET['q']);
  $item['href'] = 'node/1';
  menu_set_item(NULL, $item);
}

```

However both options just add the 'active-trail' (not 'active') class(es), but that should suffice in most cases.

# Answer
> 1 votes
You could use `menu_set_active_trail` to set which menu should be rendered as active.

Another way is to mess with `$_GET['q']`, but you really want to avoid that if at all possible, since it can lead to some strange bugs.

# Answer
> 1 votes
You can also use `hook_translated_menu_link_alter()`

```
/**
 * Implements hook_translated_menu_link_alter()
 */
function Module_translated_menu_link_alter(&$item, $map) {

    if ($item['menu_name'] == 'menu-name') {

        //check first two arg from url
        $path = arg(0)."/".arg(1);

        //add class active-trail if path match
        if (strpos($item['link_path'], $path) !== false) {
            $item['in_active_trail'] = true;

        }

    }
}

```

---
Tags: 7, routes, hooks
---


title: Taxonomy import via csv?

text:
# Question
Title: Taxonomy import via csv?
Is there a way to quickly create taxonomy categories by importing a csv file?

If so would it preserve any hierarchical relationships?

I've explored the `taxonomy_csv` project just not totally sure if it does what i wanted.

# Answer
> 3 votes
this is a Module Drupal 6 to import nodes from CSV, but acording their description, you can import taxonomy with its hierarchy: http://drupal.org/project/node\_import

to Drupal 7 exist an alternative: Feedshttp://drupal.org/project/feeds

# Answer
> 1 votes
You can use Taxonomy CSV import/export
Also it work well with hierarchical relationships.

# Answer
> 0 votes
I had to import hundreds for terms, which contained custom fields, for a recent project. Here is a method for Drupal 7 using custom drush command...

```
 /**
 * Implements hook_drush_command
 */
function glossary_import_drush_command() {
  $items['glossary-import'] = array(
    'description' => "Import glossary terms to Glossary taxonomy from CSV",
    'aliases' => array('gloss-imp'),
    'options' => array(
      'csv' => 'Path to CSV file to use',
    ),
    'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL,
  );
  return $items;
}
/**
 * Run command logic.
 */
function drush_glossary_import($csv) {

  // Read csv contents into PHP
  $file = file_get_contents($csv);

  // Create array from file
  $array = array_map("str_getcsv", explode("\n", $file));

  // Make sure it's converted to utf8
  $array_utf8 = utf8_converter($array);

  // Get the vocab id from the vocabulary name
  $vocab = taxonomy_vocabulary_machine_name_load('VOCABULARY_NAME');

  // Create taxonomy terms for each item in array
  foreach ($array_utf8 as $item) {
    // If we have no term name, skip
    if (!empty($item[0])) {
      // Create some friendly variables from $item
      $term_name = !empty($item[0]) ? $item[0] : '';
      $term_sort_name = !empty($item[1]) ? $item[1] : '';
      $term_search_term = !empty($item[2]) ? $item[2] : '';
      $term_description = !empty($item[3]) ? $item[3] : '';

      // Check if term exists so we do not overwrite or create duplicate term
      $query = new EntityFieldQuery;
      $result = $query
      ->entityCondition('entity_type', 'taxonomy_term')
      ->propertyCondition('name', $term_name)
      ->propertyCondition('vid', $vocab->vid)
      ->execute();

      // If we don't find a term with the above query, create term
      if (empty($result['taxonomy_term'])) {
        // Setup term
        $term = new stdClass();
        $term->vid = $vocab->vid;
        $term->name = $term_name;
        $term->field_glossary_sortable_name[LANGUAGE_NONE][0]['value'] = $term_sort_name;
        $term->field_glossary_search_term[LANGUAGE_NONE][0]['value'] = $term_search_term;
        $term->description = $term_description;

        // Save term
        taxonomy_term_save($term);

        // Report message term was saved
        drupal_set_message($term_name . ' added');
      }
      else {
        // Warning message, term exists, skip
        drupal_set_message($term_name . ' exists! Skipping', 'warning');
      }
    }
  }
}

function utf8_converter($array) {
  array_walk_recursive($array, function(&$item, $key) {
    if(!mb_detect_encoding($item, 'utf-8', true)){
      $item = utf8_encode($item);
    }
  });

  return $array;
}

```

# Answer
> 0 votes
This module allows you to import or export taxonomy from or to a CSV (comma-separated values) file or with a copy-and-paste text.

https://www.drupal.org/project/taxonomy\_csv

---
Tags: 7, taxonomy-terms, importing-exporting
---


# Question
Title: Getting the available template variables in a custom module
I'm making a custom module that will hook into the default theme and override a template file. Like you can do in a custom theme. At this moment I can already use the template that was made in the custom module with the hook\_theme() function, it shows in my page. But the available variables are not showing in here. (for example: content, attributes, ...).

Probably because the module does not recognise these variables? How do I pass these variables to the template in my custom module. I read about the function hook\_preprocess\_HOOK() but no luck so far.

This is the implementation of `hook_theme()`.

```
/**
 * Implements hook_theme()
 */
function episode_data_theme($existing, $type, $theme, $path) {
        return [
        'paragraph__episode_content_question_slider' => ['variables' => [] ],
    ];
}

```

This is the content of the template.

```
{#
/**
 * @file
 * Default theme implementation to display a paragraph.
 *
 * Available variables:
 * - paragraph: Full paragraph entity.
 *   Only method names starting with "get", "has", or "is" and a few common
 *   methods such as "id", "label", and "bundle" are available. For example:
 *   - paragraph.getCreatedTime() will return the paragraph creation timestamp.
 *   - paragraph.id(): The paragraph ID.
 *   - paragraph.bundle(): The type of the paragraph, for example, "image" or "text".
 *   - paragraph.getOwnerId(): The user ID of the paragraph author.
 *   See Drupal\paragraphs\Entity\Paragraph for a full list of public properties
 *   and methods for the paragraph object.
 * - content: All paragraph items. Use {{ content }} to print them all,
 *   or print a subset such as {{ content.field_example }}. Use
 *   {{ content|without('field_example') }} to temporarily suppress the printing
 *   of a given child element.
 * - attributes: HTML attributes for the containing element.
 *   The attributes.class element may contain one or more of the following
 *   classes:
 *   - paragraphs: The current template type (also known as a "theming hook").
 *   - paragraphs--type-[type]: The current paragraphs type. For example, if the paragraph is an
 *     "Image" it would result in "paragraphs--type--image". Note that the machine
 *     name will often be in a short form of the human readable label.
 *   - paragraphs--view-mode--[view_mode]: The View Mode of the paragraph; for example, a
 *     preview would result in: "paragraphs--view-mode--preview", and
 *     default: "paragraphs--view-mode--default".
 * - view_mode: View mode; for example, "preview" or "full".
 * - logged_in: Flag for authenticated user status. Will be true when the
 *   current user is a logged-in member.
 * - is_admin: Flag for admin user status. Will be true when the current user
 *   is an administrator.
 *
 * @see template_preprocess_paragraph()
 *
 * @ingroup themeable
 */
#}
{% block paragraph %}
    <div{{ attributes }}>
        {% block content %}
            {% set sliderDescription = content.field_slider_description|render|striptags %}
            {{ content.field_available_for }}
            <div {{ attributes }}  class="content-block content-block-slider">
                {{ content.field_slider_question }}
                <div class="field_slider_description">{{ sliderDescription|length > 200 ? sliderDescription|slice(0, 200) ~ '...' : sliderDescription }}</div>
                <a class="got-it" href="#content-block-{{ paragraph.id() }}" data-id="{{ paragraph.id() }}">{{ 'Got it'|trans }}</a>
            </div>
            <div id="content-block-{{ paragraph.id() }}" class="modal-dialog">
                <div>
                    <a href="#close" data-id="{{ paragraph.id() }}" id="{{ paragraph.id() }}" class="content-block-done close-modal-dialog"></a>
                    {{ content.field_slider_question }}
                    {{ content.field_slider_description }}
                </div>
            </div>
        {% endblock %}
    </div>
{% endblock paragraph %}

```

This is the debug output I get on the page.

>

# Answer
> 2 votes
According to your code, you are creating a custom template for a paragraph.

As you are trying to access variables, that will be added by the paragraph module, you'll have to tell the theming system that it is a paragraph.

You can do so by adding the 'paragraph' base hook. This way the template will get the variables provided by the paragraph (pre-)processing:

```
/**
 * Implements hook_theme()
 */
function episode_data_theme($existing, $type, $theme, $path) {
  return [
    'paragraph__episode_content_question_slider' => [
      'base hook' => 'paragraph',
    ],
  ];
}

```

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


# Question
Title: Pass variable from theme page template to commerce-product file
I am new to drupal and this is my first website in drupal. I am looking to pass a variable from newtheme.theme to commerce-product.html.twig but I am not able to do so.

Here is my code (newtheme is name of my theme)

```
function newtheme_preprocess_page(&$variables) {
 $variables['product_cta'] = 'Static Text';
}

```

in commerce-product.html.twig

```
{{product_cta}}

```

but this is not working the product\_cta will be a call to action which will be calculated programmatically and passed to the product single page. I am using Drupal 8 and Commerce 2.X.X

Any help is really appreciated.

# Answer
> 1 votes
You can use the next function in your theme / module:

```
function YOURT_HEME_preprocess_commerce_product(&$variables) {
 $variables['product_cta'] = 'Static Text';
}

function YOURT_MODULE_preprocess_commerce_product(&$variables) {
 $variables['product_cta'] = 'Static Text';
}

```

And show the variables in the commerce-product.html.twig file:

```
{{ product_cta }}

```

;)

# Answer
> 0 votes
Clear the cache after you created the new function if you didn't.

If It still not working, create a new module and place the preprocess\_page function into the module

---
Tags: commerce
---


title: How to create a drop-down block?

text:
# Question
Title: How to create a drop-down block?
I created a view block to display my content in a boostrap grid.

My question is simple:

How to create a "Header" in my view to create an "Accordion" link and display My content when I click on it?

I want to display on the link "Accordion", the number of elements of the view

I would like to do like this page, but with the contents of my view instead of the text :

https://www.w3schools.com/bootstrap/tryit.asp?filename=trybs\_collapsible\_accordion&stacked=h

# Answer
I think the Ajax Docs gives a pretty good example. Here are the pseudo steps:

1. You render your view block with 5 elements with "read more" submit as a form. The wrapper is is "my-ajax-block".
2. Clicking on the submit will create an ajax call (with help of built in ajax mechanism of Drupal).
3. You will make a call for all the items you need (50 pieces in your case), hopefully with the same service you provide the 5 one.
4. And you just send back the ajax response which will override the "my-ajax-block" with the fetched content.
> 0 votes

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


# Question
Title: Is it possible to override a core function instead of just altering it?
I would like to add a feature to the core string contextual filter, implemented in core/modules/views/src/Plugin/views/argument/StringArgument.php.

If I use `hook_views_query_alter()`, I would have to undo everything the core function did first, then roll out my changes.

Is there a way to just completely override the core function instead of only altering the results?

The contextual range filter accomplishes this by presenting the site admin with a configuration page to select which instances of an existing filter should be replaced by the new object. I could follow this route, but I would prefer to update all cases site-wide.

# Answer
Personally I would make an inheritance from this core plugin, extend it in my own class (classes), and change in the views to use my custom plugin.
> 0 votes

---
Tags: 8, views
---


# Question
Title: Why the menu items to edit a specific vocabulary and terms does not show up in administration tool bar?
I created a new user with specific role and permissions to CRUD 1 content type and 1 taxonomy vocabular and terms. The thing is that the administration menu item does not show up for the taxonomy pages, logged in as that user i only see the Content tab \> Add content \> My content type

The user has permissions to adminiter vocabularies and taxonomies and edit/delete terms for its specific vocabulary. Has access to administration toolbar

If i put the URL directly i can edit a term, even create a new one for the specific vocabulary

Do i need to set up another permission?

I'm using admin\_toolbar module

# Answer
> 0 votes
You need to add 2 more permissions as below

1) 'Use the administration pages and help' under System 2) 'Use the administration toolbar' under Toolbar

---
Tags: 8, configuration, taxonomy-terms
---


# Question
Title: Is there a way to get multiple image sizes from a single image?
In Drupal 8 *Manage display* for the image field, I can assign only one image style.

I have two image styles: thumbnail and medium.

when I upload an image through image uploader, I need to view my uploaded image in those two image styles.

Is there a way to show the image in those two sizes from the single image I have uploaded?

If I selected thumbnail in the manage display on the image field it will save the image as thumbnail, but not as medium size as well. I need to save the image in both the sizes, or I need to get both the styled images from the single image I upload. The following code can get the image for the given style in manage display.

```
$imageStyle = ImageStyle::load('medium');
$galleryImage = $imageStyle->buildUri($image->entity->getFileUri());

```

# Answer
By default, any file you upload via the file field goes into the public files directory `/sites/default/files`. And you can choose to apply any image style to the same image and configure it separately per display.

E.g. Let's say you upload an image with name `my_beatiful_cat.jpg` from a file field on a node page.

1. The image by default will stay at `sites/default/files/my_beatiful_cat.jpg`.
2. From manage display of the content type, in the `default` view, let's say you choose the image style to be medium and save.
3. When you view the node, a new image will be created from the uploaded image at `sites/default/files/styles/medium/public`. So, you will have a file `sites/default/files/styles/medium/public/my_beatiful_cat.jpg` which will have the dimensions as per the image style applied.
4. This is true for any other image style that you apply for any other display.

So, you only upload an image once. Image styles are responsible for generating images with respective sizes as per the configuration and the appropriate image file is rendered.
> 2 votes

# Answer
It is not mandatory to define image styles with actual image during upload. Once the image is uploaded we can assign the image style to any image field for display.
> 1 votes

---
Tags: 8, media
---


# Question
Title: How can I select a user role at the time of the account registration?
How can I show the field to let users choose the role when they register an account on Drupal 8?

# Answer
> 1 votes
Good day,

Have you tried the Select registration roles module? I think this would be a straightforward configuration for the role field that you want.

Hope everything is in order.

Thanks!

# Answer
> 0 votes
You can add a new entity reference field (users) in account setting pages 'admin/config/people/accounts' and select Role. Form display settings can be updated to display the Roles.

---
Tags: users
---


title: Special characters in email body

text:
# Question
Title: Special characters in email body
I'm attempting to send an email from a Drupal 8 module I'm developing, and it works except that special characters (' \< \>) seem to be getting escaped.

My module has a configuration to select whether the emails are plain text or HTML (using Swiftmailer). In plain text messages, apostrophes get replaced by `'` while in the HTML messages, all HTML tags receive similar treatment, so the message arrives, but the HTML tags are all shown in the message, rather than formatting it.

Heres an extract from my hook\_mail handler:

```
  $message['subject'] = $params['subject'];
  $body = $params['body'];
  if ($config->get('confirmation.format_html')) {
    // Set up HTML email.
    $message['headers']['Content-Type'] = 'text/html; charset=UTF-8';
    $message['body'][] = $body;  // HTML version of message body.
    $message['plain'] = \Drupal\Component\Utility\SafeMarkup::checkPlain($params['body']);  // Plain text version of body.
  } else {
    $message['body'][] = $params['body'];  // Plain text version of body.
  }

```

It seems there's some escapement of special HTML characters going on, but I can't see where?

# Answer
> 1 votes
Make sure what you're passing in is a renderable array... and render it before assigning it to the message body field:

```
  $markup = ['#markup' => "<strong>We do HTML</strong>"];
  $message['body'][] = render($markup);

```

Note: This makes some sense i guess but i really just stumbled onto the solution, so i'm not sure how correct it is, but it works.

---

Incidentally, for the plain-text version i recommend doing what Drupal core's PHP mailer does in its format method:

```
use Drupal\Core\Mail\MailFormatHelper;

// Join the body array into one string.
$message['body'] = implode("\n\n", $message['body']);

// Convert any HTML to plain-text.
$message['body'] = MailFormatHelper::htmlToText($message['body']);
// Wrap the mail body for sending.
$message['body'] = MailFormatHelper::wrapMail($message['body']);

```

---
Tags: 8, emails
---


# Question
Title: Checking if user is logged into Drupal from another php application using Drupal services and REST
I have an external php application that currently uses Drupal services to authenticate users.

It's working fine but users frequently enter incorrect credentials and Drupal's flood control eventually blocks the IP of my application. And therefore every user that attempts to login to my application.

The plan to get around this is to have users log directly into Drupal and redirect them to the app. And if they go straight to the app it checks to see if the user is logged in via services. If not logged in then direct them to Drupal's login page.

As far as I can tell I should be able to use /system/connect.json to get the current user, but I keep getting anonymous user and not the user currently logged into the browser.

When I retrieve the X-CSRF-Token using a REST console browser extension via /services/session/token I get the correct token for the currently logged in user .. But getting the token through the app using php\_curl I get an new token with every request.

Is it possible for me to determine if a user is logged into Drupal in the current browser via services not knowing who they are? Or am I going about this the wrong way?

# Answer
> 0 votes
I would recommend using OAuth2.0, check out OAuth 2.0, assuming Drupal 8, otherwise there's the OAuth 1.0 for Drupal 7 (or if you're not using SSL with D8 for some reason).

This is the same tech that Facebook and Google use when you want to let people log into your site/app using their 3rd party credentials, so it should be robust enough if I understood what you were asking.

---
Tags: services
---


# Question
Title: Show available languages in content-view
in older-drupal-versions when content was translated to different languages, it was possible to indicate in which other languages that content is available and in which not.

Let's say I have en, de and fr as languages. Foo is translated to en and de and bar is translated to fr only.

In my contents index (/admin/content) I want to display that linked info as:

`foo``en, de, ~~fr~~`
`bar``~~en~~, ~~de~~, fr`

Where clicking a non-striked text leads to the edit of the particular node and clicking the striked one will start a translation.

Is that, or something which gets close, possible in D8?

# Answer
@CG-monroe is correct that there isn't anything out of the box, but you can still list the language for each node, edit the content view (defaults to `/admin/structure/views/view/content`) and add `Translation language` to the fields, you can also add the `Original language` field if that is useful as well.
> 1 votes

# Answer
The content admin screen is now just a view. AFAIK there is no view widget that will do that.

It probably would be possible to write a entity specific global widget for this. Basically, you can get the list of installed languages from the language manager and then for each entity row use the getTranslations() method to find what has been translated.
> 0 votes

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


# Question
Title: Can I delete leftover field_deleted_* tables?
I have a lot of `field_deleted_*` tables in the database and neither `drush cr` or running cron is removing them. Is it okay to just remove them from the database? How can I tell Drupal to remove them otherwise?

Edit: Per 4k4 troubleshooting tip:

```
➜  default git:(HUHLR-172) ✗ drush ev "var_dump(\Drupal::state()->get('field.storage.deleted'))"
array(0) {
}

```

This means:

> If this is empty, then you can remove the tables in the database as well, because Drupal has no chance to guess the hash keys of the table names without this information.

# Answer
> 14 votes
No, this is not a good idea, because there are more things that need to be removed, not only the database tables. Deleting these tables without checking their usage first (see troubleshooting below) results in this error Cron error message. table or view not found: 1146

The deleted fields are purged by cron, but only 50 rows per run. If you want to accelerate the process, run cron more often or increase the batch size in *field.settings.yml*:

```
purge_batch_size: 50

```

Instead of cron you can run `field_purge_batch()` from the command line, then with a higher batch limit, for example 1000 or how many rows you have and are able to delete without hitting a memory/time limit:

```
drush ev "field_purge_batch(1000)"

```

---

**Troubleshooting**

If cron or the drush command has no effect, even not deleting some of the rows (if there are any more rows left in the tables), then check whether there are still field storages registered for these tables:

```
drush ev "var_dump(\Drupal::state()->get('field.storage.deleted'))"

```

If this is empty, then you can remove the tables in the database as well, because Drupal has no chance to guess the hash keys of the table names without this information.

If this is not empty, then you can use this output of the field storage definition(s) to debug this further (see comment of @MarioSteinitz).

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


# Question
Title: How do I display three months in the event calendar view?
I used calendar and views template module to create a calendar view for my Drupal 8 site, but the view returns only one month.

I want to display three months. How can I get this?

# Answer
It doesn't look like there isn't anything in the admin that will give you three months. I've implemented some similar solutions with custom calendars.

There are a few ways that you could do this. I'm not going to get to far into the code, but just describe what I've done (I don't have a multiple-month example).

Method 1) Duplicate the monthly view and alter the defaults in the contextual filter. Display these multiple blocks or feeds on a page.

Method 2) Create a custom node for displaying 3 months. Pass the contextual filter to the same view. Twig Tweak can handle passing arguments, though you may end up needing to do more preprocessing what Twig Tweak allows.
> 0 votes

---
Tags: views
---


# Question
Title: How to change (re-order) the deltas programmatically in node_presave
In a node, I have a multi-value field "field\_MV" containing 3 items

I don't think it is important, but field\_MV is of type "Entity reference revisions" and the items are paragraphs of only one type.

Each paragraph (item) have a field "field\_quantity" containing a number.

Here is my exemple:

```
$node->field_MV[0]->field_quantity->value=5 (paragraph at delta 0)
$node->field_MV[1]->field_quantity->value=3 (paragraph at delta 1)
$node->field_MV[2]->field_quantity->value=7 (paragraph at delta 2)

```

In hook\_node\_presave, I would like to loop in the paragraphs to change their delta according the the value of field\_quantity (descending)

Here is the result I would like to have:

```
$node->field_MV[0]->field_quantity->value=7 (previously paragraph delta 2)
$node->field_MV[1]->field_quantity->value=5 (previously paragraph delta 0)
$node->field_MV[2]->field_quantity->value=3 (previously paragraph delta 1)

```

My question is not how to order (I can handle this), but how to change the delta with something like:

```
$node->field_MV[0]->set("delta",1);
$node->field_MV[0]->save();

```

# Answer
> 4 votes
You would want to set the field value to an array in the order you want them. Since you are doing this inside hook\_node\_presave, you don't have to bother saving the node. It will be done for you.

Something like this should work:

```
$values = $node->get('field_mv')->getValue();

... your sorting function ...

$node->set('field_mv', $values);

```

---
Tags: 8
---


# Question
Title: The site has a mix of modules installed manually and via Composer: Can I move all to Composer?
I've inherited a Drupal 8 site where only few modules were installed via Composer; the rest was manually installed.

Is there a way to fix this, and *move* the manually installed modules to be handled by Composer?

# Answer
> 4 votes
You can just add the modules to Composer as you would normally: `composer require drupal/MODULENAME`.

You can then confirm everything is working OK by making a new copy of your site with Composer and verifying that the site loads correctly.

Potential issue: If you are looking at the list of installed modules to decide what to install, you don't necessarily need to add every module; some may be dependencies of others (for example, with Composer, if you are using Pathauto module, you don't need to install Token explicitly; it will automatically be installed with Pathauto.) However, it won't hurt anything if you force some dependencies to be installed as well, so this isn't really anything to worry about.

---
Tags: installation, composer
---


title: How to bulk update image alt and title?

text:
# Question
Title: How to bulk update image alt and title?
I have a content type with an image field. How do I update all my images to have the node title as the alt and title of the image? I don't want to edit hundreds of nodes...

Thank you. Daniel

# Answer
> 5 votes
The basic logic goes like this:

```
$nodes = entity_load('node', FALSE, array('type' => 'the_type'));

foreach ($nodes as $node) {
  $node->field_image[$node->language][0]['alt'] = $node->title;
  $node->field_image[$node->language][0]['title'] = $node->title;

  node_save($node);
}

```

You should probably split that up into a batch job if you have a lot of nodes.

I'm also pretty sure you could make a quicker solution using VBO and some custom PHP but I don't have time to flesh that out right now.

# Answer
> 1 votes
With VBO it is very easy to do. All you need is "**Execute arbitrary PHP script**" on nodes your want to add alt and title. Change field name "**field\_image**".

```
foreach ($entity->field_image[$entity->language] as $key => $value) {
  if(empty($value['alt'])) $value['alt'] = $entity->title;
  if(empty($value['title'])) $value['title'] = $entity->title;
  $entity->field_image[$entity->language][$key] = $value;
}
node_save($entity);

```

# Answer
> 1 votes
This may have been closed, but saw this while searching for the same concern. To date, Drupal 7 has two modules that might help. Hope this helps anyone searching for same requirement.

---
Tags: nodes, media, batch-operations
---


# Question
Title: How to save custom theme settings in a subtheme?
I've created a subtheme of the Premium Responsive theme. It was working fine until I tried to change some of the advanced theme settings within the subtheme's *Appearance* page. The parent theme adds settings for configuring social icons, a slideshow, etc., but unchecking some of the custom options and submiting the form resulted in a message saying "The configuration options have been saved", but the settings were returned to checked.

At first, I thought I needed to copy the theme-settings.php to my subtheme and customize it, but that results in two sets of settings displaying on the *Appearance* page, one for the parent theme and one for the subtheme (plus, still neither set of settings would stay unchecked when I submitted the form). This seems odd, since the Creating a sub-theme documentation, says "Theme settings set via advanced theme settings' theme-settings.php are not inherited."

So, how am I supposed to set custom theme settings within a subtheme? Do I need to implement a theme-settings.php file within the subtheme or not?

# Answer
I ran into the same issue. After doing an analysis I found the following:

1. THEME\_form\_system\_theme\_settings\_alter is called for the base theme and then for the sub theme. It's not really a hook as they say - "Implements hook\_form\_FORM\_ID\_alter().".
2. The base theme uses things like theme\_get\_setting('asdf\_asdf', 'responsive') to get the default values for the settings form.
3. The settings you're saving are saved for the sub theme.
4. In templates settings are returned also using theme\_get\_setting('asdf\_asdf', 'responsive').

Because of #2 and #3 the settings appear to not be saved.

Maybe they should have used theme\_get\_setting('asdf\_asdf'). So it will default to the current theme. It can be used in both cases: #2 and #4. It would have worked fine.

For the sake of not altering the theme and because of #4, I would remove the extra settings in SUB\_THEME\_form\_system\_theme\_settings\_alter so you can modify the settings only in the base theme configuration page.
> 2 votes

# Answer
You can also use the module magic although it's not always exporting the correct code. In any case it provides a fast solution.
> 0 votes

# Answer
you can set your current theme variable set as parent theme variable

```
$theme_subtheme_settings = variable_get('theme_subtheme_settings', array());
if(empty($theme_oswsubtheme_settings)){
    $theme_parent_settings = variable_get('theme_parent_settings', array());
    variable_set('theme_subtheme_settings', $theme_parent_settings);
  }

```
> 0 votes

---
Tags: 7
---


# Question
Title: How to change menu item URL in menus for Drupal 7 multiiste
I am using drupal 7 multisite (sharing the same database, same code base) i.e

1) **one.example.com**

2) **two.example.com**

Everything is working correctly and my site using the same menus for all the sites.

for primary domain, menus are working correctly like there is one menu item named as **test** and published to both the sites but If I access the first site i.e **one.example.com** then my menu URL is **one.example.com/test**

and same when I access the secondary domain i.e. **two.example.com** then my menu URL should be **two.example.com/test** instead of **one.example.com/test** and currently, menu URL is **one.example.com/test**

# Answer
> 0 votes
I got solution to my question The node URL is not updated in the menu so its taking primary site URL after updating URL it is working fine.

Just edit all the nodes and save as it is all the URL of menus will automatically be updated. And in menu items, it will automatically consider current working site URL

# Answer
> 0 votes
Try to add menu links as "*Relative Paths*", then a domain name will be added automatically depends on sites.

E.g. use `/test` , not `one.example.com/test`.

---
Tags: navigation
---


# Question
Title: How do I strip HTML markup or use plain text in the body field?
I am using a view to create a block that display a set of data. The data appears as expected, but it shows HTML markup between body fields, which I want to strip or render as they are like in nodes. I am using hook\_views\_pre\_render(), but I am not able to strip HTML markup with that.

How can I achieve this? Is there any view settings for removing HTML markup?

# Answer
I was using Aggregation (Group Results Together) which caused body field to print the unrendered HTML which is fixed by checking the **Format** option in additional fields to true.
> 3 votes

# Answer
If you are using fields in the View, just click on the body field in the View configuration and check “Strip HTML tags”. I believe that’s the name of the option. You don’t need code for that.
> 0 votes

# Answer
Use the strip HTML tags option in rewrite results
> 0 votes

---
Tags: views, 8
---


title: Send mails in an asynchronous process

text:
# Question
Title: Send mails in an asynchronous process
I'm using `drupal_mail()` to send mails from the HTML formatted content.

It takes more time to send mails. Actually, Mail is triggered while the form submission after the save logic.

To save the page loading time, how can I send emails in an asynchronous process?

# Answer
As far as a pre-built solution goes, you can try the Background process module, which would theoretically allow you to do something like:

```
$handle = background_process_start('drupal_mail', $module, $key, $to, ...);

```

Beyond that Drupal has nothing to help, so If you don’t use that module, just approach this as a general PHP task. The options and difficulties for async/background processing in PHP are very well documented around the web.
> 1 votes

---
Tags: 7, emails
---


# Question
Title: Command entity-updates needs a higher bootstrap level to run
I am trying to make drush work on Debian 8 with Drupal 8.

Unluckily, executing `drush entity-updates` returns the following error messages:

> Command entity-updates needs a higher bootstrap level to run - you will need to invoke drush from a more functional Drupal environment to run this command.
> Command entity-updates requires Drupal core version 8+ to run.
> The drush command 'entity-updates' could not be executed.

`drush -vd status` executed from `.../sites/default` returns the following:

```
.../sites/default# drush -vd status
Starting Drush preflight. [0.04 sec, 2.09 MB]                        [preflight]
Loading drushrc "/etc/drush/drushrc.php" into "system" scope. [0.04  [bootstrap]
sec, 2.09 MB]
Cache MISS cid: 7.1.0-commandfiles-0-81cc86c1995ab7206f383ec28ad43baf    [debug]
[0.09 sec, 2.14 MB]
Cache SET cid: 7.1.0-commandfiles-0-81cc86c1995ab7206f383ec28ad43baf     [debug]
[0.12 sec, 2.16 MB]
Bootstrap to phase 0. [0.53 sec, 6.04 MB]                            [bootstrap]
Found command: core-status (commandfile=core) [0.54 sec, 6.05 MB]    [bootstrap]
Loading outputformat engine. [0.54 sec, 6.06 MB]                        [notice]
Calling hook drush_core_status [0.55 sec, 6.11 MB]                       [debug]
Returned from hook drush_core_status [0.55 sec, 6.11 MB]                 [debug]
 PHP executable         :  /usr/bin/php
 PHP configuration      :  /etc/php5/cli/php.ini
 PHP OS                 :  Linux
 Drush script           :  /root/.composer/vendor/drush/drush/drush.php
 Drush version          :  7.1.0
 Drush temp directory   :  /tmp
 Drush configuration    :  /etc/drush/drushrc.php
 Drush alias files      :

Command dispatch complete [0.63 sec, 6.25 MB]                           [notice]

```

Running `drush sqlc` executed from `.../sites/default` results in:

```
Unable to load class Drush\Sql\Sql                                   [error]
exception 'Drush\Sql\SqlException' with message 'Unable to find a    [error]
matching SQL Class. Drush cannot find your database connection
details.' in
/root/.composer/vendor/drush/drush/commands/sql/sql.drush.inc:597
Stack trace:
#0
/root/.composer/vendor/drush/drush/commands/sql/sql.drush.inc(454):
drush_sql_get_class()
#1 [internal function]: drush_sql_cli()
#2 /root/.composer/vendor/drush/drush/includes/command.inc(359):
call_user_func_array('drush_sql_cli', Array)
#3 /root/.composer/vendor/drush/drush/includes/command.inc(210):
_drush_invoke_hooks(Array, Array)
#4 [internal function]: drush_command()
#5 /root/.composer/vendor/drush/drush/includes/command.inc(178):
call_user_func_array('drush_command', Array)
#6
/root/.composer/vendor/drush/drush/lib/Drush/Boot/BaseBoot.php(62):
drush_dispatch(Array)
#7 /root/.composer/vendor/drush/drush/drush.php(70):
Drush\Boot\BaseBoot->bootstrap_and_dispatch()
#8 /root/.composer/vendor/drush/drush/drush.php(11): drush_main()
#9 {main}

```

I have read other topics but none of the solutions seems work.

I have installed Drush according to instructions provided here How to install drush 8 properly on Debian 8?.

# Answer
Same problem here.

In my case I discovered that drush uses native mysql commands, not php lib. Then I've installed by

> apt-get install mysql-client

and works great.

For windows users, I think must install mysql cli commands here.
> 0 votes

---
Tags: drush, 8
---


# Question
Title: Is it possible to create a rule on the event "after saving an existing block"?
The reason of such a rule would be that there is just one block a certain user can edit. And when he does so, after saving he is redirected to the blocks management page, which he has not the permission to see and manage. So I wish there would be a rule that allows to redirect "after saving an existing block" (combined with a condition of a certain user) to some other page.

I can't find any information about it in the documentation.

# Answer
> 1 votes
How is the user getting to the edit block screen? If its via contextual links then that should already be taking you can to the page you were on?

Or do you provide them the link to end the block? If so you could use the destination parameter to redirect then automatically (Same as what contextual links do) e.g.:

/admin/structure/block/manage/block/1/configure?destination=MYPAGETHEYSHOULDGOBACK

---
Tags: 7, blocks, rules
---


# Question
Title: How do I create a sticky navigation bar in Open Social?
I'm using D8 and working on new theme in Open Social witch uses bootstrap/sass. In my theme I want the navigation bar (in the header region) to be sticky at the top of the screen. I've made some javascript/sass code but I can't get it to work. This is what I have done so far:

Created a new javascript function in the theme\_name.js file:

```
    //-- Sticky Header
    (function($) {
        Drupal.behaviors.navbar = {
            attach: function (context, settings) {

                var nbar = $('.header');

                if (nbar.length) {
                    var elmHeight = $('.header-top').outerHeight(true);
                    $(window).scroll(function() {

                        var scrolltop = $(window).scrollTop();
                        if (scrolltop > elmHeight) {
                            if (!nbar.hasClass('sticky')) {
                                nbar.addClass('sticky');
                            }

                        } else {
                            nbar.removeClass('sticky');
                        }
                    });
                }
            }
        }
    })();

```

This is a code snippet from the navbar.scss file:

```
.navbar-sticky-top {
  @include z-depth-3;
  position: fixed;
  top: 0;
  left: 0;
  z-index: $zindex-navbar-sticky;
}

```

Code snippet from the index.twig file:

```
<nav class="navbar navbar-default navbar-sticky-top" id="top"
role="banner">
    <div class="container">
      <div class="navbar-header">
...

```

This is the content of the region--header.html.twig file:

```
{% if content %}
  <nav {{ attributes.addClass('navbar navbar-default navbar-sticky-top') }} role="banner">
    <div class="container">
      {{ content }}
    </div>
  </nav>
{% endif %}

```

What am I missing here?

# Answer
Seems like you're over-complicating it by re-writing things that bootstrap already does. The stock bootstrap theme and most of it's subthemes should have a setting in the theme for setting a fixed nav bar.

See Appearances -\> Theme settings -\> Components -\> Navbar. There is an option for fixed top navbar.

If that does not do what you want, there is also the Bootstrap Affix plug-in which should be part of the standard drupal bootstrap theme.

See: This W3school page for details.
> 0 votes

# Answer
I see that in the latest version of Open Social, the header bar is sticky. So maybe updating to a newer version helps you out!
> 0 votes

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


title: Document viewer for the uploaded files

text:
# Question
Title: Document viewer for the uploaded files
I had been using a module called "filebrowser" for implementing the file management system. This provides with a content type "Directory Listing" (listing all the uploaded files) through which a node can be added in which, the users can upload files, view or download them based on configuration set. I had been searching regarding a possible internal document viewer for drupal that would actually help in view

The file types like pdf or images are opened via browser when clicked but the file types like doc, excel or PPT are downloaded when clicked on it.

Much appreciate any help or guidance regarding the possibilities of such in the Drupal8 where files can be viewed using a common internal document viewer. There have been few viewer modules but they seem to be suitable for embedding documents onto a page.

So far, I had been thinking of an approach where clicking on the files would actually convert them to the pdf format and viewed via browser, Being a newbie to the drupal, having a challenge in planning an approach to get this done. I believe I may have to develop a custom module integrating with the code of filebrowser module.

# Answer
> 0 votes
Your browser is natively handling those document types, i.e. most browsers can view a pdf or an image in the browser, but the other file types can't be viewed so they're downloaded.

You're on the right track with converting them to PDF or jpg for browser viewing, you might want to have an option for people to download the native file as well.

Google does something similar to this when they let you preview documents uploaded to Drive. I think that a custom module utilizing ImageMagick would be the way to go, there are some examples out there for Drupal 7, including PDFPreview (pdf to jpg), and I found this ImageMagick module that's ready for Drupal 8 that could give you a head start.

---
Tags: files
---


# Question
Title: How to create a custom display mode for user in D8?
I've created an edito custom content type wich can be linked to a user. I'd like to custom the display with the picture and the name of the user in a view. I don't know how to create a custom display mode for an user.

Any help ?²

# Answer
> 1 votes
You need to create the view mode at Admin \> Structure \> Display Modes, then configure the new display mode at `/admin/config/people/accounts/display`.

---
Tags: views, users
---


# Question
Title: Custom file uploads seem impossible from a POST request?
**Why are $\_Files and/or HTTPFoundation\FileBag invalid in custom module Controller?**

I have noticed a very strange issue with accessing an individual file from the `$_FILES` object or the Symfony derived `\Symfony\Component\HTTPFoundation\FileBag` from within a custom module controller.

The exact location of the issue seems to be in `Symfony\Component\HttpKernel\HttpKernel` -\> `handleRaw`

Specifically, the file exists prior dispatching the `KernelEvent::REQUEST` but it does not after.

```
// request
$event = new GetResponseEvent($this, $request, $type);

// THE FILE EXISTS HERE
// file_exists( $request->files->get(0)->getRealPath()) == TRUE

$this->dispatcher->dispatch(KernelEvents::REQUEST, $event);

// THE FILE DOES NOT EXISTS HERE
// file_exists( $request->files->get(0)->getRealPath()) == FALSE

```

---

Here is the entire method for reference also including some code to move the file, which works as expected as long as it is before the event dispatch.

```
  /**
 * Handles a request to convert it to a response.
 *
 * Exceptions are not caught.
 *
 * @param Request $request A Request instance
 * @param int     $type    The type of the request (one of HttpKernelInterface::MASTER_REQUEST or HttpKernelInterface::SUB_REQUEST)
 *
 * @return Response A Response instance
 *
 * @throws \LogicException       If one of the listener does not behave as expected
 * @throws NotFoundHttpException When controller cannot be found
 */
private function handleRaw(Request $request, $type = self::MASTER_REQUEST)
{
    $this->requestStack->push($request);

    $directory = \Drupal::service('file_system')->realpath(file_default_scheme() . "://");

    /* @var \Symfony\Component\HttpFoundation\File\UploadedFile $uploadedFile*/
    $uploadedFile = $request->files->get(0);

    if (is_uploaded_file($uploadedFile->getRealPath())){
      $success = $uploadedFile->move($directory);
    }

  // request
    $event = new GetResponseEvent($this, $request, $type);
    $this->dispatcher->dispatch(KernelEvents::REQUEST, $event);

    if ($event->hasResponse()) {
        return $this->filterResponse($event->getResponse(), $request, $type);
    }

    // load controller
    if (false === $controller = $this->resolver->getController($request)) {
        throw new NotFoundHttpException(sprintf('Unable to find the controller for path "%s". The route is wrongly configured.', $request->getPathInfo()));
    }

    $event = new FilterControllerEvent($this, $controller, $request, $type);
    $this->dispatcher->dispatch(KernelEvents::CONTROLLER, $event);
    $controller = $event->getController();

    // controller arguments
    $arguments = $this->argumentResolver->getArguments($request, $controller);

    $event = new FilterControllerArgumentsEvent($this, $controller, $arguments, $request, $type);
    $this->dispatcher->dispatch(KernelEvents::CONTROLLER_ARGUMENTS, $event);
    $controller = $event->getController();
    $arguments = $event->getArguments();

    // call controller
    $response = call_user_func_array($controller, $arguments);

    // view
    if (!$response instanceof Response) {
        $event = new GetResponseForControllerResultEvent($this, $request, $type, $response);
        $this->dispatcher->dispatch(KernelEvents::VIEW, $event);

        if ($event->hasResponse()) {
            $response = $event->getResponse();
        }

        if (!$response instanceof Response) {
            $msg = sprintf('The controller must return a response (%s given).', $this->varToString($response));

            // the user may have forgotten to return something
            if (null === $response) {
                $msg .= ' Did you forget to add a return statement somewhere in your controller?';
            }
            throw new \LogicException($msg);
        }
    }

    return $this->filterResponse($response, $request, $type);
}

```

I am trying to write a custom `GraphQL module` mutation plugin that handles file uploads and unless I can get access to the file object from the POST request, I don't think this will be possible.

Any thoughts are greatly appreciated.

I believe this may be a core issue or an upstream issue with Symfony or at the very least a side effect of the assumptions of how new requests are created.

https://www.drupal.org/project/drupal/issues/2934486#comment-12406531

# Answer
Update: this has been addressed upstream here https://github.com/symfony/psr-http-message-bridge/issues/39#issuecomment-558306949

There is an issue when a Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory request is created from anywhere. If there are any POST $\_FILES (File object) on that request, they are renamed and moved to the tmp directory with a new name. This new name is not propagated on the original request.

During this process of creating the new psr7 request, any temporary files are moved and renamed in the temporary folder.

The `tmp_name` values starts as something like: /private/var/tmp/phpEHH19a and then on line 102 of the HTTPFoundationFactory, the file is moved and renamed to something like:

`symfony5a4e551619af73.65717941BYwCkd`

This renaming flow happens like this

HttpFoundationFactory-\>createRequest() -\> getFiles --\> createUploadFiles and this line 102 of HTTPFoundationFactory

$psrUploadedFile-\>moveTo($temporaryPath); causes the file to be renamed.

This type of request can happen in a number of places, but definitely in a decoupled app, especially during authentication. For example with the simple\_oauth module when updating the tokens. This new request is never passed along and the original request still retains the original `tmp_name` file paths.

Once you finally get access to the request object in a module controller via \Symfony\Component\HttpFoundation\Request

and check all the files via: $request-\>files-\>all();

The Symfony\Component\HttpFoundation\File\UploadedFile Object contains the original file path.

This is a major problem that needs to be overcome in order to handle multipart/form-data with decoupled javascript file uploads. I noticed the issue when working on a custom graphql module to handle file uploads.

Here is the path you can use to trace through the issue: The SimpleOauthAuthenticationProvider calls validateAuthenticatedRequest($request) which creates a new psr7 request (see above). During this process, the files are moved and the new request does not include the updated request files object.

I think this is a bug upstream with Symfony or it's a bug with how files are handled with sub requests or maybe it's a bug with how simple\_oauth handles getting the new tokens. I don't think it's a simple\_oauth bug though because it's just making a request and there is a side effect of the temporary files being moved.

See the screenshot below. The $request variable is created and the tokens are reset. As a result of the new request, the temporary files are moved and renamed. The screenshot shows the new spl filepaths but this request dies in this method and the files do not get updated on the original request object. If you look at the watched variables on the right you can see that the file at the original tmp\_name path no longer exists.
> 0 votes

---
Tags: 8
---


# Question
Title: How to access node properties of another node using the Rules Link module?
I wonder how to access node properties via another node with Rules. I already store the link of my other node in a field (of the original node), but I don't know if we can do that.

I'm using the Drupal Commerce 7.x, Rules Link, and Content Access modules.

Here is what I want to do: after a candidate (a particular user) clicks on a rules link in a 1st node, I want to grant access for that candidate to a 2nd node and do a redirection to that 2nd node.

Here is what I currently do and how it works : When an **Advertiser** creates a node of type "`classified ad`" i use a rule to do 2 things:

1. Store the url of the primary node in one of the node's fields.
2. Clone that node and convert it in another content type (= "`classified complete`").

Then with Content Access I block the access for all users except the **author** (in this case the **Advertiser**), administrator and super users.

When a candidate clicks on the link in the 1st node (with content type "`classified ad`"), the candidate spends 100 credits (using the Userpoints module). Next I need to grant the candidate access to the 2nd node (with content type "`classified complete`"), followed by a page redirect to that 2nd node.

a) My Rules Link export :

```
{
  "settings" : {
    "text" : "Access to contact informations",
    "link_type" : "confirm",
    "bundles" : { "classified" : "classified" },
    "entity_link" : 1,
    "view_mode" : { "full" : "full" },
    "confirm_question" : "spend credits",
    "confirm_description" : "Would you like to spend 100 credits to access contacts informations ?"
  },
  "name" : "access_to_contact_info_links",
  "label" : "authenticated user Link contact infos ",
  "path" : "access_to_contact_info_links",
  "entity_type" : "node",
  "rdf_mapping" : []
}

```

b) Rules Link Access condition (don't know how to export that) : I use a "user has role" condition and I check if the user is authenticated

c) Rules Link Reaction rule:

```
{ "rules_link_set_access_to_contact_info_links" : {
    "LABEL" : "Rules link: Access to contact info links rules set",
    "PLUGIN" : "rule set",
    "OWNER" : "rules",
    "REQUIRES" : [
      "rules",
      "userpoints_rules",
      "rules_conditional",
      "rules_i18n",
      "content_access_rules"
    ],
    "USES VARIABLES" : { "node" : { "label" : "node", "type" : "node" } },
    "RULES" : [
      { "RULE" : {
          "PROVIDE" : { "loaded_points" : { "loaded_points" : "Number of credit in the specified category." } },
          "IF" : [
            { "user_has_role" : {
                "account" : [ "site:current-user" ],
                "roles" : { "value" : { "2" : "2" } }
              }
            }
          ],
          "DO" : [
            { "userpoints_rules_get_current_points" : {
                "USING" : { "user" : [ "site:current-user" ], "tid" : "86" },
                "PROVIDE" : { "loaded_points" : { "loaded_points" : "Number of credit in the specified category." } }
              }
            },
            { "CONDITIONAL" : [
                {
                  "IF" : { "data_is" : { "data" : [ "loaded-points" ], "op" : "\u003C", "value" : "100" } },
                  "DO" : [
                    { "drupal_message" : { "message" : "You don\u0027t have enough credits !", "type" : "error" } }
                  ]
                },
                { "ELSE" : [
                    { "userpoints_action_grant_points" : {
                        "user" : [ "site:current-user" ],
                        "points" : "-100",
                        "tid" : "86",
                        "entity" : [ "" ],
                        "operation" : "Remove",
                        "display" : "1",
                        "moderate" : "approved"
                      }
                    },
                    { "CONDITIONAL" : [
                        {
                          "IF" : { "node_is_of_type" : {
                              "node" : [ "node" ],
                              "type" : { "value" : { "classified_complete" : "classified_complete" } }
                            }
                          },
                          "DO" : [
                            { "CONDITIONAL" : [
                                {
                                  "IF" : { "entity_has_field" : { "entity" : [ "node" ], "field" : "field_link_to_unlocked_content_t" } },
                                  "DO" : [
                                    { "drupal_message" : { "message" : "Trying to grant access !" } },
                                    { "content_access_action_user_grant" : {
                                        "node" : [ "node" ],
                                        "content_access_user_view" : [ "site:current-user" ],
                                        "content_access_user_update" : [ "" ],
                                        "content_access_user_delete" : [ "" ]
                                      }
                                    },
                                    { "redirect" : { "url" : "[node:field-link-to-unlocked-content-t]", "destination" : "1" } }
                                  ]
                                }
                              ]
                            }
                          ]
                        }
                      ]
                    }
                  ]
                }
              ]
            }
          ],
          "LABEL" : "Enough Credits"
        }
      }
    ]
  }
}

```

\**

Is it possible ?

# Answer
This is (was) quite a challenging question, for a number of reasons:

* It's impossible to import your rule(s), and not only if you don't have the content types defined like in your case: you need the ACL module to have the Rules Action with machine name `content_access_action_user_grant` available (without that the import will fail). Moreover, the ACL module seems to be a weak module dependency of the Content Access module. So if ACL is NOT enabled, then trying to import your rule will fail.
* For unknown (to me) reasons, your exported rule claims to have a dependency (cfr the "requires") related to the `rules_i18n` module. However, there is nothing in your rules that actually uses it. So I just removed that line prior to trying to import your rule in my environment.
* Your naming conventions of your rules variables are pretty challenging: everything is called ... "node" ... that's asking for getting confused (since you have 2 different content types involved ...).

Anyway, have a look at this simplified (I think) Rules Component that replaces the "reaction"-rules (item "c)" in your question, with machine name `rules_link_set_access_to_contact_info_links`):

```
{ "rules_link_set_access_to_contact_info_links" : {
    "LABEL" : "Rules link: Access to contact info links rules set",
    "PLUGIN" : "rule set",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "userpoints_rules", "rules_conditional" ],
    "USES VARIABLES" : { "node" : { "label" : "node", "type" : "node" } },
    "RULES" : [
      { "RULE" : {
          "PROVIDE" : { "loaded_points" : { "loaded_points" : "Number of credit in the specified category." } },
          "IF" : [
            { "user_has_role" : {
                "account" : [ "site:current-user" ],
                "roles" : { "value" : { "2" : "2" } }
              }
            }
          ],
          "DO" : [
            { "userpoints_rules_get_current_points" : {
                "USING" : { "user" : [ "site:current-user" ], "tid" : "86" },
                "PROVIDE" : { "loaded_points" : { "loaded_points" : "Number of credit in the specified category." } }
              }
            },
            { "CONDITIONAL" : [
                {
                  "IF" : { "data_is" : { "data" : [ "loaded-points" ], "op" : "\u003C", "value" : "100" } },
                  "DO" : [
                    { "drupal_message" : { "message" : "You don\u0027t have enough credits !", "type" : "error" } }
                  ]
                },
                { "ELSE" : [
                    { "userpoints_action_grant_points" : {
                        "user" : [ "site:current-user" ],
                        "points" : "-100",
                        "tid" : "86",
                        "entity" : [ "" ],
                        "operation" : "Remove",
                        "display" : "1",
                        "moderate" : "approved"
                      }
                    },
                    { "component_rules_grant_access_to_a_node" : { "node_containing_classified_ad" : [ "node" ] } }
                  ]
                }
              ]
            }
          ],
          "LABEL" : "Reduce points and grant access"
        }
      }
    ]
  }
}

```

Apart from the label (which I changed from "*Enough Credits*" to "*Reduce points and grant access*"), the only difference with your original rules set, is that all Rules Actions after the Rules Action to deduct userpoints, have been replaced by an additional (new) Rules Component named `rules_grant_access_to_a_node`. And here is how that Rules Component looks like:

```
{ "rules_grant_access_to_a_node" : {
    "LABEL" : "Grant access to a node",
    "PLUGIN" : "rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "content_access_rules" ],
    "USES VARIABLES" : { "node_containing_classified_ad" : { "label" : "Node containing classified ad", "type" : "node" } },
    "IF" : [
      { "node_is_of_type" : {
          "node" : [ "node-containing-classified-ad" ],
          "type" : { "value" : { "article" : "article" } }
        }
      }
    ],
    "DO" : [
      { "entity_fetch" : {
          "USING" : {
            "type" : "node",
            "id" : [ "node-containing-classified-ad:field-free-format-nr" ]
          },
          "PROVIDE" : { "entity_fetched" : { "fetched_classified_complete" : "Fetched classified complete" } }
        }
      },
      { "drupal_message" : { "message" : "Trying to grant access to node with Id = [fetched-classified-complete:field_free_format_nr]" } },
      { "content_access_action_user_grant" : {
          "node" : [ "fetched-classified-complete" ],
          "content_access_user_view" : [ "site:current-user" ],
          "content_access_user_update" : [ "" ],
          "content_access_user_delete" : [ "" ]
        }
      },
      { "redirect" : { "url" : [ "fetched-classified-complete:url" ] } }
    ]
  }
}

```

You should be able to import this Rules Component in your own site also, though you'll have to apply these corrections prior to importing:

* replace machine name `article` by `classified` (assuming that's the content type for your "Classified Ad").
* the `field-free-format-nr` (name it whatever you want) is an integer field defined for your "Classified ad", which contains (only!) the node Id for which you want to grant access (which relates to your "classified complete" content type). So as per your extra comment (= "*...yes i can take the id instead of the url...*") you'll need to slightly adapt the design of your content type.

Note these (way more?) meaningful variables I used (instead of just "`node`"):

* `node_containing_classified_ad`
* `fetched_classified_complete`

Some more details about this Rules Component:

* Rules Condition: check the type of the node used as parameter. That will give us access (in the Rules Actions following them) to the crucial field `field-free-format-nr`.
* Rules Actions:
    + Fetch entity by ID (i.e. a node) with ID indicated in `node-containing-classified-ad:field-free-format-nr`, and give it a name like `fetched_classified_complete` (see the importance of naming conventions for parameters!?!?!?).
    + Continue with the 3 Rules Actions similar to what is included in your question (but with a meaningful name like `fetched_classified_complete`). Note the adapted token in the redirect action also.

***Voilà*** ...
> 1 votes

---
Tags: 7, nodes, rules, users
---


title: Override core Js file

text:
# Question
Title: Override core Js file
Working on my theme

I need to override a core Js file ..\core\modules\contextual\js\contextual.js

My code from theme.info

```
libraries-override:
  contextual/drupal.contextual-links:
    js:
      js/contextual.js: js/override/contextual.js

```

The problem is that the loading order of this component js files did change after the override which cause script errors :

So how can override file js core and still same order file?

# Answer
Thanks can be done with with the hook\_js\_alter function

```
    function hook_js_alter(&$javascript) {
    $javascript['js/contextual.js']['data'] = drupal_get_path('theme', 'THEMENAME') . 'js/override/contextual.js';
    }

```
> 2 votes

# Answer
This is a solution I've applied to override a base theme js Library by overriden js Library in custom theme: Two files are concerned:

* custom\_theme.libraries.yml
* custom\_theme.info.yml

**In .libraries.yml file :**

```
mycontextextual.links:
  js:
    js/override/contextual.js: {}

```

**In .info.yml file:**

```
libraries-override:
  contextual/drupal.contextual-links: custom_theme/mycontextual.links

```

I hope it will help.
> 2 votes

---
Tags: 8, theming
---


# Question
Title: How to find which module is causing PHP warning
In the Recent log messages I get this message repeated many times:

> Warning: array\_flip(): Can only flip STRING and INTEGER values! i DrupalDefaultEntityController-\>cacheGet() (rad 388 av C:\wamp\www\includes\entity.inc).

I assume that the problem lies within one of the modules I have installed, but after spending the whole day trying to narrow down which module is causing the problem, without luck, I post this question. I have read other answers that relates to the same log message, but they did not help me.

Anyone that can explain how to get more info out of that warning?

# Answer
> 1 votes
Best way is probably to use a debugguer like xdebug and watch the callstack in your IDE before your warning.

If you cannot, use debug\_print\_backtrace() or debug\_backtrace(), locate your warning and you will see all the calls before it happens.

Here is an exemple you have to adapt (or not) : set\_error\_handler()

# Answer
> 1 votes
We always prefer to use drush and view the watchdog from the command line using:

```
drush watchdog-show --tail

```

`watchdog-show` gives the latest log messages.

`--tail` gives you a 'live look' at any log messages.

# Answer
> 0 votes
> I haven't used Xdebug but I will try to get it to work in my environment (WAMP and Atom). My problem is that the warning can originate from any of about 30 modules, so I need to pin down the faulty module before I can print and die

Another approach is like so:

1. Disable ALL 30 modules
2. Re-enable each of those 30 modules, 1 at a time.
3. Try to recreate the issue each time you re-enabled 1 of those modules.
4. At some point the issue will come back ... the last module you re-enabled is the module you were looking for ...
5. To ensure there are no other (extra) modules that cause the issue, temporary disable that module again, and continue with the remaining modules. When you're done, re-enable the module discovered in step 4.

# Answer
> 0 votes
Latest patch for adding backtrace to errors in core: https://www.drupal.org/project/drupal/issues/1158322#comment-12405373

This is a must for any Drupal install; very handy.

---
Tags: 7, entities, debugging
---


title: Webform email themeing

text:
# Question
Title: Webform email themeing
How do I theme emails sent via a Webform to display like the webform preview?

Below is the output from the email, viewed in Gmail and below that is the output from the preview of the form.

I am using Drupal Version 8.4.3
Webform Version: 8.x-5.0-rc1, with all modules enabled.
Mail System: Version: 8.x-4.1.
Other modules include:
Ctools
Pathauto
Token
Twig tweak
Honeypot
Imce File Manager

This is the output of the email from Gmail

And this the preview of the message in the form.

# Answer
> 1 votes
The styling of an element is handled via the webform-element-base-html.html.twig template. The email formatting is using simple HTML markup vs Drupal's standard form element/item output.

If you globally want the layout of all elements to be on a single line in email. You should change...

```
{% if title %}<b>{{ title }}</b><br />{% endif %}{{ value }}<br /><br />

```

to

```
{% if title %}<b>{{ title }}</b> {% endif %}{{ value }}<br /><br />

```

---
Tags: theming, webforms, emails
---


title: Add custom HTML into my view

text:
# Question
Title: Add custom HTML into my view
so I have a content-type `X` and a view which gets all nodes of this type. In the view I get all the fields I want and display all items in a list. I'd now like to have social sharing buttons. All modules which do that are just enabling it for the display of the content-type, I can't use it as a field itself.

So I though about just creating my own little HTML for my sharing buttons and just implement it somehow as a field, so I can place and style it like I want. \[Wheras a module might bebetter but I just can't wrap my head around how to display it outside of the node's display\]

So, can someone tell me how I can achieve that?

# Answer
I would advice you to use a node display instead of fields. So first create a new node-display (if you want to use anything else then node teaser), set the fields display correctly, and create a template file.

Then alter your view so it takes the node-display instead of fields.
> 0 votes

---
Tags: theming
---


# Question
Title: How to create a rule which after several updates in 5 minutes of a node sends 1 message?
When a node is being updated I have a trigger for this in the rules engine. I want a notification of this in the email.

The node is however updated several times in 5 minutes.

I only need 1 notification of this.

I first had the idea to compare the node:changedate with site:current-time with 300 seconds diff in a php rule, but then all email is not send as the first email is also within the 300 seconds.

Any suggestion how to solve this?

# Answer
> 3 votes
Assuming your question is about D7, and that you can think of creating a view for such updated content for (say) "the last 5 mins", there is a solution to do what you're asking about. This solution uses the Rules, Views and Views Rules module, as further detailed below.

### 1. About the Views Rules module

The Views Rules module makes Views data available in Rules, enabling intuitive rule configuration for dynamic data. Some details from its project page:

> ... provides two types of elements in Rules, configured with a "Rules" view display:
>
> * **Views loop**: A views loop is similar to a regular Rules loop, but allows looping over rows of view results.
> * **Collect view result rows (action)**: This action collects each variable in all view result rows into list variables for use in Rules.
>
> ***Tip***: When selecting the data type for variables in the view, if the field is an entity identifier (e.g. Node ID), you can set the data type to the entity type (i.e. Node) to directly use the variable in Rules as an entity!

### 2. Create a view of display type 'Rules'

After you enable the Views Rules module, use Views to create a view of your "*updated content for (say) the last 5 mins*" (as in your question). Add of view of display type ***`Rules`*** (important, that's the key to make it work!). Here is how you can add such display:

Next configure the row variables, by using the link that says "edit field info", as shown here:

### 3. Create a Rule Component using the view of display type 'Rules'

Create a Rules Component, using these guidelines:

* Add whatever Rules Conditions you might want (if any).
* Some Rules Actions you'll need to create (add) for sure:
    + **`Create a variable`**, with no initial value, say you name it "eMail Summary" (machine name `email_summary`), which will be used in subsequent Rules Actions.
    + **`Add a Views loop`** (by using the link that says `Add view loop`), and select the "Rules" display created in the previous step. Configure the parameters and variable names. And for each views result contained in your Views loop (about some "flagged content / user", as in your question), perform a Rules Action like **`Set a data value`**, for the `email_summary` variable from the previous Rules Action. The actual value to be assigned, is the previous value of `email_summary`, to which you append the desired data about the Views result being processed. For this you can use the variables you configured at the end of the previous step (you may have to revisit the previous step to add more similar variables there if needed).
    + Add a Rules Action to **`Send an eMail to a selected role`** (as per your "periodic summary email that gets sent to a specific role"), whereas for the body of that eMail you simply use the value of the `email_summary` variable.

If you're not familiar enough with Rules to create and populate that `email_summary` variable, you may want to have a look at the Rules example included in my answer to "How to concatenate all token values of a list in a single field within a Rules loop?", in which a similar variable is used.

Try to execute your Rules Component "manually" (just to test), to unit-test if it works as desired. To do so, use the "execute" link to the right of the Rules Component (in the Rules UI).

### 4. Schedule the Rules Component for periodic execution

Make sure you have the "Rules scheduler" enabled (a sub-module of Rules).

Improve your Rules Component from the previous step, by adding a Rules Action (as the last action to be performed) to **`Schedule a Rules Component`**, whereas the actual Rules Component to be scheduled is the Rules Component itself. You want it to be scheduled in "5 mins from now" (to make it happen every 5 mins).

To execute this Rules Component the very first time, just execute your Rules Component "manually". To do so, use the "execute" link to the right of the Rules Component (in the Rules UI).

Assuming your QA-testing succeeded, and assuming your cron jobs are running also, the eMail should get created next time cron runs (after an amount of time, depending on the amount of time you configured in your Rules Component to get it rescheduled).

# Answer
> 1 votes
I think is easier of use custom code. If you don't care who edited the node and just want the email when a node is edited several times in 5 minutes (by the same or different users) you can:

* Add a number field to nodes, defaulted to 0, removed from normal node edit and view.
* Add a node presave hook (this is your custom code) that: if last edit date is less than 5 minutes add 1 to this field, else set it to 0.
* Then you can set the Rule checking that field, or send th email directly from code.

May be you can avoid custom code using a rUle that adds 1 to that field, but I'm not sure if you can do it with Rules easily.

---
Tags: 7, rules
---


# Question
Title: Multilingual pages links showing node instead of URL alias
My web has 2 languages, English and Malay. The language selection is by session of `?lang=en` or `?lang=ms`.

English is the default language and it is working fine. All internal links are using the correct URL aliases. The problem arises when switching to Malay language. All links became node/(some-number).

For example: About Us Page all using about-us as URL Alias

In English www.example.com/about-us

In Malay www.example.com/node/2

Even when I type out the URL `www.example.com/about-us?lang=ms` it doesn't work. It will still show the English language.

# Answer
> 0 votes
Add translation in Malay language for about-us node and add alias to it. When node hasn't translation to Malay language, it will be without alias when You change lng

---
Tags: 7, path-aliases, uri
---


title: Exporting large data using cron

text:
# Question
Title: Exporting large data using cron
I am working on a website which has around 150k users. I have to create a csv file which contains the details of user (drupal fields and profile2 fields ) and export the csv to another server daily.

I have implemented by export function in a hook\_cron and in the function i do a user\_load function call and two profile2\_load\_by\_user and some other custom mysql queries.

The problem which i have is that my export\_function does not seem to terminate, it may be a timeout or a memory problem.

I have tested my function my limiting the number of users to around 1000 and it works fine.

I am wondering whether it is possible to export huge volume of data through hook\_cron.

# Answer
Why don't you do this in chunks.I mean schedule you cron using elysia\_cron or ultimate cron at every hour or something and export chunks of users at a time,flag users you exported and at every next cron run get the new ones.

One **important** thing you should have crontab set on your server,do not use drupal's default poormanscron.
> 1 votes

# Answer
I work with large data sets in the form of Webform results. To export 60k records with 30+ columns of data I had to kick the memory limit up in my .htaccess file.

```
# FILE: .htaccess
# PHP 5, Apache 1 and 2.
<IfModule mod_php5.c>
  php_value magic_quo...
  ...
  # 2013-09-30 -- These new settings have been put in place so that the data dump (download) for the webform module doesn't exceed memory limits causing it to crash. -- 512 to 1024
  php_value memory_limit 1024M
  php_value max_execution...
</IfModule>

```

you may also want to change your php\_value max\_execution\_time from 180 to something a little higher if your request is timing out.
> 1 votes

# Answer
I would suggest creating a drush command that retrieves and saves the data via batch or queue. This article may come handy which provides the following code examples:

```
function mymodule_setup_batch($start=1, $stop=100000) {
  //  ...
  //  Populate $lots_of_data from record $start to record $stop.
  //  ...

  //Break up all of our data so each process does not time out.
  $chunks = array_chunk($lots_of_data, 20);
  $operations = array();
  $count_chunks = count($chunks);

  //for every chunk, assign some method to run on that chunk of data
  foreach ($chunks as $chunk) {
    $i++;
    $operations[] = array("mymodule_method_to_work_on_a_small_part", array( $chunk ,'details'=> t('(Importing chunk @chunk  of  @count)', array('@chunk '=>$i, '@count'=>$count_chunks))));
    $operations[] = array("mymodule_another_method",array($chunk));
  }

  //put all that information into our batch array
  $batch = array(
    'operations' => $operations,
    'title' => t('Import batch'),
    'init_message' => t('Initializing'),
    'error_message' => t('An error occurred'),
    'finished' => 'mymodule_finished_method'
  );

  //Get the batch process all ready!
  batch_set($batch);
  $batch =& batch_get();

  //Because we are doing this on the back-end, we set progressive to false.
  $batch['progressive'] = FALSE;

  //Start processing the batch operations.
  drush_backend_batch_process();
}

function mymodule_method_to_work_on_a_small_part ($chunk, $operation_details, &$context) {
  //Do something to $chunk, maybe create a node?
  $context['message'] = $operation_details; //Will show what chunk we're on.
}
function mymodule_another_method($chunk, &$context) {
  //Do some more work.
  $context['message'] = t('We have done a second thing to a chunk of data');
}

function mymodule_finished_method($success, $results, $operations) {
  //Let the user know we have finished!
  print t('Finished importing!');
}

```

If you like, you can implement Drush command, e.g.

```
function mymodule_drush_command() {
  $items  = array();
  $items['myimport'] = array(
    'callback'    => 'mymodule_setup_batch',
    'description' => dt('Import'),
    'arguments'   => array(
      'start'     => "start",
      'stop'      => "stop",
    ),
  );
  return $items;
}

function mymodule_drush_help($section) {
  switch ($section) {
    case 'drush:myimport':
      return dt("import items from the Internal Database [start record] [end record].");
  }
}

```
> 0 votes

# Answer
In Drupal 8, you can use Default Content module to export users into CSV file via `drush` command which can be invoked periodically by adding into the system's crontab. It's better to approach, as having big chunk of data exports in `hook_cron`, as it's blocking the other important processing.

---

Another way is to create a View which exports users in CSV format by using Views Datasource module. Then you can enable caching, so the results are cached.

---

As the suggestion, to avoid using too many resources on processing and memory (such as a huge number of calls to `user_load`), you should implement memory caching service such as Redis or Memcached. Further more, please check: How do you improve Drupal performance?

---

If you still got the issue, use PHP profiler (such as XDebug) to find the cause of your issue.
> 0 votes

---
Tags: cron, importing-exporting
---


# Question
Title: Filter Views based on Webform Submission Data and Current User Email
I've got a webform that collects an email address. What I want to do is build a view based on that email address and the email address of the current user that is logged in. Basically, show all the webform links that the currently logged in user's email address has been submitted in the different webforms and deny access to any other webform that those don't match.

I've been able to get the email address from the submitted value, but I'm having issues getting the current user's email.

Anyone know how to do this?

Thanks!

# Answer
I was able to get this working by adding a relationship with the Webform Submission data and then under the contexual filter using that relationship and providing a default value using php code:

global $user; $user-\>mail;

Then I validated it using php code as well to prevent unauthorized access to the view.
> 0 votes

---
Tags: views, webforms
---