# Question
Title: Recommended way to clone functionality to create a site in Drupal 8
I have a Drupal 8 installation with different content types, paragraphs defined, views and taxonomy vocabularies. Ideally I wanted to be able to export some of these features and import them in another site, to deploy sites quickly without having to define them.

So first I tried with the module Features, I have followed the tutorial http://www.beaconfire-red.com/epic-stuff/how-setup-features-module-drupal-8, but this module only brings problems. I have also tried the Configuration Installer module, but also gives me problems. And also changing the uuid in the new installation and trying to import the configuration. But there are always problems and errors. So the only solution I can find is just cloning the database, but I think it's just a dirty solution.

I'm not an expert using drush, but I was wondering if it is possible in Drupal 8, to create a profile installation where you can define the content types, paragraphs and views created to reuse them. Is it possible?

Is there another way to achieve what I need? How is it possible that there is not an easier way to export just part of the functionality of a site?

# Answer
> 0 votes
There currently is no simple (UI guided/mouse click) way to export and reuse complex features. Period.

A) Features works well for simple features (e.g. a paragraph with a few basic fields), but fails quickly when adding advanced features (adding entity references, dependency on modules, image styles,....).

B) It is moderately easy to export and reuse the complete feature set into a fresh new site. See my own conclusions in a similar question: Can I safely use the same UUID on independent sites?

There is some undergoing work to make variant B better/easier using configuration installer, but currently requires a core patch. See Acquia's blog post =\> section "Solution (Drupal 8.4.x)" how to use the new (and IMHO better solution than features) to clone an entire site's feature set

# Answer
> 0 votes
If you want to just extract specific functionality, you need Features.

If you just want to clone an entire site, first you need to export the site config with drush. Then, you will need to wipe all UUIDs from config export files using a script, here is an example:

```
#!/bin/bash
FILES=/path/to/your-site/config/*
for f in $FILES
do
  echo "Processing $f file..."
  sed -i '' '/^uuid:/d' $f
done

```

From here, you can install a brand new Drupal 8 site, and then drop the config in and do a `drush cmi` to overwrite the entire config state to the one you exported.

I've used this method a few times to clone *entire* sites. You don't need to copy the database, in fact I would strongly advise against this.

If you wanted to make an install profile, you could do that too, and one route to doing that is to put your feature modules in a profile, include them as dependencies in the profile info file, and optionally add an installer script to configure the site a little further (default content?). But yeah, you will have to dive in a bit here.

---
Tags: 8, features, installation-profiles
---


# Question
Title: How to print name and all the roles (if user has more than 1) of a single user separated by comma?
I need to print the name of the user in one column and his roles in the second column. If a user have more than one role assigned, roles in the second column should be comma separated. How to do this?

# Answer
This would go into .tpl.php template file for your page.

```
<?php
  global $user;
  print 'name: '.$user->name;
  print 'roles: '.implode(', ', $user->roles);
?>

```

Or, you can make it a table with 2 columns like so (note, this is html):

```
<table>
<tr>
    <td>User Name</td>
    <td>', $user->name, '</td>
  </tr>
  <tr>
    <td>User Roles</td>
    <td>', implode(', ', $user->roles), '</td>
  </tr>
</table>

```
> 2 votes

---
Tags: users, database
---


# Question
Title: Why does deleting a translation on my custom entity delete the entire record?
I have defined a custom content entity. (You may find the details below.) If I create an entry in the table and a translation for the entry and then delete the translation it removes the entire entry.

```
/**
 * @ContentEntityType(
 *   id = "my_custom_entity",
 *   label = @Translation("My Custom Entity"),
 *   handlers = {
 *     "storage" = "Drupal\Core\Entity\Sql\SqlContentEntityStorage",
 *     "access" = "Drupal\my_custom_entity\MyCustomEntityAccessControlHandler",
 *     "form" = {
 *       "default" = "Drupal\my_custom_entity\Form\MyCustomEntityForm",
 *       "delete" = "Drupal\my_custom_entity\Form\MyCustomEntityDeleteForm",
 *     },
 *     "list_builder" = "Drupal\my_custom_entity\Entity\Controller\MyCustomEntityListBuilder",
 *     "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
 *     "views_data" = "Drupal\my_custom_entity\MyCustomEntityViewsData",
 *     "translation" = "Drupal\content_translation\ContentTranslationHandler"
 *   },
 *   translatable = TRUE,
 *   base_table = "my_custom_entity",
 *   data_table = "my_custom_entity_field_data",
 *   fieldable = FALSE,
 *   entity_keys = {
 *     "id" = "id",
 *     "label" = "label",
 *     "langcode" = "langcode"
 *   },
 *   links = {
 *     "canonical" = "/my_custom_entity/{my_custom_entity}",
 *     "edit-form" = "/my_custom_entity/{my_custom_entity}/edit",
 *     "delete-form" = "/my_custom_entity/{my_custom_entity}/delete",
 *     "collection" = "/my_custom_entity/list"
 *   },
 *   list_cache_contexts = {"user"}
 * )
 */

```

Update: I've made a bit of progress on this. The issue seems to be that the entity provides a delete-form. On account of this `core/modules/content_translation/src/Access/ContentTranslationManageAccessCheck::access` ends up returning `AccessResult::forbidden()` on line 85 (Drupal 8.3.7) when looking at the path `/my_custom_entity/{my_custom_entity}/translations/delete/{language}`. Instead it uses `/my_custom_entity/{my_custom_entity}/delete`. Now I've got to figure out what I'm supposed to do instead. The User entity does not declare a delete-form, but the Node entity does. My initial attempt at removing the delete-form key on my entity resulted in `Uncaught PHP Exception Symfony\\Component\\Routing\\Exception\\RouteNotFoundException: "Route "entity.my_custom_entity.delete_form" does not exist." at /var/www/html/drupal8/core/lib/Drupal/Core/Routing/RouteProvider.php line 190`. However, I didn't actually uninstall and reinstall the module. I just visited the Extend page and cleared cache.

# Answer
> 1 votes
TL;DR: Extend `ContentEntityDeleteForm` instead of `ContentEntityConfirmFormBase`.

The solution was to pattern my approach after the way Node and Taxonomy Terms create their delete forms. I changed my delete form to extend `ContentEntityDeleteForm` instead of extending `ContentEntityConfirmFormBase`. Look at `ContentEntityDeleteForm::submitForm`

```
// Make sure that deleting a translation does not delete the whole entity.
if (!$entity->isDefaultTranslation()) {
  $untranslated_entity = $entity->getUntranslated();
  $untranslated_entity->removeTranslation($entity->language()->getId());
  $untranslated_entity->save();
  $form_state->setRedirectUrl($untranslated_entity->urlInfo('canonical'));
}
else {
  $entity->delete();
  $form_state->setRedirectUrl($this->getRedirectUrl());
}

```

It explicitly takes care not to delete the whole entity when you are deleting a translation.

`ContentEntityConfirmFormBase` inherits the `ContentEntityForm::submitForm` method, which in turn executes the `EntityForm::submitForm` method. The entity never gets deleted anywhere in that process. Thus, I needed to override the submitForm method in my class. I hadn't included the necessary logic to account for translations, though. Rather than reproducing the necessary logic in an overridden submitForm method, it made more sense to change the class that I was extending.

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


# Question
Title: Anyone successfully accepting bitcoin or other cryptocurrency on a commerce site?
We're already accepting bitcoin and litecoin in our physical store and would love to add it to our online stores. We tried the Bitpay drupal module but it breaks both our sites. Anyone accepting cryptos successfully? How?

# Answer
If you want a solution where customers can choose from a wide range of cards/currencies to pay with, Stripe integrated with Drupal Commerce is a good way to do so. Here is the module: Commerce Stripe module
> 1 votes

---
Tags: commerce
---


# Question
Title: Possible parent values for parent of links
I am trying to create links in my Drupal 8 module, following this tutorial. So far, I have a link as follows in my `module.links.menu.yml` file:

```
module.admin_settings:
  route_name: module.adminForm
  title: 'Module Configuration'
  description: 'Set up module on your website'
  parent: system.admin_config_system

```

My question is, how do I find all possible values for the `parent` property? I looked in the docs but couldn't find one. However, there is a paragraph in the above tutorial which says:

> Determining the parent menu\_link name can be a little tricky at first. If you know the path of the parent menu item, you would need to search for it in all available \*.routing.yml files (most text editors and IDEs should allow you to search all files in a project) and find the route name for that path. Then, you would need to search for the route name in all available \*.links.menu.yml files. The menu\_link whose route\_name matches is your link. Alternatively, if you know which module is defining the parent menu link (or one of the parent menu link's children), you can go straight to that module and perform your search.

But I am not sure I understand as I am new to Drupal. Is there an easy way to find the set of possible parent values?

Thanks.

# Answer
> 1 votes
You can go to the menus structure and click on edit of the menu link under which you want to place the new link. The example from your question would open in this url:

```
/admin/structure/menu/link/system.admin_config_system/edit

```

Then you'll find the parent name in the slug before `/edit`.

But the easiest way is to register the menu link without parent, which would place the new link in the top level of the menu and then drag and drop the link where you want it to be.

You probably need to specify the menu name in the yaml file:

```
menu_name: admin

```

---

In the exported configuration the links you've moved in UI appear in this configuration file:

```
core.menu.static_menu_link_overrides.yml

```

where you'll find the parent value where you dragged the link to. You could then use this information for `module.links.menu.yml`, if you want to deliver your module with this information.

---
Tags: 8, routes, navigation
---


# Question
Title: How to fix my Rules Actions to copy data from geofield to geofield?
I want to copy a geofield to another geofield in the same content type.

1. I created a Rule where I "Set Data Value" and with that I copy the data of one geofield into the other. Actually I created two actions one for longitude and latitude.
2. This action is triggered when "After updating existing content".
3. I used VBO to parse through my nodes therefore the trigger to be fired and geofield data to be copied.

Nothing happens. I get two errors in error log saying:

> Unable to evaluate action data\_set.
> Unable to modify data "node:field-business-location...

I tried to expose the fields to rules by "Entity has field" condition but doesn't work either.

What am I doing wrong.

PS: There is also an option of "Create Geofield values from Lat/Lon but I don't see how I can copy data from one Geofield to another Geofield like this.

My Rule Export

> { "rules\_copy\_geolocation\_data" : {
>
> ```
> "LABEL" : "Copy geolocation data - Destinations",
> "PLUGIN" : "reaction rule",
> "OWNER" : "rules",
> "REQUIRES" : [ "rules" ],
> "ON" : { "node_update--destination" : { "bundle" : "destination" } },
> "IF" : [
>   { "entity_is_of_bundle" : {
>       "entity" : [ "node" ],
>       "type" : "node",
>       "bundle" : { "value" : { "destination" : "destination" } }
>     }
>   },
>   { "entity_has_field" : { "entity" : [ "node" ], "field" : "field_destination_location" } },
>   { "entity_has_field" : { "entity" : [ "node" ], "field" : "field_business_location" } }
> ],
> "DO" : [
>   { "data_set" : {
>       "data" : [ "node:field-business-location:lat" ],
>       "value" : [ "node:field-destination-location:lat" ]
>     }
>   },
>   { "data_set" : {
>       "data" : [ "node:field-business-location:lon" ],
>       "value" : [ "node:field-destination-location:lon" ]
>     }
>   }
> ]   } }
>
> ```

# Answer
*Debugging is the art of taking away all possible reasons that may cause your issue* ... Read on for more details to find out which one it might be, and how to possibly solve it.

# Option 1: After updating actually happens before updating

Have a look at the issue about ***"After updating existing content" runs before content is saved***, about an event which is a variation of your event here, and somehow explains that "***after*** saving something" actually happens "***before*** saving something". Therefor I'm about sure this is not a bug, but simply how the Rules module works.

A possible compromise to avoid these kind of issues, is to transform what you're trying to do into a Rules Component, so that your original Rule "schedules the execution" (using the Rules Scheduler sub-module) of that Rules Component. For example after only a few seconds or minutes if your cron job runs frequent enough (otherwise it'll be next time cron runs). This compromise will ensure that, at the time the Rules component is executed, the entity is for sure saved (so *that* can't be the reason anymore then why things don't work as expected).

# Option 2: Add an extra Rules Action 'Save Entity'

Another cause of possible confusion is within the Rules module, where sometimes it gets tricky to "save entities". So possibly adding an appropriate "save entity" action (after the 2 Rules Actions you already have) may also help (if nothing else helps).

# Option 3: Rules debugging

Rules is great, but sometimes also tough to debug if things don't work as you'd expect. There are some typical facilities to do such debugging (further detailed below), but a **K**eep-**I**t-**S**uper-**S**imple technique I often use, is my ***BINGO***-trick. A sample of such rule can be found in my answer to "Which Rules condition can be used to email a user when an admin updates their profile?". Stupid, but simple and efficient (I think). If tis doesn't help, then there are typically 2 ways of more advanced debugging:

* ### Rules Evaluation Log

Within the Rules **settings**, experiment a bit with the debugging facilities that come with the rules module. At least have a look at the "***Rules Evaluation Log***" (to check that the Rules logic being executed, actually matches what you expect that logic to be).
* ### Rules Action to display a value (using devel)

You may also want to (temporary) enable the Devel module, so that you can (temporary) add a Rules Action like "Display a value".

Obviously, make sure that there are no Rules Conditions that would prevent the Rules Action(s) from being executed (if needed temporary remove such Rules Conditions).

For way more details about these 2 variations, refer to **Rules debugging**, as explained in the answer to "How can I display the value of a variable inside a condition?".
> 0 votes

---
Tags: 7, rules
---


title: Trusted redirect response

text:
# Question
Title: Trusted redirect response
I installed version 8.3.7 and today the version 8.4.0 (NOT localhost, multilingual or not), using PHP 7.0.13, MySQL 5.6.22, and made the proper settings apparently. I read about this problem, which generates this error:

> Redirects to external URLs are not allowed by default, use \Drupal\Core\Routing\TrustedRedirectResponse for it.

I took the necessary steps like changing the settings.php file and inserting:

```
$settings['trusted_host_patterns'] = [
  '^gersonvagner\.com$',
  '^www\.gersonvagner\.com$',
];

```

However, the problem persists in all instances, for example when I try to put the site under maintenance or try run cron. I don't know where else I might be going for more than a week of testing and reading. If anyone can help me.

Every time I go to validate any action in the administrative environment it returns me with this message, anyway, the changes are accepted, but always this message is shown to me. Examples: If I run cron for updates, it runs and the message appears successful, but after the screen with the message I mentioned earlier. If I put or remove the site from the maintenance mode, the same occurs, that is, the site enters or leaves the maintenance with success, but I will only know this if I return to the domain and see the status, because the screen that always appears next is with this message: "Redirects to external URLs ...". This is repeated in all changes that are made in the admin environment, such as installing or uninstalling modules or templates. I don't see what I am doing wrong.

# Answer
For me, I just needed to uncomment 'RewriteBase /' in '.htacess'. Working now. I had forgotten this little detail.
> 0 votes

---
Tags: 8
---


# Question
Title: Discount and coupon 100% off of for only 1 item in shopping cart
I am using Drupal 7 with the 2.x version of the Coupon and Discount modules.

I am attempting to issue a 100% discount (free item) to my users, but I want to apply it only to 1 item in the cart. This way, 1 item is free but anything else is still full price. I want each user to be able to choose any item they want.

I would like the user to be able to browse the site for 1 item and, at checkout, apply the coupon code so that the item is free. To prevent people getting every item for free and adding many items to the cart, I would like the coupon to only apply to one item in the cart.

Is there a way to give each user the ability to get an item free?

# Answer
> 0 votes
You could use the Flag module to get this to work, by configuring an appropriate (non-global) flag, which you should then use to (automagically) flag a user after such user applied (for the first time) the coupon code at checkout. To actually flag such users, you should use the Rules module, which integrates extremely well with the Flag module. All that's left is to find the appropriate Rules Event for such rule to be triggered (somewhere along the lines of "checkout completed" I would assume).

Any time a user tries to apply such coupon code, you can then verify if it is the very first time, or yet another time. For this verification, all you'd have to do is use a Rules Condition to check "has this user yes or no been flagged already (by the flag you created for this purpose)".

If you're not familiar with the Flag module, checkout either of these:

---
Tags: commerce, rules
---


# Question
Title: What to enter into browser-sync command to run it on Aquia Dev Desktop?
I'm trying to set up Broswers-Sync for my Aquia Dev Desktop Drupal 7 installation on localhost

In the page tutorial it says to set up local host like this command:

```
browser-sync start --proxy "myproject.dev" --files "css/*.css"

```

But I'm not sure what to put in there for my actual project.

The file I want to target is:

```
C:\patch\sites\all\themes\bootstrap_subtheme_local\css\style.css

```

And site URL on my machine is:

```
http://patch.dd:8083/

```

I want to know what to put in the command line to make this work.

# Answer
> 1 votes
You need to specify the hostname and port (patch.dd:8083) and the path to the CSS files you want to watch. Using the values in your example, you should therefore run:

```
browser-sync start --proxy "patch.dd:8083" --files "C:\patch\sites\all\themes\bootstrap_subtheme_local\css\style.css"

```

# Answer
> 0 votes
Here's the fix, I used...

The problem was that localhost:3000 isn't actually connected to http://yourblogname.dd:8080/- you can verify this by going to localhost:3001 (or the UI port shown on your console) and you should see that while using aquia dev desktop, there is no connection unless you go to yourblogname.dd/3000

To fix this, I've used an external call, that will change the output localhost:3000 to myblogname:3000

```
gulp.task('browserSync', function() {
    //note: special fix for aquia dev desktop, to get mybog.dd
    browserSync.init({
       open: 'external',
       host: 'yourblogname.dd',
       proxy: 'http://yourblogname.dd:8080/', // or project.dev/app/
   });
});

```

---
Tags: acquia-dev-desktop
---


# Question
Title: Set the value of a hidden form component
I have a Webform in drupal 7. I want to add a hidden field porgramatically to it, and I would like to set the value of this field per form. I want to achieve all these in a custom submit function, as I want to use the sid (serial ID) of the Submission, to generate a unique ID for each Submission. At the moment everything is working, except to set the value. I googled it a lot, tried out hundreds of codes but non of them worked in my case.

Here is my code:

```
<?php
$form['#submit'][] = 'webform_custom_submit';

function webform_custom_submit($form, &$form_state) {
  if ( !array_key_exists('my_uniq_id', $form['#node']->webform['cids'] ) ){
    $components = array(
      0 => array(
        'name' => 'My Unique ID',
        'form_key' => 'my_unique_id',
        'type' => 'hidden',
        'weight' => 1,
        'pid' => 0
      )
    );
    webform_ensure_record($form['#node']);
    foreach ($components as $component) {
      $component['nid'] = $form['#node']->nid;
      $form['#node']->webform['components'][] = $component;
      webform_component_insert($component);
    }
  }
  $my_uniqe_key = generate_some_unique_key_function();
  //Here I wan't to set the value of the component 'my unique ID', but nothing worked yet
  $form_state['my_unique_id']['#value'] = $my_uniqe_key;
}

```

Thanks for the help, I'm sure I could find the answer somewhere, but I tried it 3hours long...

Here is the $form and $form\_state written out with dpm from my webform\_custom\_submit function.

And here are some codes, I tried already:

```
<?php
$form['values']['my_unique_id'] = $my_uniqe_key;
$form['values']['my_unique_id']['#value'] = $my_uniqe_key;
$form['values']['my_unique_id']['value'] = $my_uniqe_key;
$form['submitted']['my_unique_id']['#value'] = $my_uniqe_key;
$form['my_unique_id']['und']['0']['value']['#value'] = $my_uniqe_key;
$form_state['values']['my_unique_id'] = $my_uniqe_key;
$form_state['values']['my_unique_id']['#value'] = $my_uniqe_key;
$form_state['values']['my_unique_id']['value'] = $my_uniqe_key;
$form_state['my_unique_id']['und']['0']['value']['#value'] = $my_uniqe_key;
$form_state['values']['my_unique_id'][LANGUAGE_NONE][0]['value'] = $my_uniqe_key;
drupal_array_set_nested_value($form, array('submitted', 'my_unique_id', '#value'), $my_uniqe_key;);
form_set_value( array('submitted','my_unique_id'), array(0 => array('value' => $my_uniqe_key;)), $form_state) ;

$cid = $form['#node']->webform['cids']['my_unique_id'];
$form_state['values']['submitted'][$cid] = "static text";

```

# Answer
> 0 votes
Finally I was able to solve my problem with the help of this answer to an other question. Here is the part of my code from `my_custom_submit` function, which updates hidden field:

```
<?php
module_load_include('inc', 'webform', 'includes/webform.submissions');
$node = node_load($form_state['storage']['details']['nid']);
$submission = webform_get_submission($node->nid, $form_state['storage']['details']['sid']);
foreach ($form['#node']->webform['components'] as $key => $component) {
  if ( $component['form_key'] == 'my_unique_id' ){
    $submission->data[$key][0] = $my_uniqe_key;
  }
}
webform_submission_update($node, $submission);

```

I tried all your suggestions, but non of them worked for me. Thanks for all your efforts!

# Answer
> 2 votes
You should use the presave hook provided by webform instead of adding additional submit handlers to the form.

```
/**
 * Modify a Webform submission, prior to saving it in the database.
 *
 * @param $node
 *   The Webform node on which this submission was made.
 * @param $submission
 *   The Webform submission that is about to be saved to the database.
 */
function hook_webform_submission_presave($node, &$submission) {
  // Update some component's value before it is saved.
  $component_id = 4;
  $submission->data[$component_id][0] = 'foo';
}

```

This is a lot cleaner than adding custom submit handlers to the form (your custom handler is called after the webform submission handler, which can be a big part of the problem).

You have access to the node object in the presave hook so additional checks can be added beforre altering the component.

# Answer
> 0 votes
I think you should set your value in $form\_state\['values'\]\['submitted'\]:

```
$form_state['values']['submitted'][$cid] = $my_uniqe_key;

```

Here $cid is the component ID, which is the key of the component info in $form\['#node'\]-\>webform\['components'\].

---
Tags: 7, webforms
---


# Question
Title: Communication between hook_webform_submission_presave and a Custom submit function
My users fill out a registration form (with their emails, and some options). I calculate with ajax from these options a price. I want to redirect them to an other site, so they can pay there the price.

With `form_alter` I add some hidden fields (components) to my webform (like `PaymentRequestId` and Payment Status). And I set a **custom submit function** to the form, as I want to redirect the users.

But I have some difficulties: first I tried to generate and set the `PaymentRequestId` in my **custom submit function**, but I was not able to save the value into the formfield of the submission there. I already asked it here, how to do that, but I could not achieve it. So for a suggestion, I moved these into a `hook_webform_submission_presave` function. Now, I was able to save my `PaymentRequestId` (HURRAY!).

But I also need this ID in my **custom submit function**, as the URL (where I need to redirect my users) is generated from this. But neither the `$form`, nor the `$form_state` in my **custom submit function** does not contains the value of the `PaymentRequestId`. I do not understand why, as when I watch the Submission on the admin interface, the `PaymentRequestId` is there.

Do you have any ideas/workarounds for my problem? Thanks a lot, for all your efforts!

# Answer
I did not find a way with the `hook_webform_submission_presave` function, but finally I found a solution with the help of this answer to an other question, to save values into the webform submission in `my_custom_submit` function. Here is the part of my code from `my_custom_submit` function, which updates hidden field:

```
<?php
module_load_include('inc', 'webform', 'includes/webform.submissions');
$node = node_load($form_state['storage']['details']['nid']);
$submission = webform_get_submission($node->nid, $form_state['storage']['details']['sid']);
foreach ($form['#node']->webform['components'] as $key => $component) {
  if ( $component['form_key'] == 'my_unique_id' ){
    $submission->data[$key][0] = $my_uniqe_key;
  }
}
webform_submission_update($node, $submission);

```

I tried all your suggestions, but non of them worked for me. Thanks for all your efforts!
> 0 votes

# Answer
First of all you need to make sure that your ajax return your results to the form so as you can have the value on your custom form submit. Maybe one more hidden field with the new value would be the solution. So in your custom ajax callback you need to `return $form['new_value_field'];`

After that, in your custom submit function you should get the new value and you can save your form in there. `$form_state->setValue('new_field', 'new_value');`. Even though I'm not sure if you need to set the value again as you already did it with ajax earlier.

Finally, you can redirect the user in your custom submit function by using `$form_state->setRedirect('machine_name');`
> 0 votes

---
Tags: forms, webforms
---


# Question
Title: Using same images in different content and products
I am developing a website and on the homepage I have an add to cart form as well as a carousel which use the same images.

I am also re-using certain images for several types of products in Commerce.

Is there a method of using the same image rather than uploading a new one each time as I am thinking this will save bandwidth on page-load

Thanks for your help

# Answer
> 0 votes
I am assuming you want different size variations of the same image for the different section of your website.

Imagekit.io can help you resize images just by passing width in the URL. This will allow you to store just one big image on your server and deliver smaller size variations as per the layout. There is some automatically advanced optimization as well which will help you save bandwidth on page-load.

---
Tags: commerce, media
---


# Question
Title: How can I clone and use the default taxonomy view to learn its behavior?
Views comes with a default taxonomy view packaged with it.

I can see it over here and modify it:

```
admin/structure/views/view/taxonomy_term/edit

Taxonomy term
A view to emulate Drupal core's handling of taxonomy/term
default/taxonomy/term/%,/taxonomy/term/%/%/feed

```

Now how do I actually "view" this view!

I want to clone it, modify it and experiment, but can't access it from front end...

# Answer
The `%` symbol in the URL works a placeholder for a parameter. So if you access taxonomy/term/**1** or taxonomy/term/**2** note that the number is actually the term id, so that is the way you "view" (access) the view. You can see, edit, add, delete or modify those parameters if you click the advanced option in the view and you will see the option "Contextual filters".

Now, to clone it, you can access the up right button and then click the "duplicate" option, wich for this case will have a URL `/admin/structure/views/view/taxonomy_term/duplicate`. Note that this will clone all the view and its styles, in this case, will duplicate a view with two styles: the page view and the RSS view.
> 1 votes

---
Tags: views
---


title: local drush - installation failed

text:
# Question
Title: local drush - installation failed
I recently manually upgraded to Drupal 8.4, from 8.3 because I couldn't get drush to work. I'm now trying to install drush locally as this seems to be the recommended way from the drush documentation. (I removed the global install of it I had), but I get the following errors (below).

```
[www public_html]$ composer require drush/drush
Using version ^8.1 for drush/drush
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - drush/drush 8.1.0 conflicts with drupal/drupal[No version set (parsed as 1.0.0)].
    - drush/drush 8.1.1 conflicts with drupal/drupal[No version set (parsed as 1.0.0)].
    - drush/drush 8.1.2 conflicts with drupal/drupal[No version set (parsed as 1.0.0)].
    - drush/drush 8.1.3 conflicts with drupal/drupal[No version set (parsed as 1.0.0)].
    - drush/drush 8.1.4 conflicts with drupal/drupal[No version set (parsed as 1.0.0)].
    - drush/drush 8.1.5 conflicts with drupal/drupal[No version set (parsed as 1.0.0)].
    - drush/drush 8.1.6 conflicts with drupal/drupal[No version set (parsed as 1.0.0)].
    - drush/drush 8.1.7 conflicts with drupal/drupal[No version set (parsed as 1.0.0)].
    - drush/drush 8.1.8 conflicts with drupal/drupal[No version set (parsed as 1.0.0)].
    - drush/drush 8.1.9 conflicts with drupal/drupal[No version set (parsed as 1.0.0)].
    - Conclusion: don't install drush/drush 8.1.14
    - Conclusion: don't install drush/drush 8.1.13
    - Conclusion: don't install drush/drush 8.1.12
    - Conclusion: don't install drush/drush 8.1.11
    - Conclusion: don't install drush/drush 8.1.10
    - Conclusion: don't install drush/drush 8.x-dev
    - Installation request for drupal/drupal No version set (parsed as 1.0.0) -> satisfiable by drupal/drupal[No version set (parsed as 1.0.0)].
    - Conclusion: remove symfony/console v3.2.8
    - Installation request for symfony/dependency-injection (locked at v3.2.8, required as ~3.2.8) -> satisfiable by symfony/dependency-injection[v3.2.8].
    - Installation request for drush/drush ^8.1 -> satisfiable by drush/drush[8.1.0, 8.1.1, 8.1.10, 8.1.11, 8.1.12, 8.1.13, 8.1.14, 8.1.2, 8.1.3, 8.1.4, 8.1.5, 8.1.6, 8.1.7, 8.1.8, 8.1.9, 8.8.x-dev, 8.x-dev].
    - Conclusion: don't install symfony/console v3.2.8
    - drush/drush 8.8.x-dev requires symfony/console ~2.7 -> satisfiable by symfony/console[2.7.x-dev, 2.8.x-dev].
    - Can only install one of: symfony/console[2.7.x-dev, v3.2.8].
    - Can only install one of: symfony/console[2.8.x-dev, v3.2.8].
    - Installation request for symfony/console (locked at v3.2.8, required as ~3.2.8) -> satisfiable by symfony/console[v3.2.8].

Installation failed, reverting ./composer.json to its original content.

```

# Answer
Download this:

https://dev.acquia.com/downloads

Then install it in one click.

After your site is installed, click on the left on +more.

Once you click on that, console pop ups and Drush is installed and working, turn key
> 0 votes

---
Tags: drush
---


# Question
Title: Cannot get translated value for an entity inside twig
Inside a custom module I get the translated nodes like this:

```
$ids = Drupal::entityQuery('node')
    ->condition('type', 'event')
    ->condition('status', 1)
    ->execute();

$nodes = Drupal::entityTypeManager()->getStorage('node')->loadMultiple($ids);

$events = array_map(function ($node) {
    return Drupal::entityManager()->getTranslationFromContext($node);
}, $nodes);

```

and inside the template:

```
<div class="events">
  {% for event in events %}
    <div>
      <h4>{{ event.title.value }}</h4>
      <div class="event-type">
        {{ event.field_event_type.entity.name.value }}
      </div>
    </div>
  {% endfor %}
</div>

```

The event\_type entity which is a taxonomy is displayed in the original language always. How can I get the translated value for the entity too?

# Answer
> 0 votes
You would need to prepare the taxonomy entities the same way like the nodes. But normally it's not your job to do either of this.

Use viewMultiple() instead of array\_map() in the first php example:

```
$nodes = \Drupal::entityTypeManager()->getStorage('node')->loadMultiple($ids);
$build = \Drupal::entityTypeManager()->getViewBuilder('node')->viewMultiple($nodes, $view_mode);
$variables['events'] = $build;

```

In Twig:

```
{{ events }}

```

Customize the twig of the view mode specific event content type and other templates like the taxonomy field template if needed.

---
Tags: 8
---


# Question
Title: After updating I got these error messages
After updating my Drupal 8 test site from 8.3.7 to 8.4.0, I got these error messages:

> Mismatched entity and/or field definitions
> The following changes were detected in the entity type and field definitions.
>
> ### Webform submission
>
> * The Sprache field needs to be updated.
>
> ### Absatz
>
> * The Veröffentlicht field needs to be updated.
> * The Behavior settings field needs to be updated.

What do I have to do? I don't know how and where I should update these fields. Should I update any database table, or is there another workaround?

# Answer
> 0 votes
Try on terminal this command

```
drush entity-updates

```

Or if you have Devel module installed, you can also use the "Execute PHP Code" page at http;//example.com/devel/php

```
try {
  \Drupal::entityDefinitionUpdateManager()->applyUpdates();
}
catch (EntityStorageException $e) {
  print_r($e);
}

```

---
Tags: updating
---


# Question
Title: Rules: get content created by user account being cancelled?
Case: using Rules module, when a user account is cancelled, create a new node of type Archive and (a) copy select data from that account to the new node of type Archive, and (b) copy select data from a single node of type XYZ authored by the cancelled user to the new node of type Archive.

I have this rule:

```
EVENT
After a user account has been deleted
CONDITIONS
None
ACTIONS
Create a new entity
(set data values here)
Save entity

```

In Actions, the new node created is of type Archive. In between creating and saving this new node, data values are set (i.e. "Set data value") on it. The values are derived from the account being cancelled.

However, how can I access a node of type XYZ authored by this account, and use that to also set data values on the new node of type Archive? There seems to be no way to access the fields of XYZ in the Data Selector. The available fields pertain only to the account, and not to content authored by that account.

As a comparison, in Views I would establish a Relationship to open up access to fields of related entities. What's the equivalent in Rules?

Thanks

# Answer
You can use the 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, you can use Views to create a view of your "*node of type XYZ authored by this account*" (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 using the view of display type 'Rules'

Adapt your Rulew Actions, using these guidelines:

* Use the link that says `Add view loop` to add a Views loop, and select the "Rules" display created in the previous step.
* Configure the parameters and variable names.
* For each node contained in your Views loop (I seem to understand you will only have one), perform whatever Rules Action that fits your requirement, using 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).
> 2 votes

---
Tags: 7, rules
---


# Question
Title: How can I get the entity ID after saving it?
I am saving an entity and I would want to get its ID.

```
$CustomerEntity = CustomerEntity::create([
  'customer_id' => $customer['id'],
  'customer_name' => $customer['name'],
  'address' => $customer['address'],
]);

$CustomerEntity->save();

```

How do I get the entity ID with that code?

# Answer
Use `$CustomerEntity->id();` after saving your entity.

```
$CustomerEntity = CustomerEntity::create([
  'customer_id' => $customer['id'],
  'customer_name' => $customer['name'],
  'address' => $customer['address'],
]);

$CustomerEntity->save();
$id = $CustomerEntity->id();

```
> 9 votes

---
Tags: 8, entities
---


# Question
Title: facebook login redirect drupal for facebook module
I am using Drupal for facebook module. I want to redirect user to specific URL, if he login from facebook ? Note: I am using Login destination for normal users and works fine for this.

# Answer
Drupal for facebook module has a sub module called "FB Rules Integration" Enable it.

Then create a new rule: give it a name, something like "after connecting facebook account".

add an action: page redirect then enter where do you want to redirect to, something like ""

Here is an export of the rule which you can just import.

```
{ "rules_after_connecting_facebook_account" : {
    "LABEL" : "after connecting facebook account",
    "PLUGIN" : "reaction rule",
    "REQUIRES" : [ "rules", "Drupal for Facebook" ],
    "ON" : [ "fb_user_connected", "fb_user_login" ],
    "DO" : [ { "redirect" : { "url" : "\u003Cfront\u003E" } } ]
  }
}

```
> 1 votes

# Answer
You can also use hook\_fb, provided by drupal for facebook module like this:

```
function fb_example_fb($op, $data, &$return) {
  $fb_app = isset($data['fb_app']) ? $data['fb_app'] : NULL;
  $fb = isset($data['fb']) ? $data['fb'] : NULL;
  if ($op == FB_OP_AJAX_EVENT) {
    // We get FB_OP_AJAX_EVENT when fb.js calls us in reponse to a javascript event.

    if ($data['event_type'] == 'session_change') {
      // The user has clicked the connect button, or logged into/out-of
      // facebook in another browser window, then refreshed.
      if ($fbu = fb_facebook_user()) {
        // The user has connected (as opposed to logged out).  Let's redirect
        // them to our 'welcome' page.  Replace 'welcome' with the path you
        // really want.
        $url = url('welcome',
                   array('absolute' => TRUE, 'fb_canvas' => fb_is_canvas()));
        // We return javascript to be evaluated by fb.js.
        $return[] = 'FB_JS.reload("'. $url .'");';
      }
    }
  }
}

```

This one worked for me.

Also you can check this link for more informations.

Hope it helps someone. Cheers.
> 1 votes

# Answer
An easy option would be to use simple fb connect module. It has this feature out of the box. On the configuration page there is a form where you can add the (dynamic) path. The user will be redirected to this path when logging in with fb.
> 0 votes

---
Tags: users, redirection, social-network
---


# Question
Title: How to use multiple sorting criteria across multiple content types?
I'd like to display a view of several content types on my frontpage (news, events, products, artists). That's easily done.

However I also need to sort the posts in a pretty specific way. It's a bit hard to explain but here we go:

News and artists should be sorted by publish date. Events should be sorted by a date field (event date). Products should be sorted by a date field (release date).

Here's an example of how the first 5 posts on my front page could look all together on a random day:

* Sep 15 (publish date) - News post 1
* Sep 14 (event date) - Event post 1 (could be published on a much earlier date)
* Sep 13 (publish date) - News post
* Sep 12 (release date) - Product post 1 (could be published on a much earlier date)
* Sep 11 (event date) - Event post 2 (could be published on a much earlier date) etc. etc.

I don't see any way to set sorting criteria per content type within the same view though? Any ideas? Or did I miss anything?

# Answer
> 0 votes
You can't do what you are suggesting with Views as written. The **Sort** criteria applies to everything being sorted by the view.

I would suggest adding a date field to all content types you want to sort called **Sort**, and then use hooks in a custom module to automatically set the value for the field when possible (for example, automatically set the date field's value to the publish date upon publishing for news posts).

Then you can easily sort by the single (newly created) date field in Views.

---
Tags: views
---


# Question
Title: How do I simply make the whole site use a secure connection?
In Drupal 7, I used the *Secure login* module to run the site on a secure connection, but it seems it doesn't revert back to http on logout. I would like to just run the whole site as https:// as a simplification.

Is there a simple way to do this without the use of module?

# Answer
> 8 votes
Start by reading Enabling HTTP Secure (HTTPS). Please ask more specific questions and/or update your question if that doesn't help.

# Answer
> 39 votes
If you want to redirect all of your pages to be forced to use SSL then add this to your `.htaccess` file.

```
# Redirect to HTTPS
RewriteCond %{HTTPS} off
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

```

This should be placed **directly after** `RewriteEngine on` if you have no previous rewrites.

# Answer
> 1 votes
Another handy trick, if you have root access to Apache to alter your vhost directives is to add this to the SSL directive for the site. Most modern browsers obey this directive (IE9 does not)

```
Header always set Strict-Transport-Security "max-age=63072000"

```

You can set the age to whatever you want. What this does is inform web browsers that obey this to ONLY use SSL to communicate with your website and never plain HTTP. This adds a little bit of assurance with the whole HTTP/HTTPS switching situation.

It's a handy hack.

NOTE: This will only work if you have a VALID SSL certificate (not self-signed, expired or otherwise incorrect) on your site. If you don't, it will prevent the browser from connecting to it until the max-age period expires.

# Answer
> 0 votes
There is another option you may wish to try—it's what I needed for one of my installs, and it required no additional modules:

First, in your .htaccess:

```
RewriteCond %{HTTPS} !on
RewriteCond %{HTTP_HOST} ^www\.yourdomainhere\.com*
RewriteRule ^(.*)$ https://www.yourdomainhere.com/ [L,R=301]

```

This should be added after:

```
RewriteEngine on

```

Then, in your settings.php:

```
$base_url = 'https://www.yourdomainhere.com';

```

Also, you may want to check for external resources, such as Web fonts and other references that need to be coming from an https domain in order to avoid certificate warnings.

Hope this helps.

---
Tags: .htaccess, ssl
---


# Question
Title: view_embed_view doesn't work as expected(Drupal commerce)
I want to output the views block of collection\_products which is filtered by a taxonomy term but it doesn't print anything when I tried the following code:

print views\_embed\_view('collection\_products','block\_1','sample-category-1');

attached is the views editing page.  So what might be the problem?

# Answer
> 1 votes
Try to use `$term->term_id` instead of `$term->name` in `views_embed_view()`

You can get it programmatically by loading taxonomy term through `taxonomy_term_load()` function and passing it to `views_embed_view()` as a third argument

---
Tags: commerce
---


# Question
Title: Unlimited field collection pagination in node edit page
In my node I have a field collection which is set to unlimited. How to enable pagination for node edit page, where all items from that field collection are displayed? For display there are couple possibilities - pagination modules, views etc. but how to do it for node edit page?

# Answer
> 0 votes
A great solution to your problem would be to use the EmbeddedViewField module. It fixes your problem, as mentioned in the module's project page:

> EmbeddedViewField is a module that will allow you to render a view as any other field.
>
> It is based on keithm's ViewField module, except that it will always render the view, regardless of whether the user is editing or displaying the entity that has the EmbeddedViewField. The view used for displaying is controlled by the default value set for the view.

---
Tags: 7, nodes, paging
---


# Question
Title: Node access control based on users at the node edit page
I want to ask is it possible to assign **customized roles** to particular users at the **node edit page**? For example, the node author/admin can assign "editor" role to user A & user B and assign "admin" role to user C at the node edit page. The node access control is different among different nodes and different users.

I found some related modules such as Permissions by Term and Permission by field but none of these can perfectly fulfill my requirements. I am using Drupal 8 so some modules may not suitable for me.

Is there any solution for that?

# Answer
You could use the Group module for this. This module allows any node to be "assigned" to some group. And then it depends how you configure the group roles (which are NOT the standard Drupal roles) about who has what kind of permissions.

For your case, create a group type named something like "Node Authors", and then create a "Group" for each user (using something containing the user's name as its label). And tune the permissions which come with the Group module (which are different from standard Drupal permissions!) to fit your needs.

After you enable `gnode`, a submodule of the Group module, you can assign any node to a group. In D7, you could simply do so at the node edit page: there is an extra form field on the node edit form which can be used to select the group that you want the node to be assigned to. However, in D8 this is no longer possible, for reasons explained in this comment, and which states:

> ... all content-to-group relationships are now fieldable and we therefore need to ensure the user is presented with the fields that were configured on said relationship. A simple auto-complete to select a group would therefore not work.

Therefor, in D8, this is what you have to do instead, as described also in the feature request "UI: more easily select group for a node":

* Open the Groups list and click through it.
* Select the appropriate Group.
* Go to Group content.
* Select "add group content".
* Select which group content.

More info:
> 1 votes

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


# Question
Title: Trying to turn on theme debug, but getting an error: Drush command terminated abnormally due to an unrecoverable error
I'm new to Drupal and Drush and so am hoping someone can shed some light on this.

I tried to turn on Theme Debug with Drush:

```
drush vset theme_debug 1

```

But I keep getting an error I don't entirely understand:

```
Drush command terminated abnormally due to an unrecoverable error.
Error: Declaration of Drush\Command\DrushInputAdapter::hasParameterOption() must be compatible with
Symfony\Component\Console\Input\InputInterface::hasParameterOption($values, $onlyParams = false) in
phar:///usr/local/bin/drush/lib/Drush/Command/DrushInputAdapter.php, line 27

```

I tried `drush status` too and got the same issue, so I think drush is probably broken across the board.

I tried deleting and reinstalling drush and reprovisioning my virtual box to no affect.

Would anyone know what could've gone wrong here?

(I am running Drush 8.1.7. on Drupal 7.5)

# Answer
> 0 votes
Update drush

```
composer require drush/drush:9.0.0-alpha1

```

---
Tags: drush
---


title: CSS not applying in drupal 8 site

text:
# Question
Title: CSS not applying in drupal 8 site
I have upgraded my site from 8.1.3 to 8.4 after that, while i load any pages. CSS is not been applied

**View source:**

**while inspecting in browser**

**Cases tried:** Placed an image file in the (**core/themes/seven**) folder and I can successfully access it from the browser.

# Answer
> 1 votes
I have followed this and disabled the css/js aggregation. Css were applied.

---
Tags: 8, theming
---


# Question
Title: 8 - Register form automatically fills in input fields
I am using the core `user-register-form` to let users register to my site. When I first want to register a new account the form is displayed as followed:

Now, when I enter credentials and submit the form, the user is created. I can login and out with the created user.

However, if I want to register ANOTHER new account the form automatically fills in the e-mail and username of the user I just created.

I have tried several things that did not solve the problem:

* Clear Drupal cache
* Close browser and re-open
* Kill browser and re-open
* Open incognito browser
* Clear browser cache
* Disabled browser auto-fill

I also tried clearing the inputs using jQuery `val('');` but then the form doesn't submit properly.

I assume this has something to do with drupal core? Please advice!

# Answer
> 3 votes
I found a solution thanks to the Drupal Community

Apparently this is defined in the core of Drupal: `core/modules/user/src/RegisterForm.php`

The following should be set to `FALSE`

```
// For non-admin users, populate the form fields using data from the browser.
    if (!$admin) {
      $form['#attributes']['data-user-info-from-browser'] = TRUE;
    }

```

However it would be better to not mess with the core values and write a `form_hook_alter` instead in your theme file:

```
function MYTHEME_form_alter( &$form, &$form_state, $form_id ) {
  if ( TRUE === in_array( $form_id, array( 'user_register_form') ) ) {
    $form['#attributes']['data-user-info-from-browser'] = FALSE;
  }
}

```

This solved the problem.

---
Tags: theming, 8, users
---


# Question
Title: Adding a class to a node for a certain term
I am working on a node content type that has the vocabulary fruits (I love fruits). Per node there are more type of fruits possible. By selecting field tags (terms of the vocabulary) the classes are added to a variable which is printed in the twig template.

Currently this is my code:

```
function theme_preprocess_node__fruit(&$variables) {

    if ($variables['elements']['field_tags'][0]['#title']=== 'Apple') {
        $variables['APPLE'] = 'active';
    }
    if ($variables['elements']['field_tags'][1]['#title']=== 'Banana') {
        $variables['BANANA'] = 'active';
    }
    if ($variables['elements']['field_tags'][2]['#title']=== 'Peer') {
        $variables['PEER'] = 'active';
    }
}

```

My problem is the following the bold number printed between field tags and title: \['field\_tags'\]**\[2\]**\['#title'\] . The numbers are the weights of the terms. And when the user deselects one of the terms, the classes will not be printed because the order (weight) is changed. Is there a way to not take into account the weight? (Which is not important for me anyway in this case)

Thanks in advance!:)

# Answer
```
function theme_preprocess_node__fruit(&$variables) {

$fieldtag = $variables['elements']['field_tags'];

for ($i = 0; $i < count($fieldtag); $i++) {
    if ($fieldtag[$i]['#title'] === 'Apple') {
        $variables['APPLE'] = 'active';
    }
    if ($fieldtag[$i]['#title'] === 'Banana') {
        $variables['BANANA'] = 'active';
    }
    if ($fieldtag[$i]['#title'] === 'Peer') {
        $variables['PEER'] = 'active';
    }

   }
}

```

Solved it this way, I am looping over the weights and comparing the title every time to the fruit type. Is there a more performant efficient way? Because I want to make a really long list with 200 items...
> 0 votes

---
Tags: taxonomy-terms
---


title: How do I send emails from a .php file?

text:
# Question
Title: How do I send emails from a .php file?
I have developed a separate functionality using PHP in a sub folder of my Drupal site (e.g. mysite.com/myfolder/myfunc.php).

Now I want to send emails using Drupal functions. Since this is not a custom module I can't use `hook_mail()`.

How do I send an email through Drupal?

# Answer
Try like this:

```
$to = 'ABCD@example.com';
$subject = 'Email in PHP';
$message = 'This is a test email message';
$headers = 'From: ABCD@example.com' . "\r\n" . 'Reply-To: webmaster@example.com' . "\r\n" . 'X-Mailer: PHP/' . phpversion();
mail($to, $subject, $message, $headers, 'ABCD@example.com');

```
> 0 votes

---
Tags: 7, emails
---


# Question
Title: Render array value empty for Datetime field
I'm using `hook_form_alter` to modify an admin edit node screen. The form has a datetime field which I'm unable to get the value for in the render array. textfields value usually appears in value-\>#default\_value.

```
xxx_form_alter(&$form, &$form_state, $form_id) {
  print(json_encode($form['field_date_test']['widget']));
}

```

When the page loads, the value is in the input field but I can't find where I can get hold of the value before the page loads.

# Answer
> 0 votes
The solution was `$item['value']['#default_value']->render()`. This outputs the value in the following format `Y-m-d H:i:s e`.

Alternatively, calling `format('Y-m-d')` or any other format string will update accordingly

because '#default\_value' was of type `DrupalDateTime` which must not implement `jsonSerialize` this is why I was getting and empty object for a value when dumping out as JSON.

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


title: Print JavaScript in Custom Block Module

text:
# Question
Title: Print JavaScript in Custom Block Module
I have a google chart timeline that is dynamically updated from a google sheet. I created a custom module 'jsblock' to manage the script, styling and layout of the chart.

To begin with, first I need to get the chart to actually print in the block, which it does not.

**jsblock/js/custom.js:**

```
(function ($) {
Drupal.behaviors.jsblock = {

    attach: function (context, settings) {

    google.charts.load('current', {'packages':['corechart', 'controls', 'timeline']});
google.charts.setOnLoadCallback(drawStuff);

function drawStuff() {
  // query against spreadsheet
  var queryString = encodeURIComponent('SELECT A, B, D, E');
  // Test that the variables are added to the queryString as the strings contained within the variables - which they do.
  //alert(queryString);
  // below grabs just data, not header rows
  var query = new google.visualization.Query('https://docs.google.com/spreadsheets/d/[chartstrid/gviz/tq?gid=0&headers=1&tq=' + queryString);
  query.send(handleQueryResponse);
}

// handler for query response from spreadsheet
function handleQueryResponse(response) {
  if (response.isError()) {
  alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
    return;
  }
  var data = response.getDataTable();
  // control for date filter
  var datepicker = new google.visualization.ControlWrapper({
    'controlType': 'DateRangeFilter',
    'containerId': 'control4',
    'options': {
      'filterColumnLabel': 'Start',
      'labelStacking': 'horizontal',
      'ui': {
        'cssClass': 'slider'
       }
    }
  });

  var changeTimeline = new google.visualization.ChartWrapper({
     'chartType': 'Timeline',
     'containerId': 'timeline',
     'chartArea': {'left': 55, 'top': 15, 'right': 0, 'bottom': 0},
  });
}

function drawChart(dataTable) {
  var container = document.getElementById('timeline');
  var chart = new google.visualization.Timeline(container);
  var dataTable = new google.visualization.DataTable();
  var options = {
    timeline: { showRowLabels: false, singleColor: '#8d8' }
  };
  chart.draw(dataTable, options);
      // data and options to be used in drawing the regular table
  var programmaticChart1 = new google.visualization.ChartWrapper({
    'chartType': 'Timeline',
    'containerId': 'programmatic_chart1_div',
    'chartArea': {'left': 55, 'top': 15, 'right': 0, 'bottom': 0}
           //'view': {'columns':[0,2,]}
  });
  // start up the dashboard
  var dashboard = new google.visualization.Dashboard(document.getElementById('programmatic_dashboard_div'));
  //bind the control and the chart to the dashboard
  dashboard.bind(datepicker, programmaticChart1, changeTimeline);
  // Draw the dashboard.
  dashboard.draw(data);
}

function createCustomHTMLContent(flagURL) {
  console.log('inside custom');
       //
    }
  }
);

```

**jsblock.module:**

```
// Render the chart in the block inside the divs specified by the getElementById calls in the chart code above
<?php

function jsblock_block_info() {
    $blocks = array();
    $blocks['jsblock']['info'] = t('My JS Block');
    return $blocks;
}

function jsblock_block_view($delta = '') {
    $block = array();
    $block['subject'] = t("The title");
    $block['content']['#markup'] = "My content goes here";
    $block['content']['#attached']['css'][] = drupal_get_path("module", "jsblock")."/css/styles.css";
    $block['content']['#attached']['js'][] = drupal_get_path("module", "jsblock")."/js/custom.js";
    $block['content']['#attached']['js'] = array(
  'https://www.gstatic.com/charts/loader.js' => array(
    'type' => 'external',
    ),
    );
    $block['content']['#markup'] = "
       <div id=\"content\" class=\"column\"><div class=\"section\">
       <div id=\"timeline\">
       <h2 style=\"padding-left: 2em; min-width: 250px;\"> Technology Product Life Cycle </h2>
       <div id=\"programmatic_dashboard_div\">
          <table class=\"columns\">
             <tr>
                <td>
                    <div id=\"programmatic_chart1_div\" style=\"padding-left: 2em; min-width: 500px;\"></div>
               </td>
            </tr>
            <tr>
                <td>
                    <div id=\"control4\" style=\"padding-left: 2em; min-width: 250px\"></div>
                </td>
            </tr>
         </table>
      </div>
  </div>
</div>";

  return $block;
}

```

**Here's how it's currently rendering:**

**Here is how it should look:**

No console errors in chrome or firefox.

Any help is greatly appreciated!

# Answer
At first sight I see 2 problems in your code.

1. The javascript order, the external file has to load first in order to use the code in your custom javascript.
2. The custom javascript will never be loaded because you rebuild the complete $block\['content'\]\['#attached'\]\['js'\] array in the next line.

Change

```
$block['content']['#attached']['js'][] = drupal_get_path("module", "jsblock")."/js/custom.js";
$block['content']['#attached']['js'] = array(
  'https://www.gstatic.com/charts/loader.js' => array(
    'type' => 'external',
  ),
);

```

to

```
$block['content']['#attached']['js'] = array(
  'https://www.gstatic.com/charts/loader.js' => array(
    'type' => 'external',
  ),
  drupal_get_path("module", "jsblock") . "/js/custom.js"
);

```

Add

Also, if is good practice to use hook\_theme to load a template instead of inserting html directly as content markup.
> 0 votes

---
Tags: 7, database, javascript, blocks, charts
---


title: Custom pagination with template

text:
# Question
Title: Custom pagination with template
So I have a custom module where there is a basic function that returns an array of data where I try to add a pager. I then call the function in the template.php the pass a custom variable to my template file. A listing appears there, with the working pagination to say so, but the list items are displayed weird. All the data is added as a HTML attribute.

This is how I create the pager from my function:

```
$result = Array(
    array(0)
        tile
        author
    array(1)
        tile
        author
    array(2)
        tile
        author
    array(3)
        tile
        author
     ....

  $total = count($result);
  $num_per_page = 12;
  // Initialize pager and gets current page
  $current_page = pager_default_initialize($total, $num_per_page);
  // Split the items up into chunks:
  $chunks = array_chunk($result, $num_per_page);
  // Get the items for our current page:
  $current_page_items = $chunks[$current_page];
  // Theme each item. Note that the theme
  // some_theme_hook is left out of this tutorial
  // for simplicity
  foreach($current_page_items as $i => $item) {
    $current_page_items[$i] = array(
      '#item' => $item,
    );
  }

  // Generate the render array for our page
  $render_array['page'] = array (
    '#theme' => 'item_list',
    '#items' => $current_page_items,
  );

  // Calls Drupal standard pager theme and set 5 page links on pager
  $render_array['pager'] = array (
    '#theme' => 'pager',
    '#quantity' => 5,
  );

  return $render_array;

```

And this is my rendered markup:

```
<li #item="http://localhost.../sites/default/files/styles/videos_page/public/16-Inside-03-L.jpg?itok=PXCk5oXs Inside the Track #3 watch for $123 Michael Brauer The Rides Game on Series new 1:20:00" class="first">
</li>

```

Any ideas of how can I manage this?

# Answer
> 0 votes
The code I've pasted works actually. I've just replaced the 'item\_list' theme, with a custom one, where I added my markup per Item.

---
Tags: theming, paging
---


# Question
Title: Does anything need to be done to upgrade from 1.0-beta1 to full release other than "composer update"?
I had a basic store with four items working fine under 1.0-beta1. I wanted the newest 20 Sept 2017 official full release version, so I executed the command:

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

```

I cleared the cache and all appeared OK with no errors.

But when I go to the list of items (via a view I created) on the website itself nothing is displayed - even though when editing the view the preview shows all four of the products with descriptions and prices as expected.

What other steps did I need to take? Shouldn't the upgrade from beta1 to 2.0 be seamless using only the Composer update command? I checked the new documentation and didn't see anything else.

---

Here are more details as to what I run into when attempting to upgrade my Commerce 2 installation from Beta 1 to RC1.

When I check Reports / Available Updates, two modules are flagged::

a) Address 8.x-1.1 --- Recommended version: 8.x-1.2 (2017-Sep-20)

b) Profile 8.x-1.0-beta1 --- Recommended version: 8.x-1.0-rc1 (2017-Sep-19) \[This is the main Commerce 2.0 module.\]

Before I attempt the update, this is what I currently have set and what results I get:

My store is defined with four products. All products are displayed on the Shop link in the main navigation menu, and placing into the cart is done solely from there.

The "Shop" link is defined as a View: Online Store (Index D8 search index)

Key settings are:

```
Title
Title: Online Store

Format
Format: Unformatted list
Show: Fields

Fields
Product datasource: Body
Product datasource: Variations

Page settings
Path: /shop
Menu: Normal: Shop
Access: None

Pager
Use pager: Mini | Mini pager, 10 items

```

Now I begin the upgrade:

1. In the Administration panel, I put the site in Maintenance mode
2. Using Composer, I execute:

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

```
3. Execute:

```
php drush.php cache-rebuild

```
4. Execute:

```
php drush.php cc drush

```
5. For the fun of it, I also cleared cache from the Admin panel.
6. Checked Reports / Available updates. Address and Profile (ie, Commerce 2.0) have both been updated.
7. Took the site out of Maintenance Mode.

So I go to the website on a separate browser. Go to the online store page. No items are listed. Everything else is there: header & graphics, main navigation menu, sidebar, footer, etc. Just blank where the four products and their "Add to cart" buttons should be.

I go to Commerce / Products - all four products are listed. Nothing changed there.

I go to the Search API page and check the D8 search index. It says "4/4 indexed". For the fun of it I clear all indexed data and re-index. When done it again says "4/4 indexed", but refreshing the web page still shows nothing.

I go to the View for that page. All products show in the preview. I click to "Update preview" . All four products still are listed.

Yet the store page on the website still shows nothing.

**So what am I missing? Why did the upgrade take place with no errors, all of my products are still listed, yet the web page / view does not show any of the products?**

---

Update Sat Oct 7, 9:31 am

Per Patrick Kenny's comment I added the **updatedb** command, but the product page still does not display when completed. Here is my console session for review:

```
# composer update drupal/commerce --with-dependencies

Dependency "drupal/entity" is also a root requirement, but is not explicitly whitelisted. Ignoring.
Dependency "drupal/entity" is also a root requirement, but is not explicitly whitelisted. Ignoring.
Dependency "drupal/entity" is also a root requirement, but is not explicitly whitelisted. Ignoring.
Loading composer repositories with package information
Updating dependencies (including require-dev)
  - Removing drupal/address (1.1.0)
  - Installing drupal/address (1.2.0)
    Loading from cache

> Drupal\Core\Composer\Composer::vendorTestCodeCleanup
  - Removing drupal/profile (1.0.0-beta1)
  - Installing drupal/profile (1.0.0-rc1)
    Loading from cache

> Drupal\Core\Composer\Composer::vendorTestCodeCleanup
  - Updating drupal/commerce dev-2.x (7c2decc => 1118fcb)
    Checking out 1118fcb2d9ddeb29b622a39391bb07d7bbc01674

> Drupal\Core\Composer\Composer::vendorTestCodeCleanup
Writing lock file
Generating autoload files
> Drupal\Core\Composer\Composer::preAutoloadDump
> Drupal\Core\Composer\Composer::ensureHtaccess
Removing packages services cache file:
/home/xxxxxx/www.bbbbbbbb.com/vendor/drupal/console/extend.console.uninstall.services.yml
Creating packages services cache file:
/home/xxxxxx/www.bbbbbbbb.com/vendor/drupal/console/extend.console.uninstall.services.yml

# php drush.php updatedb -y

The following updates are pending:

commerce_order module :
  8203 -   Add the 'locked' field to 'commerce_order' entities.

commerce_product module :
  8202 -   Set the 'published' entity key.
  8203 -   Update the 'status' field.

commerce_order module :
  Update the profile address field.

commerce_product module :
  Expose the status field on every product form.

Do you wish to run all pending updates? (y/n): y
Performing commerce_product_update_8202                [ok]
Performing commerce_product_update_8203                [ok]
Performing commerce_order_update_8203                  [ok]

Post updating commerce_order                           [ok]
Post updating commerce_product                         [ok]
Cache rebuild complete.                                [ok]
Finished performing updates.                           [ok]

# php drush.php cache-rebuild
Cache rebuild complete.

# php drush.php cc drush
'drush' cache was cleared.

```

In addition, someone on Drupal.org suggested that I also needed to run the **entup** command. I tried once again, but when running it I got these errors. Maybe they can provide a clue as to what else may be amiss on my site.

```
# php drush.php entup -y
The following updates are pending:

block_content entity type :
  The block_content.field_select_a_form field needs to be updated.
Do you wish to run all pending updates? (y/n): y
Drupal\Core\Entity\EntityStorageException: Exception thrown while performing a schema update. SQLSTATE[42S02]: Base table or view not found: 1146 Table 'aaaaaaa_bbbbbbb.bbbbbbb_block_content_revision__field_select_a_form'      [error]
doesn't exist: SELECT 1 AS expression
FROM
{block_content_revision__field_select_a_form} t
WHERE field_select_a_form_target_id IS NOT NULL
LIMIT 1 OFFSET 0; Array
(
)
 in Drupal\Core\Entity\Sql\SqlContentEntityStorage->wrapSchemaException() (line 1485 of /home/xxxxxxxx/www.bbbbbbbb.com/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php).
Failed: Drupal\Core\Entity\EntityStorageException: !message in Drupal\Core\Entity\Sql\SqlContentEntityStorage->wrapSchemaException() (line 1485 of                                                                              [error]
/home/xxxxxxxx/www.bbbbbbbb.com/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php).
Cache rebuild complete.                                                                                [ok]
Finished performing updates.

```

# Answer
1) Make sure you've run update.php

2) It is generally risky to go through a year of updates at once. Segmenting them (beta1 -\> rc1, rc1 -\> 2.0) is much safer.

3) The 2.0 release notes have a note about having to grant the "view products" permission to your user roles after updating.
> 0 votes

---
Tags: commerce
---


# Question
Title: Custom field in order not shown on checkout panel
I just discovered the commerce 2 module. I create a date field in the order type ( each customer need to select a shipping date when they bought product ). If I create the order from the adminstrator interface the field is displayed. But when the customer use cart to buy a product the date field is not display ? Can you help ?

# Answer
> 0 votes
There is no code that shows custom order fields at checkout. You will need to write a custom checkout pane plugin.

---
Tags: commerce
---


title: Currency switcher

text:
# Question
Title: Currency switcher
Is there a currency negotiation service in Drupal Commerce 8? How can I change product currency on my multi currencies e-commerce?

# Answer
Please check https://www.drupal.org/project/commerce\_currency\_switcher which is currently in active development. You can use this to switch your currencies and also set either exchange rates between your currencies or have your own price fields per currency for your product.
> 0 votes

---
Tags: 8, commerce
---


# Question
Title: How can I show field from profile2 instead of username depends on user's role?
I have 2 profile2 types (and two common user roles) - "employer" and "applicant". I have "field\_company\_name" in "profile\_employer" and "field\_real\_name" in "profile\_applicant". I want to show field\_company\_name instead of username for employers and field\_real\_name for applicants (and "Editor" string for admins). How can I do that?

# Answer
You can show an alternative name using the Real Name module.

However, you can't show one field for employers and a different field for applicants with Real Name out of the box.

What I would do is reuse the `field_real_name` in `profile_employer` and change the label to the company name; this will allow you to use `field_real_name` as a token for both employers and applicants.

In Drupal, you generally want to reuse fields across content types instead of making new fields if the uses are similar. Doing so makes it much easier to use modules like Real Name, Views, and Rules to manage your entire site.
> 0 votes

---
Tags: 7, entities, users
---


# Question
Title: PathProcessorEntityResourceBC Class not found error after updating to Drupal 8.4
After updating to Drupal 8.4 I now have an error in my browser when trying to load my Drupal site:

**Error: Class '\Drupal\rest\PathProcessor\PathProcessorEntityResourceBC' not found in Drupal\Component\DependencyInjection\Container-\>createService() (line 262 of core/lib/Drupal/Component/DependencyInjection/Container.php)**

If I execute a drush or drupal console command the error is the same but with more of a stacktrace.

I upgraded to Drush 9 which simplifies the error a bit more:

**Service 'rest.path\_processor\_entity\_resource\_bc' for consumer 'path\_processor\_manager' does not implement Drupal\Core\PathProcessor\InboundPathProcessorInterface.**

It looks like I have some dependency missing somewhere. I'm not sure how to track it down.

I have tried "composer install", "composer update", and removing the vendor directory and re-installing the composer packages but nothing has worked yet.

Has anyone had this error or know how to get the missing PathProcessorEntityResourceBC class?

# Answer
I have fixed the error by replacing the 'core' directory with the latest 8.4.0 version. I then checked the git log and differences which were found in these files:

```
modified:   core/scripts/drupal.sh
modified:   core/scripts/password-hash.sh
modified:   core/scripts/rebuild_token_calculator.sh
modified:   core/scripts/run-tests.sh
modified:   core/scripts/update-countries.sh

```

The differences were similar for each file, for example:

```
--git a/core/scripts/update-countries.sh b/core/scripts/update-countries.sh

```

I'm not sure exactly how and why this fixed the missing class, but it seems like I have some differences between the 2 versions of the site.

I then added the changes into git on a new branch and after switching between the 2 branches I don't get the fatal error any more (with or without the updated files).

It's possible that something was cached and as my site and drush was broken I was unable to clear the cache, refreshing the core files must have fixed it.
> 0 votes

---
Tags: 8
---


# Question
Title: How to add checkbox to subscribe newsletter in webform
I'm using D7, and I want to create a newsletter subscribing page with simplenews module.
Other than email column, I want to have fields like name, address, contact number, select field (checkbox) in the form, like in the link below

http://bsgproperty.com/registration\_form.php

However, I found that simplenews is hard to add in fields, so I decided to use webform to create fields and add in a checkbox to subscribe newsletter.

I had successfully created a checkbox, but how can I link this checkbox to newsletter module?

I want the email address entered in webform to be added in newsletter subscriber list after users check the checkbox and submit.

Is there anyway to do this?

# Answer
> 2 votes
If you want to add a checkbox field using the Webform module...

Choose the "Select options" type, enter the value and label, then choose the "Multiple" setting (even if you just want one checkbox to appear), and make sure "Listbox" option is not on.

# Answer
> 0 votes
If writing a custom module is an option, and you need to do a custom integration of Webform with another module, you can:

1. Implement the form\_alter hook to add a new submit handler to the webform client form.
2. On the submit handler do any actions to subscribe your user (or any other actions you need to do). Read the code in the newsletter number to learn how to register a new subscriber; it shouldn't be too hard.

Here is a gist with a bit of example code and comments: https://gist.github.com/noel-rivas/6fc0de57b31ca8c6885db06c92bffab0

This is an old question, and this is a very generic answer of how to use webform submitted data to accomplish some other action, but it might be helpful to you, or others.

---
Tags: 7, webforms, emails
---


# Question
Title: How to export paragraph bundles with features?
According to paragraphs documentation, it's should be possible to export paragraph bundles with features module, but whatever I search, I can't find any option in the features component section for doing this.

**Paragraphs documentation**

> **Features:**
> This module has some overlapping function with field\_collection, but this module has some advantages over field\_collection.
>
> * Different fields per paragraph bundle
> * Using different paragraph bundles in a single paragraph field
> * Displays per paragraph bundle
> * **Bundles are exportable with features.**
> * Entities, so: exportable field bases/instances, usable to show in Search API, used in Views

It seems that features not treated the same for every paragraph types because I can't see `paragraph type` in the features `component` section for some of the created paragraph types.

# Answer
Paragraphs in D8 are entity types. So to create a feature with a paragraph bundle definition, you will need at least:

* The paragraph type definition
* The Entity form display
* The Entity view display
* The field instances you use.
* Core override fields.
* Optionally, you will need the field storage definitions.. but generally it is best to put these in a separate feature like core since fields can be used in multiple places.

The easiest way to get all these is to create a new feature and search for paragraph.\[type-machine-name\]. E.g. I have a paragraph type named banner, so I created a paragraph\_banner feature by searching for paragraph.banner and adding the results.
> 2 votes

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


# Question
Title: Export a specific non-default database using drush sql-dump
My Drupal 7 site connects to multiple databases using a `$databases` array like this:

```
$databases = [
  'default' => [
    'default' => [
      'database' => 'examplecom',
      'username' => 'example',
      'password' => 'sostrongpassword',
      'host' => '',
      'port' => '',
      'driver' => 'mysql',
      'prefix' => '',
    ],
  ],
  'nondefault' => [
    'default' => [
      'database' => 'notdefaultdb',
      'username' => 'notdefaultuser',
      'password' => 'notdefaultpass',
      'host' => '',
      'port' => '',
      'driver' => 'mysql',
      'prefix' => '',
    ],
  ],
];

```

Ideally I want to be able to do something like `drush --database-key=nondefault sql-dump > myfile.sql` but I don't see a way in drush to do that. Is it possible?

I tried creating a custom script to do this like:

```
drush_sql_bootstrap_further();
db_set_active('nondefault');
$sql = drush_sql_get_class();
return $sql->connect(FALSE);

```

And then calling that script with `drush scr foo.php` but the sql connect (or any other command) seem to work against the default database.

# Answer
According to the Drush 8 docs, there is a --database=key option that does what you want.

I've verified it against a D8 site with multiple databases using the command:

```
drush @dev sql-dump --database="blog_import" > ~/tmp/blog_import.sql

```

The drush sql-cli command also has the same option so you should be able to import the dump using a command like:

```
drush @dev sql-cli --database="blog_import" < ~/tmp/blog_import.sql

```
> 5 votes

---
Tags: 7, database, drush
---


# Question
Title: Installing SMTP module, not able to enable module
On a Drupal site that I've inherited, I'm trying to fix an issue where the contact form isn't sending out emails. To that end, I'm attempting to install, enable, and configure the SMTP module to see if that will fix things.

I've attempted to install the SMTP module via direct link as well as uploading it myself. While the module appears in the site admin list, I'm not able to enable it (just goes to a yellow "on", and then back to disabled).

What are some ways to figure out what the conflict or problem may be?

# Answer
Most likely, your host provider does not have one or more of the PhP extensions enabled for your site. Check the status page / php info to see if the following items listed in the readme are there:

> ## REQUIREMENTS
>
> * Access to an SMTP server
> * The following PHP extensions need to be installed: ereg, hash, date & pcre.
> * Optional: To connect to an SMTP server using SSL, you need to have the openssl package installed on your server, and your webserver and PHP installation need to have additional components installed and configured.

If the requirements are there, check the watchdog error log (you probably have).

If possible, check the actual server error logs.

If you can't check the error logs, you might try going to the Logging and Error settings in the Devel area and setting the option to display all errors with a stacklog.

NOTE: This should be reset once your debugging is done.
> 0 votes

---
Tags: 8
---


# Question
Title: Create an EventSubscriber for a specific module
I'm attempting to make something occur at a specific event in the GatherContent module found here https://www.drupal.org/project/gathercontent

Based on the information here http://help.gathercontent.com/importing-and-exporting-content/drupal-integration/drupal-integration-extending-the-module-using-the-api and several tutorials and documentation

I created a module with the code entered like so

my\_gathercontent.services.yml

```
services:
  my_gathercontent:
    class: '\Drupal\my_gathercontent\EventSubscriber\MyGatherContentSubscriber'
    tags:
      - { name: 'event_subscriber' }

```

src/EventSubscriber/MyGatherContentSubscriber.php

```
namespace Drupal\my_gathercontent\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Event Subscriber MyGatherContentSubscriber.
 */

class MyGatherContentSubscriber implements EventSubscriberInterface {
    public function onGatherContentPostImport(DrupalgathercontentEventPostImportEvent $event) {
        \Drupal::logger('my_gathercontent')->notice('This is a test');
        drupal_set_message("Debug: This is a test.");
        var_dump($event);
    }
    public static function getSubscribedEvents() {
        $events['gathercontent.post_import'] = ['onGatherContentPostImport'];
        return $events;
    }
}

```

And none of those messages get logged. I do now receive a page not found message after performing an action that should trigger that event. I'm not sure what I'm doing wrong.

Is there something wrong with the way I'm attempting to subscribe to the event?

# Answer
> 3 votes
Each event in the `$events` array should itself be an array; try:

```
$events['gathercontent.post_import'][] = ['onGatherContentPostImport'];

```

---
Tags: 8, event-subscribers
---


# Question
Title: How to programmatically embed iframe in a page
I am trying to render a page with iframe embedded in it. My code is as follow

```
public function giveHugs() {
  return [
    '#type' => 'inline_template',
    '#template' => '<iframe frameborder="0" style="border: none;" width="400" height="400" src="{{ url }}"></iframe>',
    '#context' => [
      'url' => 'yahoo.com'
    ]
  ];
}

```

Some how its not rendering the iframe , rather it is embedding the drupal site it self. How can i render iframe in a page?

# Answer
> 2 votes
Unless you provide an absolute URL, Drupal will treat it as relative. So `yahoo.com` becomes `https://example.com/yahoo.com`, which explains why you're seeing your own site embedded.

To solve, just use an absolute URL:

```
'#context' => [
  'url' => 'https://yahoo.com'
]

```

---
Tags: theming, 8
---


# Question
Title: Some info missing on Drupal 7 ckeditor accordion instructions
Trying go to get this working:

https://www.drupal.org/project/ckeditor\_accordion

But it's not working, step 5 and 6 don't exist or I can't find them in Drupal 7, are these instructions for Drupal 8 only?

```
 5.Scroll down to the bottom to the input Allowed HTML tags
 6.Find and replace <dl> with <dl class>

```

Can't find 5 and 6 in the backend

# Answer
Go to */admin/config/content/formats* and click configure on the format that you'll be using.

Scroll all the way down and click on "Limit allowed HTML tags" tab. Now replace `<dl>` with `<dl class>`
> 1 votes

---
Tags: views, nodes
---


title: How does the batch API work internally?

text:
# Question
Title: How does the batch API work internally?
I ran into a timeout issue using migrate the other day and started to wonder how the Batch API works internally.

The way I understand it is that in its simplest form you'll pass an array of values (nids for example) and a function to operate on those values. The batch API then processes a fixed number of those values with each request until it's finished.

When a batch is running the page seems to use Ajax requests to show the progress of the batch operation (% done and messages). I assume it waits until the request has finished to update the progress and then start the next request immediately afterwards?

If the page with the batch request is closed does the batch processing stop? Will it restart when the same URL is opened again? The migrate module sometimes continues but it's probably using queues?

# Answer
This is how batch works (Based on my Understanding)

## 1. **Initialize**

1. Initialize the batch processing. Based on the clients(Browsers) configuration on whether JavaScript is enabled or not.
2. JavaScript-enabled clients are identified by the 'has\_js' cookie set in drupal.js. If no JavaScript-enabled page has been visited during the current user's browser session, the non-JavaScript version is returned.
3. If ***JavaScript enabled*** Batch uses ***ajax*** request the keep the connection alive across the request.
4. If ***JavaScript is not enabled*** Batch uses sets a **meta tag** in html to make ***regular refresh intervals*** to the keep the connection alive across the request.

(This is how the progress bar is updated on the progress of the Job Done.)

## **Batch Process**

1. For starting the process, Batch creates a Queue and adds all the ***operations(functions and arguments)*** that you define in the batch array like,

```
$batch = array (
'operations' => array(
  array('batch_example_process', array($options1, $options2)),
  array('batch_example_process', array($options3, $options4)),
  ),
'finished' => 'batch_example_finished',
'title' => t('Processing Example Batch'),
'init_message' => t('Example Batch is starting.'),
'progress_message' => t('Processed @current out of @total.'),
'error_message' => t('Example Batch has encountered an error.'),
'file' => drupal_get_path('module', 'batch_example') . '/batch_example.inc',
);

```

Additionally it also assigns a batch id which is unique across the batches.
2. Now Batch calls claims the Queue items one by one and executes the function defined with the arguments that are defined in it.
3. This is a crucial part, The function(Operation) that implements the batch operation should chunk the data and process the data very efficiently keeping in mind of ***PHP's Memory limit, Time out***. Failing to do so will end up in your problem.

> I ran into a timeout issue using migrate the other day and started to wonder how the batch API works internally.

**The Batch Function**

The functions that implement Batch should take of the following things very carefully,

* Number of Items within the operations to process like,

```
if (!isset($context['sandbox']['progress'])) {
$context['sandbox']['progress'] = 0;
$context['sandbox']['current_node'] = 0;
$context['sandbox']['max'] = db_result(db_query('SELECT COUNT(DISTINCT nid) FROM {node}'));
}

```
* Limiting the number of items to process in one function call like setting up a limit,

```
// For this example, we decide that we can safely process 5 nodes at a time without a timeout.
$limit = 5;

```
* Update on the process to post-processing like,

```
// Update our progress information.
    $context['sandbox']['progress']++;
    $context['sandbox']['current_node'] = $node->nid;
    $context['message'] = t('Now processing %node', array('%node' => $node->title));

```
* Informing the Batch engine whether the Batch is completed or Not like,

```
// Inform the batch engine that we are not finished,
// and provide an estimation of the completion level we reached.
if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
  $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
 }

```

Most of the Above Points are taken care of the Drupal's Core batch operations if it is Missed in the Implementing function. But it is always best to define in the implementing function

## Batch Finished callback

* This is the last call back called when defined in the batch array Usually a report of how much processed etc...

# ANSWERS

> If the page with the batch request is closed does the batch processing stop? Will it restart when the same url is opened again? The migrate module sometimes continues but it's probably using queues?

Yes, Ideally it should restart the batch and as said above it is based on the function you implement.

To **solve your problem** of PHP Time out use Drush batch which is available in migrate module, But first dig out migrate's batch functions and try to chunk your processing data.
> 40 votes

# Answer
> If the page with the batch request is closed does the batch processing stop?

Yes, it will be stopped.

> Will it restart when the same url is opened again? The migrate module sometimes continues but it's probably using queues?

As Dinesh said its depends on the implementation.

You should run migration using drush, because

> Drush runs at the command line and is not subject to any time limits (in particular, PHP's max\_execution\_time does not apply). So, when you start a migration process running via drush, it simply starts up and keeps running until it's done.
>
> When running processes through a web interface, the PHP max\_execution\_time (typically 30 seconds if not less) applies. Thus, for long-running processes we need to use the Batch API, which manages the breaking up of a process across multiple requests. So, a migration process will start up, run for 25 seconds or so, then stop and let the Batch API issue a fresh page request, in which the migration process is restarted, ad infinitum.
>
> So, understanding that, why is Drush better?
>
> **It's faster**
>
> The Batch API introduces a lot of overhead - shutting down and reinvoking the page requests, the migration process needs to run through all the necessary constructors again, database connections reestablished and queries rerun, etc. And, for a partial import, it needs to pick up where it left off - if the first 500 source records have been imported, it needs to find the 501st record. Depending on your source format and how its constructed, this may or not scale - if you're using highwater marks with an SQL source, the query itself can eliminate the earlier records and start right where you left off. If not, then Migrate needs to scroll through the source data looking for the first non-imported record. With, say, a big XML file as your source, after many iterations it may very well take longer than your PHP max\_execution\_time to get to where you can pick up, and your migration can stall.
>
> **It's more reliable**
>
> Running migrations through your browser adds your desktop, and your local Internet connection, as points of failure. A network glitch when Batch API is moving to the next page request, a browser crash, an accidental close of the wrong tab or window can all interrupt your migration. Running in drush reduces the moving parts - you eliminate your desktop and local Internet connection as factors.
>
> **It's more helpful**
>
> If something does go wrong when running in Drush, if there are any useful error messages you'll see them. Failures using the Batch API often get swallowed up and all you get to see is the completely useless "An AJAX HTTP request terminated abnormally. Debugging information follows. Path: /batch?id=901&op=do StatusText: ResponseText: ReadyState: 4 ".

You can find more information on this here.

In the meantime if you want to run the batch even if the browser window is closed, consider **Background Process** module. It has a submodule **Background Batch** which does the trick.

> This modules takes over the existing Batch API and runs batch jobs in a background process. This means that if you leave the batch page, the jobs continues, and you can return to the progress indicator later.
> 10 votes

# Answer
Carefully understand Batch API and These modules will help you:

1-Progerss This is an attempt to implement a generic framework for keeping track of any progress

2- Background progress takes over the existing Batch API and runs batch jobs in a background proces
> 0 votes

---
Tags: 7, batch-operations
---


# Question
Title: Passing arguments to a node with an alias url
There is a similar issue in here: Passing an argument to a node causes 404

But there is no real viable solution. I tried using the sub-pathauto module but the restiction of 8 arguments is too little, since the urls will look something like this:

`www.site.com/alias/key/value-1/key/value-2/key/value-3/key/value-4`

and it can go on for a while. It works when instead of `alias` i have `node/nid`.

Is it possible to have it work with any amount of dynamic arguments?

# Answer
> 0 votes
Iv'e not tested with more than 8 args, but I enabled path\_alias\_xt when passing args to a node Alias with /mynode/term-name/tid and the 404s magically went away.

https://www.drupal.org/project/path\_alias\_xt

Further more using print\_r(arg(2)); in the node template prints "term-name"

---
Tags: path-aliases
---


# Question
Title: “Show as expanded” selected but children menu items not displaying
I've main menu navigation and some links checked "Show as expanded" and have child items under it. In the main site page, only parent items are appearing and child items not appearing. I've created a twig template "menu--main.html.twig" and kint the item and found that "is\_expanded" is FALSE and there are no child items.

# Answer
I've solved it. I've figured that I should have to configure the block and extend the menu levels
> 1 votes

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


# Question
Title: What is the best protocol for uploading images in batch via FTP?
What is the best protocol for uploading images in batch via FTP?

Let's say my website has 3 images.

Original size is 1000x1000

I upload all images via backend as "image upload".

Later on, I want to substitute all 1000x1000 images with identical images with same name but at size 400x400.

Curious as to what is the best workflow for Drupal for this scenario.

# Answer
> 1 votes
> I want to substitute all 1000x1000 images **with identical images** with same name but at size 400x400.

Since they are identical, simply use image styles. Create an image style of 400x400 and assign it to your content type's image field OR in your image field settings in a View.

Watch: How to apply image styles in Drupal

---
Tags: media
---