# Question
Title: File Transfer failed, reason: Cannot create directory /var/www/html/modules
I have installed Drupal 8 on EC2. I am trying to install a module (`simple_sitemap-8.x-2.5.tar.gz`).

When I use the interface, I get a failed transfer message:

I have `chmod a+x` the directory (which already exists), but to no avail.

How should I solve this one? Is there a workaround to install modules without FTP?

# Answer
The `chmod a+x` isn't enough, the directory should have write permission for HTTP server user, so try:

```
chmod 755 /var/www/html

```

Prefix with `sudo` if it's necessary.

or if you've already some files in it, try:

```
chmod -R u+rwX,go+rX,go-w /var/www/html

```

and if you're using Apache, you should change the ownership by:

```
chown -R www-data:www-data /var/www/html

```

If `www-data` is not correct, you can find the Apache user by the following command:

```
ps axho user,comm|grep -E "httpd|apache"|uniq|grep -v "root"|awk 'END {if ($1) print $1}

```
> 5 votes

# Answer
**Assuming you're using Ubuntu as your EC2 OS:**

If you were to use FTP, right now it would work, while browser install method doesn't. To allow browser method to work:

```
cd /var/www/html

sudo chown www-data -R modules

```

Note that the browser method works now, but FTP won't work. In the future, if you decide to use FTP, you will need to switch it back to ubuntu as the folder owner:

```
cd /var/www/html

sudo chown ubuntu -R modules

```
> 1 votes

# Answer
I know this may sound silly but I've had the same issue and all I had to do was unblock the port 21/22 on my EC2's Security Group. Thought maybe as simple as that -- I had been stuck for over an hour on permissions.
> 0 votes

---
Tags: 8, installation
---


title: View theme override in drupal 8

text:
# Question
Title: View theme override in drupal 8
I am new to drupal 8 and i need to override a views template. So, for that I have enabled theme debug in services.yml to view the twig template suggestion name.

This is my view theme debug.

```
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'views_view_unformatted__test_content_view' -->
<!-- FILE NAME SUGGESTIONS:
   x views-view-unformatted--test-content-view.html.twig
   x views-view-unformatted--test-content-view.html.twig
   * views-view-unformatted.html.twig
-->

```

Then, I created the file in templates of drupal8 theme and the theme file calls. I used themename\_views\_view\_unformatted\__test\_content\_view() function to override in themename.theme file but the function doesn't called.

Is there anyway to override the variables coming to the twig template. Can anyone give me suggestion to override the views template.

Thanks in advance.

# Answer
> 4 votes
In your case 'views\_view\_unformatted\__test\_content\_view' is the theme hook in the render array. In Drupal 8 that will make it possible to use following preprocess functions to modify the variables before they get to the template:

* themename\_preprocess\_views\_view\_unformatted\__test\_content\_view()
* themename\_preprocess\_views\_view\_unformatted()

There is more information about preprocess functions available here.

# Answer
> 0 votes
The best place to start would be to look at the theme suggestions for views, however they're currently missing from core. This is a known bug in Drupal 8 core, currently being worked on for version 8.6

If you need the functionality to see the proper theme suggestions now, you have two options:

1. Try the patches from comment #22 (or more recent) on Issue #2923634 and the patches on Issue #2752443. Read the comment thread on #2923634 to get a full understanding of what's going on here.
2. Or use the well-vetted patch from comment #139 on Issue #2118743 which has been postponed in favor of option 1 above.

I'm using the patch from option 2 (#2118743) successfully. Please note that this does go against the standard core contributor recommendations. But the reason is because #2118743 has a single, well-vetted and working patch for something that is only enabled / used during development, and instead of needing to test out various combinations of two separate patches that are still under development. Once the better solution (#2923634 and #2752443) get fixed in core, #2118743 should be obviated and no longer required.

Combining this solution with @lauriii's explanation of template preprocess functions, you should be able to override the variables you need.

If that doesn't work, and you need to dig deeper, then you can alter query and or result data with the Views runtime hooks (eg `hook_views_pre_render` or `hook_views_post_execute`). Place these functions inside a `module_or_themename.views_execution.inc` file in your Drupal 8 custom module or theme. Please note that the documentation is currently very thin about these functions for Drupal 8, but in most cases the Drupal 7 examples can also helpful.

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


# Question
Title: 8 - How to Get Values From $variables hook_preprocess_commerce_order_receipt?
So thankful for all the help on here, but still so baffled as to how Im not able to just quickly determine how to pull these values out of certain arrays and objects.

Trying to get the order id (and other values) from the frickin $variables array in hook\_preprocess\_hook

**Code** **afc.theme**

```
function afc_preprocess_commerce_order_receipt(&$variables) {
  dpm($variables['order_entity']);
  \Drupal::logger('afc_theme')->notice('running');
}

```

**Some of the Output**

```
stdClass Object
(
    [__CLASS__] => Drupal\commerce_order\Entity\Order
    [values:protected] => Array
        (
            [order_id] => Array
                (
                    [x-default] => 182
                )

            [type] => Array
                (
                    [x-default] => default
                )

            [uuid] => Array
                (
                    [x-default] => c8b1c210-0e6e-4efb-a59d-84b28d4dadfe
                )

            [order_number] => Array
                (
                    [x-default] =>
                )

            [store_id] => Array
                (
                    [x-default] => 1
                )

            [uid] => Array
                (
                    [x-default] => Array
                        (
                            [0] => Array
                                (
                                    [target_id] => 1
                                )

                        )

                )

```

Ive tried various **wrong** things like:

```
$variables['order_entity'] = $order;
dpm($order->get("order_id")->getValue());
dpm($variables->get("order_id")->getValue());
dpm($variables['order_entity']['order_id'];

```

**1. How do I get the order\_id from this $variables object?**

**2. How/where did you find this information telling you how to get this value out?**

# Answer
> 2 votes
> How do I get the order\_id from this $variables object?

All entities have an `id` method, inherited (or perhaps overridden) from `Entity::id`. From your debug output `$variables['order_entity']` appears to be one such entity, so:

```
$order_id = $variables['order_entity']->id();

```

> How/where did you find this information telling you how to get this value out?

Short answer, in the source and the docs (following/finding isn't always straightforward though). For example if you've read the Introduction to Entity API in Drupal 8, you'll intuitively know that a `Drupal\commerce_order\Entity\Order` is an entity type, both by the folder structure and its annotation, and you can start thinking about how to address an object of that type in more generic terms.

That leads to searches like "Drupal 8 get entity id" or "Drupal 8 get entity field value programatically", and Google will dutifully tell you everything you need to know.

If you can spare a bit of time to follow the class hierarchy up the chain, and get at least a broad idea of what each class does and how it works, that will probably take some pain out of future encounters with the entity API too.

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


# Question
Title: Views Remember Last Selection Back Button D8
I am having trouble with "Remember last selection" on views in D8. If I click a link away from the view and click back it does not remember my last selection. If I then refresh the page it does. This view does use Ajax and I cannot change that. Also I read somewhere that it may be due to caching from the headers.

If so what is the best way to add / change headers on a View response?

# Answer
> 1 votes
Looks like you have to subscribe to an event and manipulate the headers from there. I originally found this answer on how to manipulate headers in D8 here.

This will force a request to the server:

This file will go into your mymodule/src/EventSubscriber folder.

```
namespace Drupal\mymodule\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;

class NoCacheSubscriber implements EventSubscriberInterface {

  public function RemoveCacheHeaders(FilterResponseEvent $event) {
    $response = $event->getResponse();
    $response->headers->set('Cache-Control', 'private, must-revalidate, max-age=0, no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
  }

  public static function getSubscribedEvents() {
    $events[KernelEvents::RESPONSE][] = array('RemoveCacheHeaders', -10);
    return $events;
  }
}

```

Then this will go into the your mymodule folder as mymodule.services.yml

```
    services:
  remove_cache_options_subscriber:
    class: Drupal\mymodule\EventSubscriber\NoCacheSubscriber
    tags:
      - { name: event_subscriber }

```

---
Tags: views, caching
---


title: profile2 image field not show images

text:
# Question
Title: profile2 image field not show images
I tested my profile2 image field at upload moment and the file upload successfully and unexpectedly after save changes the image fid appears like 0 but the image don't show.

What I do?

Thanks!

# Answer
Finally I found that I have an module conflict, if you decide to use DDF (Dynamic Dependent Fields) you must think before make tests with profile2 fields.
> 0 votes

---
Tags: 7, users
---


# Question
Title: How to check that an attribute not exists in an element with PHPUnit?
I'm trying to test that an element don't exists in a page. I know that exists the `elementAttributeExists()` method that checks that an attribute exists in an element. But I can't find any method like `elementAttributeNotExists()` to check that an attribute don't exists in an element.

So, with the following code I can check that the 'autocomplete' attribute is present in the #edit-pass element:

```
  public function testLoginForm() {
    // Going to the log in.
    $this->drupalGet('/user/login');

    // Checking that the autocomplete is not set.
    $this->assertSession()->elementAttributeExists('css', '#edit-pass', 'autocomplete');
  }

```

But how I can check that the autocomplete attribute is not present?

# Answer
You can check if there is a matching element for `#edit-pass` which has the attribute. Because `#edit-pass` targets only one element this has the same result when you know that this element exists:

```
$this->assertSession()->elementNotExists('css', '#edit-pass[autocomplete]');

```
> 2 votes

---
Tags: 8, testing
---


# Question
Title: How to alter the user login response data
I'm just looking into adding some more data to the Drupal 8 API user login response.

```
curl --header "Content-type: application/json" --request POST --data '{"name":"username", "pass":"password"}' http://drupal8.localhost/user/login?_format=json

```

The response is like:

```
{
    "current_user": {
        "uid": "100",
        "roles": [
            "authenticated"
        ],
        "name": "username"
    },
    "csrf_token": "4gRg8XElB1jRp3xu1a4vm2oYiTCXLaoO8Ii72Dwe1kd",
    "logout_token": "gnUt53JZcM7KEFizLOFe996DTXgEqj7RyzhMwsmUssZ"
}

```

How can one add additional data to the user login API response?

I've looked into adding a custom `Normalizer`, but seems a bit tricky to intercept the `/user/login` response and curious if any other suggestions on it, thanks.

# Answer
OK, I'd like to post one more answer approach, using the response event listener (with thanks to @Berdir). This is the one I'm using in the end as it avoids duplicating the login function logic. The previous answer may still be useful if you want to alter the actual login logic flow as well.

The event subscriber class

```
<?php

namespace Drupal\example\Listener;

use Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Drupal\Component\Serialization\Xml;
use Drupal\Component\Serialization\Json;

/**
 * Class ExampleLoginListener.
 *
 * @package Drupal\example
 */
class ExampleLoginListener implements EventSubscriberInterface
{

  /**
   * @var path.current service
   */
  private $currentPath;
  /**
   * @var jwt.authentication.jwt service
   */
  private $jwtAuth;

  /**
   * Constructor with dependency injection
   */
  public function __construct($currentPath, $JwtAuth) {
    $this->currentPath = $currentPath;
    $this->jwtAuth = $JwtAuth;
  }

  /**
   * Add JWT access token to user login API response
   */
  public function onHttpLoginResponse(FilterResponseEvent $event) {
    // Halt if not user login request
    if ($this->currentPath->getPath() !== '/user/login') {
      return;
    }
    // Get response
    $response = $event->getResponse();
    // Ensure not error response
    if ($response->getStatusCode() !== 200) {
      return;
    }
    // Get request
    $request = $event->getRequest();
    // Just handle JSON format for now
    if ($request->query->get('_format') !== 'json') {
      return;
    }
    // Decode and add JWT token
    if ($content = $response->getContent()) {
      if ($decoded = Json::decode($content)) {
        // Add JWT access_token
        $access_token = $this->jwtAuth->generateToken();
        $decoded['access_token'] = $access_token;
        // Set new response JSON
        $response->setContent(Json::encode($decoded));
        $event->setResponse($response);
      }
    }
  }

  /**
   * The subscribed events.
   */
  public static function getSubscribedEvents() {
    $events = [];
    $events[KernelEvents::RESPONSE][] = ['onHttpLoginResponse'];
    return $events;
  }

}

```

and the `example.services.yml` entry

```
services:
  example.login_response_listener:
    class: '\Drupal\example\Listener\ExampleLoginListener'
    arguments: ['@path.current', '@jwt.authentication.jwt']
    tags:
      - { name: event_subscriber }

```

In this way, we can add the JWT `access_token` to the `/user/login?_format=json` API response.
> 4 votes

# Answer
OK, after some more study, I've found a reasonable solution. Posting here for the benefit of others. This one overrides the login route controller to add the custom data.

```
/**
 * @file
 * Contains \Drupal\example\Routing\RouteSubscriber.
 */

namespace Drupal\example\Routing;
use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;

/**
 * Listens to the dynamic route events.
 */
class RouteSubscriber extends RouteSubscriberBase {
  /**
   * {@inheritdoc}
   */
  public function alterRoutes(RouteCollection $collection) {
    // Alter user/login API route to return more data
    if ($route = $collection->get('user.login.http')) {
      $route->setDefaults(array(
        '_controller' => '\Drupal\example\Controller\ExampleUserAuthenticationController::login',
      ));
    }
  }
}

```

and then in the custom class handler

```
use Drupal\user\Controller\UserAuthenticationController;

class ExampleUserAuthenticationController extends UserAuthenticationController implements ContainerInjectionInterface {

  /* Add the custom login request handler with extra response data here */
  public function login(Request $request) {
    // ...
    $response_data['foo'] = 'bar';
    // ...
  }

}

```

It would be nice if it was possible to alter the response data only, without the login function override. However, this approach is working for me.
> 2 votes

---
Tags: users, 8
---


# Question
Title: Node title inside layout (Layout Discovery + Field Layout)
Just tried the new core modules Layout Discovery and Field Layout and I want to render the title of a node between two fields. Without these modules, node's title can be rendered between other fields very simple by using inside `node.twig.html` something like:

```
{{ content.field_image }}
{{ label }}
{{ content.body }}

```

But when I try to use `{{ label }}` inside the registered layout template, nothing gets rendered. Can somebody help me?

Thank you in advance.

# Answer
> 0 votes
I wasn't able to get variables inside layouts due to this bug https://www.drupal.org/project/drupal/issues/2861840 Drupal 8.5 fixed the problem. Now, inside mytheme.theme if I put this:

```
function MYTHEME_preprocess_layout(&$variables) {
  $request     = \Drupal::request();
  $route_match = \Drupal::routeMatch();
  $title       = \Drupal::service('title_resolver')->getTitle($request, $route_match->getRouteObject());
   $variables['node_title'] = $title;
}

```

I'm able to use `{{ node_title }}` inside layouts.

---
Tags: theming, entities
---


# Question
Title: Can I remove the "Item successfully added to your cart" popup?
Can I removed the *Item successfully added to your cart* popup in Drupal Commerce?

>

# Answer
> 0 votes
Goto: **/admin/config/workflow/rules** and **disable** '**Display an Add to Cart message**' Rule.

Thank You.

---
Tags: commerce
---


title: Display webform results

text:
# Question
Title: Display webform results
I want to display webform submitted data in a view. How to recover submissions of my webform in a list?

I think that I can use hook\_views\_query\_alter to change my view's query.

If that's right, how can I implement it?

Any idea please? Thank you!

# Answer
you need to **add new view** '**admin/structure/views/add**' and into Show select **webform submission** continue and edit ... you can get all the submission list into the view.

Add field webform submission data:value

Then select webform node and field you want.

You can see the fields like this

View result

So, you can get all fields which you created when you create a web form.

Thank You.
> 0 votes

# Answer
Yuu can use https://www.drupal.org/project/webform\_mysql\_views to display submission.

For More info you can visit : https://knackforge.com/blog/sivaji/displaying-webform-submission-data-drupal-views
> 0 votes

---
Tags: 7, views, hooks, webforms
---


# Question
Title: Why does in Drupal 8 there are two different namespaces for test cases?
In Drupal 8 core modules tests are under two different namespaces which maps to two different directories under the module.

```
\Drupal\Tests\<mymodule>\<TestSuiteType> => <mymodule>/tests/src/<TestSuiteType>
\Drupal\<mymodule>\Tests => <mymodule>/src/Tests direcotry.

```

For example in field\_ui module.

```
\Drupal\field_ui\Tests\FieldUIDeleteTest => field_ui/src/Tests/FieldUIDeleteTest.php
\Drupal\Tests\field_ui\Functional\EntityDisplayModeTest => field_ui/tests/src/Functional/EntityDisplayModeTest.php

```

Can someone please explain the reason behind this and any advantage of writing test cases under two different namespace for the same module?

# Answer
They're just different kinds of tests, with different requirements/dependencies, and so they're split up.

From PHPUnit file structure, namespace, and required metadata:

> # File structure and namespace
>
> There's a special relationship between the location of test files within the file structure, the namespace they use, and the class which they extend.
>
> ## Drupal Unit Test Suites: Auto-detected Tests
>
> Drupal 8 uses a number of test suites to allow for choosing between different kinds of tests to run.
>
> Drupal 8 has the following test suites:
>
> * Simpletest: Legacy tests based on the Drupal version of the Simpletest framework.
> * Unit: PHPUnit-based tests with minimal dependencies.
> * Kernel: PHPUnit-based tests with a bootstrapped kernel, and a minimal number of extensions enabled.
> * Functional: PHPUnit-based tests with a booted Drupal instance.
> * FunctionalJavascript: PHPUnit-based tests which use PhantomJS to perform tests of Javascript functionality.
>
> Drupal's test system can discover these different test suites for core, core extensions, and contrib extensions, as long as the tests are placed within the proper directories so they can be discovered as belonging to one of the test suites listed above.
>
> **Simpletest-based** tests must be placed in an extension, within that extension's src/Tests directory. They will have a namespace of \Drupal\\$extension\Tests.
>
> **PHPUnit-based**: Generally, the other suites must be within a tests/src/$suite\_type/ directory. These tests will have a namespace of \Drupal\Tests\\$extension\\$suite\_type.
>
> **Traits**: The third class is traits. It is possible to write a trait which will be discovered and can be used by the various different test types. Each test suite will discover the trait if it is placed in the tests/src/Traits directory, and the trait will have a namespace of \Drupal\Tests\\$extension\Traits.
>
> Note that the class names must **END** with the word Test. The test methods within the class must **START** with the word test.

Simpletest Class, File, and Namespace structure also provides a bit more insight.
> 2 votes

---
Tags: testing
---


title: Permission errors

text:
# Question
Title: Permission errors
What file permission should I change to fix this error?

> The specified file temporary://fileo7XApl could not be moved/copied because the destination directory is not properly configured.
>
> This may be caused by a problem with file or directory permissions. More information is available in the system log. https://ftp-origin.drupal.org/files/translations/8.x/address/address-8.x-1.3.de.po could not be saved to translations://.

I installed Drupal 8 Open Social and tried installed some languages, but I get the following errors every time.

>

I set file permissions and ownership with `chmod -R u+rwX,go+rX,go-w /var/www/html && chown -R www-data:www-data /var/www/html`.

# Answer
in admin/config/media/file-system you specify what the temporary file system path will be.

That path will have to be writable by your web server, in apache case it's www-data

Your best option would be to create a temporary directory that is owned by www-data

mkdir temp sudo chown www-data:www-data temp

My structure is usually the following:

/var/www/WEBSITE/public\_html/ - for the root directory

/var/www/WEBSITE/public\_html/sites/default/files - for the public filesystem (this is default)

/var/www/WEBSITE/private/ - for private files directory (also writable by the web server but not accessible over the web)

and I use the generalroot /tmp , but you could put the temporary folder inside your private folder which requires no change or create an extra directory owned by www-data in

/var/www/WEBSITE/temp/

Cheers!
> 1 votes

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


title: Show related entites on entity view

text:
# Question
Title: Show related entites on entity view
I have two entities, article and author which are related to each other.

When I display an author I want to display also all articles of him.

I was thinking about a block which is displayed on some url patterns, but I didn't find a way to pass the current entity as filter for the block.
Nevertheless I am not sure if it is a good practice to define blocks and place them in the layout when they are only get rendered on some pages.

How can I display content related to other content?

**EDIT:**

Trying to use contextual filter:

* Add a relationship to the other entity, but which one should I use?
    + Content referenced from
    + Content using
* Add contextual filter using default value, content ID from URL

# Answer
You can use Contextual filters on Drupal 8 to pass the current entity as the filter. Have a look at: https://valuebound.com/resources/blog/how-to-use-contextual-filter-in-drupal-8

and https://www.youtube.com/watch?v=FUlj6-Rb7Ds for more details.
> 0 votes

---
Tags: 8, entities
---


# Question
Title: How do I make the page created from my module visible only to anonymous users?
I programatically created a page using the following code.

```
/**
* Implements hook_menu().
*/
 function page_prog_menu() {
   $items['page_prog/custom'] = array(
     'title' => 'My Custom page',
     'page callback' => 'page_prog_custom',
     'access arguments' => array('access content'),
   );
   return $items;
 }

 /**
 * Custom callback function.
 */
 function page_prog_custom() {
   $content['raw_markup'] = array(
     '#type' => 'markup',
     '#markup' => '<p>Hello world</p>',
   );

 return $content;
 }

```

I need to make this page visible only to anonymous users. How can I achieve this?

I have tried with `hook_permission()`, but it doesn't help.

```
/**
* Implements hook_permission().
*/
function page_prog_permission() {
  return array(
    'access page_prog content' => array(
    'title' => t('Access content for the pages created programatically'),
    )
  );
}

```

# Answer
Try this code:

```

/**
* Implements hook_menu().
*/
 function page_prog_menu() {
   $items['page_prog/custom'] = array(
     'title' => 'My Custom page',
     'page callback' => 'page_prog_custom',
     'access callback' => 'user_has_custom_role',
     'access arguments' => array('access content'),
   );
   return $items;
 }

 /**
 * Custom callback function.
 */
 function page_prog_custom() {
   $content['raw_markup'] = array(
     '#type' => 'markup',
     '#markup' => '

Hello world

',
   );

 return $content;
 }

 function user_has_custom_role($roles) {
    if (user_is_anonymous()) {
       return TRUE;
    }
    else {
        return FALSE;
    }
}

```
> 0 votes

# Answer
'access arguments' =\> array('access page\_prog content'),
> 0 votes

# Answer
Change the access callback to `user_is_anonymous()`, and the page will be visible just to anonymous users.

```
/**
 * Implements hook_menu().
 */
function page_prog_menu() {
  $items['page_prog/custom'] = array(
    'title' => 'My Custom page',
    'page callback' => 'page_prog_custom',
    'access callback' => 'user_is_anonymous',
  );
  return $items;
}

/**
 * Custom callback function.
 */
function page_prog_custom() {
  $content['raw_markup'] = array(
    '#type' => 'markup',
    '#markup' => '<p>Hello world</p>',
  );

  return $content;
}

```

This is what the User module does for *user/login* route, which is only accessible to anonymous users. (See `user_menu()`.)

```
  $items['user/login'] = array(
    'title' => 'Log in',
    'access callback' => 'user_is_anonymous',
    'type' => MENU_DEFAULT_LOCAL_TASK,
  );

```

The alternative (which I don't suggest, but I show here just to point out what is wrong in the code you tried to use) would implementing a custom permission that is then used for that page, and assigned only to the anonymous users (i.e. every other role, including the *authenticated user*, will not have the custom permission used from that page).

```
/**
 * Implements hook_menu().
 */
function page_prog_menu() {
  $items['page_prog/custom'] = array(
    'title' => 'My Custom page',
    'page callback' => 'page_prog_custom',
    'access arguments' => 'access page_prog content',
  );
  return $items;
}

/**
 * Custom callback function.
 */
function page_prog_custom() {
  $content['raw_markup'] = array(
    '#type' => 'markup',
    '#markup' => '<p>Hello world</p>',
  );

  return $content;
}

/**
 * Implements hook_permission().
 */
function page_prog_permission() {
  return array(
    'access page_prog content' => array(
    'title' => t('Access content to the custom pages'),
  ));
}

```

The code you shown doesn't work because the access arguments were not set to an array containing the custom permission defined from the module. Then, it would not work if the custom permission is not assigned to anonymous users, and just to them.
> 0 votes

---
Tags: 7, routes
---


# Question
Title: Calling a module function name in Ajax URL
I am developing a custom payment gateway for Drupal Commerce. I am getting some problems calling a custom module function from an AJAX URL.

How do I call a module function from a custom AJAX request?

```
function custom_gateway_settings_form($settings) {
  $form = array();

  $form['code'] = array(
    '#type' => 'textfield',
    '#title' => t('Code'),
    '#maxlength' => 100,
    '#description' => t('Code.'),
    '#prefix' => '<div id="tabs-code" style = "display:none">',
    '#suffix' =>'</div>',
  );

  $form['btncode'] = array(
    '#type' => 'submit',
    '#id' => 'btncode',
    '#value' => 'Get the code',
  );
}

```

The JavaScript code is the following one.

```
   jQuery("#btncode").click(function() {
     jQuery.ajax({
       type: "POST",
       url: Drupal.settings.basePath + "/?p=ajaxGetCode",
       cache: false,
       beforeSend: function() {
         // jQuery('.loadrimage').show();
         // jQuery(".error").hide();
       },
       complete: function() {
         // jQuery('.loadrimage').hide();
       },
       success: function(htmlText) {
         alert(htmlText);
       }
   });

```

# Answer
> 1 votes
You have to create own endpoint and call post on it. For example create menu element using hook\_menu:

```
$items['my-module-ajax-endpoint'] = array(
   'page callback' => 'my_module_ajax_callback',
   'delivery callback' => 'ajax_deliver',
   'access arguments' => array('access content'),
   'type' => MENU_CALLBACK,
);

```

And now post to it.

---
Tags: ajax
---


title: Drupal 8 live preview question

text:
# Question
Title: Drupal 8 live preview question
I'm a designer who is doing a design review on a Drupal 8 website. I'm having trouble doing the design review because 'admin objects' are getting in the way of the full page design:

* Admin bar at top of screen
* View, Edit, Up-Publish etc buttons below the header
* Sticky provide feedback bar

(Sorry can't show the full page due to NDA)

Usually I would just log out and preview live site, but the staging server for this project is hidden behind multiple logins and trying to access the website when not being logged in just redirects to the currently live (old) Drupal 7 website.

Any idea for how to remove these items and just preview the normal page?

Thanks

# Answer
You could create a user without any special admin privileges. Then you can either view it from another browser as the normal user or use the Masquerade module to swap in and out of that user from the same session.
> 1 votes

---
Tags: 8
---


# Question
Title: Programmatically create panels page including variants and block plugins inside it
I want to be able to programmatically create a panels page, add a variant and add block plugins to it with specified settings for each block plugin. My ultimate goal is to create a clone of a specified panels page. My current code is

```
    $page_storage = \Drupal::entityTypeManager()->getStorage('page');
    $variant_storage = \Drupal::entityTypeManager()->getStorage('page_variant');
    $page = $page_storage->load($page_id);
    $variants = $page->getVariants();
    foreach ($variants as $variant) {
        $blocks = $variant->getPluginCollections()['variant_settings']->getConfiguration()['blocks'];
        foreach ($blocks as $block) {
            //Here I have block data. Not sure how to take advantage of it though
        }
    }
    $newPage = $page_storage->create([
        'id' => $new_page_id,
        'label' => $new_page_id,
        'description' => $new_page_id . ' description',
        'path' => '/' . $path,
    ]);
    $newPage->save();
    $newVariant = $variant_storage->create([
        'id' => 'test',
        'label' => 'test',
        'page' => $newPage->id(),
    ]);
    $newVariant->save();

```

The page does get created just fine but the variant does not get assigned to the page. So I'm not sure what I'm missing. Also even if the variant assignment did work I'm not sure how I'd be able to add and set the config of all the custom blocks I added in the regions. Also I just realized I'm going to have to figure out how to set the layout as well.

How do I programmatically create a page variant and assign it to a programmatically created page, and then programmatically add the block plugins to the variant based on the config of another panels page?

**UPDATE**: I tried using

```
$newVariant->setPageEntity($newPage);

```

to set the variant but it still doesn't show as a variant in page manager. Thought when I

```
var_dump($newVariant->getPage());

```

it does seem to show the proper page like so

> object(Drupal\page\_manager\Entity\Page)#1959 (28) { \["id":protected\]=\> string(4) "test" \["label":protected\]=\> string(4) "test"

(that's just a portion) That is when $new\_page\_id was set to test.

---

**UPDATE 2**: I'm attempting to take advantage of the createDuplicate function instead, and at this point just trying to make the variant show up. Not worrying about the blocks yet. This is my new code.

```
    $variant_storage = \Drupal::entityTypeManager()->getStorage('page_variant');
    $page = $page_storage->load($page_id);

    $id = $page->id();
    $label = $page->label();
    $clone = $page->createDuplicate();
    $clone->set('id', $new_page_id);
    $clone->set('path', $path);
    $clone->set('label', 'Test Page ' . $new_page_id);
    $clone->save();
    $variants = $page->getVariants();
    foreach ($variants as $variant) {
        $var_clone = $variant->createDuplicate();
        $var_clone->set('page', $clone->id());
    }
    $var_clone->save();

```

However like before, the page gets created but the variant does not get applied.

I tried doubling up and trying multiple methods like so

```
        $var_clone = $variant->createDuplicate();
        $var_clone->set('page', $clone->id());
        $var_clone->setPageEntity($clone);
        $var_clone->save();

```

but that also had no effect.

---

**UPDATE 3**: I managed to get the variant to show up by setting the id of the variant clone like so

```
        $hash = bin2hex(random_bytes(8));
        $var_clone = $variant->createDuplicate();
        $var_clone->set('page', $clone->id());
        $var_clone->setPageEntity($clone);
        $var_clone->set('id', $hash);
        $var_clone->save();

```

It seems like it wasn't saving because an id wasn't set for the variant. However now there are new errors that I receive whenever trying to edit or save the page variant.

> Drupal\Core\Config\ConfigDuplicateUUIDException: Attempt to save a configuration entity 'test' with UUID '5d091883-6667-4aab-9fd8-c8ef77c871f4' when this entity already exists with UUID '11066a36-ca97-428f-aa78-f17b034421d8' in Drupal\Core\Config\Entity\ConfigEntityBase-\>preSave() (line 339 of /mnt/www/html/mysite/docroot/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php).

---

**UPDATE 4**: I'm now attempting to duplicate the blocks but I can't seem to load the blocks from the variant config.

```
$conf = $var_clone->getVariantPlugin()->getConfiguration();
$blocks_config = $conf['blocks'];
foreach ($blocks_config as $uuid => $block_data) {
    var_dump($uuid);
    var_dump($block_data);
}

```

Gives me the UUID but I want to actually have an object instead of an array so I can do

```
$block_clone = $block->createDuplicateBlock();

```

But I can't seem to get the block object from the UUID. I've even tried loading by the Uuid specifying every type of entity possible like so.

```
$conf = $var_clone->getVariantPlugin()->getConfiguration();
$blocks_config = $conf['blocks'];
foreach ($blocks_config as $uuid => $bdata) {
                foreach (array_keys(\Drupal::entityTypeManager()->getDefinitions()) as $etype) {
                    $block = \Drupal::service('entity.repository')->loadEntityByUuid($etype, $uuid);
                    var_dump($block);
                }
}

```

But I get nothing but NULL when trying to print each attempt at loading the entity by the UUID I got from the variant block configuration. Are config entities loaded a different way? Or does the UUID supplied not refer to something that can be loaded?

# Answer
I managed to accomplish this with the following code:

```
    $path = '/' . $path;
    $page_storage = \Drupal::entityTypeManager()->getStorage('page');
    $variant_storage = \Drupal::entityTypeManager()->getStorage('page_variant');
    $page = $page_storage->load($page_id);

    $id = $page->id();
    $clone = $page->createDuplicate();
    $clone->set('id', $new_page_id);
    $clone->set('path', $path);
    $clone->set('label', $label);
    $clone->save();
    $variants = $page->getVariants();

    foreach ($variants as $variant) {
        $hash = bin2hex(random_bytes(8));
        $var_clone = $variant->createDuplicate();
        $var_clone->set('page', $clone->id());
        $var_clone->setPageEntity($clone);
        $var_clone->set('id', 'variant_id_' . $hash);
        $var_clone->save();

        $conf = $var_clone->getVariantPlugin()->getConfiguration();
        $blocks_config = $conf['blocks'];
        unset($conf['blocks']);
        foreach ($blocks_config as $uuid => $bdata) {
            $hash = bin2hex(random_bytes(8));
            $bdata['uuid'] = $hash;
            $conf['blocks'][$bdata['uuid']] = $bdata;
        }
        $var_clone->getVariantPlugin()->setConfiguration($conf);
        $var_clone->save();
    }

```

Edit `$conf['blocks'][$bdata['uuid']] = $bdata;`
> 1 votes

---
Tags: 8, panels
---


# Question
Title: Cannot run composer update after going from 8.3 to 8.5
Upon trying to run `composer update drupal/core --with-dependencies`, I get this error:

```
➜  docroot git:(core-upgrade) ✗ composer update --with-dependencies
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
    - The requested PHP extension ext-gd * is missing from your system. Install or enable PHP's gd extension.

```

I've never had this error before, why is ext-gd required at all?

Edit:

I am currently doing this:

`phpbrew install 7.1.15 +default+iconv+gd`

`php -m` did not show gd as an installed extension. I've been fine for months until now, so, I am not sure if there was some change between 8.3 to 8.5 or possibly Symfony packages that suddenly requires this.

Edit 2:

This looks like it is also related to updating Homebrew/Xcode, as I had to take these additional steps in order to build a new version of PHP:

https://github.com/Homebrew/homebrew-php/issues/4590#issuecomment-346977512

Still does not explain why I suddenly need the `gd` extension to install or update a module with Composer for Drupal.

# Answer
> 3 votes
As of 8.5 core now explicitly requires several PHP extensions in composer.json, including gd:

```
...
"require": {
  "ext-date": "*",
  "ext-dom": "*",
  "ext-filter": "*",
  "ext-gd": "*",
  ...

```

The requirements match the required extension list in `system_requirements`, which would theoretically have to have been met for the original installation, and they were the same all the way back to 8.0.x, so it seems likely you did have gd installed when Drupal was installed.

Without gd installed you should also see an error message in the status report telling you it's missing; if you don't see that error, perhaps you have a different php.ini for FPM and CLI, and gd is only enabled for FPM, so it works in web but not the command line.

The relevant issue on drupal.org is here for reference.

---
Tags: 8
---


title: Accessing webform status via reference

text:
# Question
Title: Accessing webform status via reference
I have a content type that has a reference to a webform. In the template for this content type, I'd like to check if the referenced webform is open or closed to conditionally display some content.

I have a `content.field_ballot[0]`, but this appears to just be a render array without access to the underlying webform settings.

Is it possible to access it through this reference? Or should I be investigating a different route?

Thanks!

# Answer
You should avoid any complex PHP code in template files. I recommend you use a THEME\_preprocess\_node\_MY\_CONTENT\_TYPE(&$vars) hook to perform your checks, then pass a variable to the template file for your basic validation. In the preprocess function you pass the variable using $vars\['my\_custom\_variable'\] = XYZ and in the template you can call the variable with $my\_custom\_variable.

Make sure Drupal looks for content type node templates, or you can just use the default THEME\_preprocess\_node(&$vars) and put a check for your content type in there to keep the full validation code from running. https://www.drupal.org/node/337022

Stackoverflow discussion along similar lines https://stackoverflow.com/questions/40645297/pass-variable-to-preprocess-node-function-for-use-in-node-template
> 2 votes

---
Tags: 8, theming, webforms
---


# Question
Title: Programmatically Add Features for Role assignment in Ubercart Drupal 7 product node
I am trying to create a product programmatically and set it features for role assignment, that a user gets a specific role after he purchases, i tried all the ways i can but couldnt get it working. below is the code i used for adding it, but when i edit the feature for role assignment it doesnt hold the values i set in the edit feature form.

```
function add_product_feature($nid, $sku){
     // Insert new product into the uc_product_features tables
     $desc = "<strong>SKU:</strong> ".$sku."<br /><strong>Role:
     </strong>purchaser<br /><strong>Expiration:</strong> <a
      href=\"/admin/store/settings/products\">Global expiration</a>
      (not overridden)<br /><strong>Shippable:</strong> No<br />
      <strong>Multiply by quantity:</strong> No";
      $nid1 = db_insert('uc_product_features')
      ->fields(array('nid' => $nid,'fid' => 'role','description' =>
      $desc,
      ))
      ->execute();
}

```

# Answer
> 0 votes
Don't do that. Inserting into the DB directly can cause you problems down the road; there's already been code written to do what you're trying to do.

Look at the uc\_roles functions/documentation and follow how it adds product features via `uc_roles_feature_form_submit` submission handler and its `uc_product_feature_save()` call.

---
Tags: ubercart
---


# Question
Title: Views Data Export: Export to XLS with column labels?
The fields gets exported to XLS, but no labels are generated for every field, but missing field labels. Labels are set for every field in the field option.

Should be:

```
Field Label 1 | Field Label 2 | etc.
====================================
Data 1        | Data 2        | etc

```

But now it's just fields with no column labels

```
====================================
Data 1        | Data 2        | etc

```

Is it a setting I'm missing out in Views or tpl.php templates needs editing?

# Answer
If your spreadsheet is missing the field labels as column headers, chances are the "label" setting is disabled on each field (probably because, you have another display in the view with the labels turned off).

For each field in the Fields section,

1. Click the field name to open the settings option.
2. If necessary, be sure to choose *For "This views\_data\_export (override)"* from the top of the modal.
3. Enable the checkbox to *Create a label* and set the column heading/field label for the spreadsheet.
4. Click the *Apply (this display)* button at the bottom of the modal to save the settings for that field.

5. Save the view, clear your caches, and test the export again.

---

If the labels are set, the next course of action to check include:

1. Checking for any template files either in the theme or a custom module that could be overriding the settings.

* Within the view, you can click the *Information* link next to ***Theme*** at the bottom of the Advanced section (far right of views edit screen). It will list template filenames that could override the view, and render existing templates in bold.
    * Should you find a template outside of the Views Data Export module's folder, you can temporarily remove it and test to see if it resolves the export issue.
2. Checking to make sure you are running the most up-to-date version of the module.
> 2 votes

---
Tags: 7, views, importing-exporting
---


# Question
Title: Can I add custom fields to a single page?
Sorry for another "In Wordpress..." question but here we go...

In Wordpress, I can use ACF to add custom fields to a single page. This is done either in code or in the GUI by basically doing something like (pseudocode),

```
if id = 123
  add_field "Phone Number"
end

```

This is especially useful on homepages or landing pages where the layout is unique and I want to provide structured data entry without needing to create a custom type that is only used once. In Drupal, I dont see a way to dynamically add fields to an arbitrary piece of content. Is this possible? How?

---

*Wordpress custom fields:*

# Answer
> 2 votes
If you are using Drupal 8, you can create a block type and add fields to it. Then create a block of your block type and on visibility rules you can assign it to a specific page.

If you're using Drupal 7, you can do the same, but you'll need the Bean module

---
Tags: entities
---


title: Creating two aliases for the same node

text:
# Question
Title: Creating two aliases for the same node
I have a content type with a field allowing to select public or private.

I am using the Pathauto module for generating path aliases using this field, using /\[node:field\_evt\_diffusion\]/\[node:title\] as pattern. I am using the CAS module to casify the /private/\* path.

Is it possible to create two path aliases for the same node?

# Answer
> 1 votes
If manual steps are OK you can use this workaround:

The pathauto module always generates aliases using the first matching pattern type/condition combo. So simply create two matching patterns for your nodes. Generate URLs using the first pattern, deactivate this pattern and rerun URL alias generation (which now automatically uses the 2nd matching pattern).

# Answer
> 0 votes
You could use the redirect module to accomplish this with How to create a redirection programmatically?

Alternatively, if you change the url alias, redirect will automatically create a new redirect.

---
Tags: path-aliases
---


# Question
Title: How to apply Image Styles to images that have been added to published nodes?
We have an image field (field\_image) that did not have an image style originally applied. In the end we have hundreds of nodes (pages) where the Image style is not present. When adding an image style to the field under the respective View Mode, we are still getting an image without the image style applied.

How can we enforce the image style to be applied to currently published nodes?

Current results:

```
<img src="sites/default/files/image-original.jpg">

```

Desired results:

```
<img src="sites/default/files/styles/large/image-original.jpg">

```

What we have tried that didn't work:

1. Flush image style
2. Cleared cache

# Answer
I had to switch the formatter to Image and the twig templates to use the {{ content.field\_image }} to get this to work.
> 0 votes

# Answer
Start by checking your admin logs for one and second make sure that the new style directory permissions are correct. Image styles Troubleshooting -That's assuming that the images are being created and the folder(s)'s `.htaccess` is all good.

Also maybe force it by adding your specific style as argument using `drush if MACHINE_NAME`
> 0 votes

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


# Question
Title: How to write a template_preprocess_node hook to get the Image Style for an Image field?
I have an image field on Basic Page content type with a View Mode where format = Image and Image Style = Large.

How can I write a template\_preprocess\_node hook to get the Image style that is based on the View mode?

Here is what I was thinking but got stuck and cannot figure out what to call.

```
function mymodule_preprocess_node(&$variables) {
  $variables['view_mode'] = $variables['elements']['#view_mode'];
  $node = $variables['elements']['#node'];
  if($variables['view_mode'] = 'default' && $node->hasField('field_image')){
    $fieldImage = $node->get('field_image');
    /** stuck here as I cannot find method to get the Image Style **/
    //goal
    $image_style = $fieldImage->getImageStyle() // not sure what method this would be
    $image_path = $fieldImage->entity->getFileUri();
    $image_url = ImageStyle::load($image_style)->buildUrl($image_path);
    $variables['content'][0]['image_url'] = $image_url; // this is the goal
  }

}

```

twig template

```
<div style="background-image: url('{{ content.image_url }}')"></div>

```

# Answer
It is part of the render array generated by the formatter: https://api.drupal.org/api/drupal/core%21modules%21image%21src%21Plugin%21Field%21FieldFormatter%21ImageFormatter.php/function/ImageFormatter%3A%3AviewElements/8.2.x

You can see that it is set on #image\_style, so in node preprocess, that should be `$variables['content'][field_imge][0]['#image_style']`.

Depending on what you want to do, you could also write your own formatter or you could preprocess/alter the image\_formatter template.
> 1 votes

---
Tags: 8, theming, nodes, hooks
---


# Question
Title: How can I change the way content titles are generate and displayed?
I'm a total amateur working on the website for my community radio station via Drupal 7. (Here for reference) Each show on the station has their own content type called a Program Page, which displays, at the bottom of the page all the Program Playlists (a type of content) they have created by clicking a link on the Program Page and filling out the 'Create Program Playlist' form (http://www.cjsf.ca/node/add/station-playlist/685).

Currently these playlists are listed by an automatically-generated title that is just the date the episode aired (a field within the 'Create A Program Playlist' form), and we'd like to be able to assign custom titles to these playlists.

I can't for the life of me figure out how to do this. I've tried editing the content type for the Program Playlist but all I have there is an un-editable 'Title' field and I can't get much further than that.

Help!

# Answer
> 0 votes
If the title field is uneditable, that might have been done through another module or custom code (Automatic Entity Label?) that is setting the title text. I would edit the content type, and look down at the bottom and see if there are any content type settings that would be determining the title (not the "manage fields" page, but the main edit page for the content type). You might be able to re-enable editing. https://www.sierraclub.org/admin/structure/types/manage/station\_playlist (? not sure if this link is exactly right, a guess...)

A work around would be to add a custom field that is your custom title, and then edit your view(s) to use the custom title if it exists. (The short version of how to do that would be to make the regular title hidden, and then add the new field, and use the if empty setting to populate with the text from the title.)

But figuring out how the title field is made uneditable and fixing it from there would probably be best in the long run.

---
Tags: nodes, entities
---


title: Specific Site Building Setup

text:
# Question
Title: Specific Site Building Setup
Currently, I have a site set up like so:

**Content Types:**

* Program
* Course

**Paragraph Type:**

* Semester

I have a lot of `courses` which are being taught in specific `programs` so I want to reference them and list them by semester on the program pages. One of my fields in `Program` is `Courses` of which I made it reference a paragraph type of `Semester` and this allows me to enter an unlimited amount of semesters.

The semester paragraph type is made up of a title field (of which I'd put in which semester it's in \[ex. Semester 1\]) and an unlimited content reference field that references the `course` content type.

I'm not sure if this is the best way to go about doing this but it seemed to work like I needed it to until I realized I needed the option to somehow add the ability to make it list two courses as optional. (Ex. It would need to say something like: 'Choose one of: *Course 1* or *Course 2*'. And I would need the option of possibly doing this more than once per semester.)

What would be the best site building method to allow me to do this?

This is basically what I'd like the final output to look like:

# Answer
> 1 votes
Assuming that you really want to groups with "Title" and those with "Choose one of:" to look the same, you can achieve that quite easily with nested paragraphs.

Something like a "Semester" paragraph type with a paragraph field called "Course groups", and a "Course group" paragraph type that has "Title" + Course lists. Then the title for the optional groups would simply be "Choose one of".

If you need different markup/output, you could handle that either with an "Optional/Select one" checkbox that you can check in a template or by defining two separate paragraph types and allowing both on the nested paragraph field, e.g. "Required course group", "Choose-one-of course group" paragraph types.

Or any other similar combination of nested paragraph types, whatever you need exactly.

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


# Question
Title: Drupal\Component\Plugin\Exception\PluginNotFoundException: The "glossify_taxonomy" plugin does not exist.
In Drupal 8 when we upload the module we will get this kind of issue very often.

I have installed glossify and its submodule glossify\_taxonomy and configured. we have created some content in production.

After some days we felt we don't need glossify module. In our local instance we have uninstalled the module using composer and exported configuration and pushed to production and configuration also imported.

whenever we have try to create content or else try to access existing content we are getting plugin not found exception.

**We have fixed it by first removed all the configuration, deleted all the content and removed the modules from contrib directory**

But in production we can't do this every time. Please suggest how to safely uninstall the module.

**thank you everyone for the answer in advance.**

# Answer
> 1 votes
There are two approaches (if you don't want to reinstall the module's source code to production and work through the same steps to fully uninstall it).

* If you have command line access to the webserver, you could try using drush to uninstall the module on production. Run `drush pm-uninstall glossify_taxonomy` and then `drush pm-uninstall glossify`
* If that fails, you could schedule a content freeze, download the database to your local instance, and manually set the module as "disabled". Unlike Drupal 7's variables table however, each module does not have it's own row of data. Instead all module enabled/disabled states are aggregated and saved in the row of data where *cid = core.extension* within both the *config* and *cache-config* tables. To disable the module without fully uninstalling:

1. load the exported database from prod locally and:
    2. Open ‘config’ table
    3. Search row with ‘core.extension‘
    4. Download Blob object
    5. Unserialize Data (http://www.unserialize.me/ is a quick online tool to serialize and unserialize)
    6. Unset the glossify & glossify\_taxonomy modules or remove them from the array.
    7. Serialize Data
    8. Upload Blob object
    9. Save the edited record
    10. Open ‘cache-config’ table and repeat steps 2-8
    11. Export the modified local database
    12. Before making changes on production, keep a backup of the database for quick reversion if needed.
    13. Import the modified local database back to prod
    14. Test to see if you continue to observe the Missing Module warning/error.

---
Tags: installation
---


# Question
Title: How to use HTML entities in links in Drupal 8?
I have a client who prefers some links to have the » symbol at the end. This is typically produced with the » HTML character entity.

In Drupal 7, you would do something like this:

```
l('Go there »', 'node/1', array('html' => TRUE));

```

But how do you do it in Drupal 8? The following won't work because of new sanitization rules:

```
$node->toLink('Go there »', 'canonical', ['html' => TRUE]);

```

They want the raquo in the link, not as a suffix.

# Answer
Translate the string

```
$node->toLink(t('Go there »'))

```

This puts the string in a translatable markup object. If you don't want to translate then use a non translatable markup `\Drupal\Core\Render\Markup::create()`.

Both mark the string as a safe string, which you should do only for string constants like in this case, not for user input.
> 1 votes

# Answer
The cleanst solution for this is doing it in CSS:

```
.my_link_css_class::after {
  content: '\00a0\00bb';
}

```

(`\00a0` is for a space, `\00bb` is for the »)
> 1 votes

---
Tags: 8, navigation
---


# Question
Title: Clone/migrate of Drupal 8 site in Aegir fails on registry rebuild
* Aegir 3.144
* Drupal 8.4.4 -\> 8.4.5 (repeatable with Drupal 8.2.0)
* Drush 8.1.17-dev (also 8.1.16)

Sites import and create on the platform correctly but when trying to clone a site to same platform (8.4.4) or to new platform (8.4.5) or when trying to migrate to new platform it fails.

Initially it failed with "ERROR! Registry Rebuild requires a working Drupal site to operate on" but I found that it was testing for the presence of the module\_list function - even though it doesn't use it for D8 - and that presumably got dropped recently as it was marked as @deprecated in Drupal 8.0. A bit of logic later and it passed that check.

I then hit another issue:

I now get "Fatal error: Call to undefined function cache() in /var/aegir/.drush/registry\_rebuild/registry\_rebuild.drush.inc on line 158" where cache is a function defined in core/lib/Drupal.php, changing the call to \Drupal::cache() gives "exception 'Drupal\Core\DependencyInjection\ContainerNotInitializedException' with message '\Drupal::$container is not initialized yet."

```
drush --debug rr
Using the Drush script found at /var/aegir/.config/composer/vendor/drush/drush/drush.launcher using pcntl_exec
Loading drushrc "/var/aegir/.drush/drushrc.php" into "home.drush" scope. [0.01 sec, 2.84 MB]                                                                                [bootstrap]
Include /var/aegir/hostmaster-7.x-3.144/profiles/hostmaster/modules/aegir/hosting_tasks_extra/http_basic_auth/drush [0.01 sec, 2.86 MB]                                                            [notice]
Include /var/aegir/hostmaster-7.x-3.144/profiles/hostmaster/modules/aegir/hosting_tasks_extra/fix_permissions/drush [0.01 sec, 2.86 MB]                                                            [notice]
Include /var/aegir/hostmaster-7.x-3.144/profiles/hostmaster/modules/aegir/hosting_tasks_extra/fix_ownership/drush [0.01 sec, 2.87 MB]                                                              [notice]
Include /var/aegir/hostmaster-7.x-3.144/profiles/hostmaster/modules/aegir/hosting_tasks_extra/drush [0.01 sec, 2.87 MB]                                                                            [notice]
Include /var/aegir/hostmaster-7.x-3.144/profiles/hostmaster/modules/aegir/hosting_site_backup_manager/drush [0.01 sec, 2.87 MB]                                                                    [notice]
Include /var/aegir/hostmaster-7.x-3.144/profiles/hostmaster/modules/aegir/hosting_remote_import/drush [0.01 sec, 2.87 MB]                                                                          [notice]
Cache HIT cid: 8.1.17-dev-commandfiles-0-89e108e056f1078378c8d0877e0d0710 [0.01 sec, 2.93 MB]                                                                                [debug]
Loading drushrc "/var/aegir/platforms/drupal-8.4.4-staging/sites/all/drush/drushrc.php" into "drupal" scope. [0.04 sec, 6.14 MB]                                                                [bootstrap]
Bootstrap to phase 0. [0.12 sec, 10.92 MB]                                                                                [bootstrap]
Bootstrap to phase 0. [0.12 sec, 10.93 MB]                                                                                [bootstrap]
Found command: registry-rebuild (commandfile=registry_rebuild) [0.12 sec, 10.93 MB]                                                                                [bootstrap]
Loaded alias @server_master from file /var/aegir/.drush/server_master.alias.drushrc.php [0.14 sec, 10.99 MB]                                                                                [notice]
Loading apache driver for the http service [0.14 sec, 11.08 MB]                                                                                [notice]
Calling hook drush_registry_rebuild [0.15 sec, 11.41 MB]                                                                                [debug]
Bootstrap to phase 4. [0.15 sec, 11.41 MB]                                                                                [bootstrap]
Drush bootstrap phase : bootstrap_drupal_root() [0.15 sec, 11.98 MB]                                                                                [bootstrap]
Loading drushrc "/var/aegir/platforms/drupal-8.4.4-staging/sites/all/drush/drushrc.php" into "drupal" scope. [0.15 sec, 11.99 MB]                                                               [bootstrap]
Initialized Drupal 8.4.4 root directory at /var/aegir/platforms/drupal-8.4.4-staging [0.16 sec, 11.99 MB]                                                                                [bootstrap]
Find command files for phase 1 (max=4) [0.16 sec, 9.24 MB]                                                                                [debug]
Cache HIT cid: 8.1.17-dev-commandfiles-1-88345322626fe4254094b893cfd5846e [0.16 sec, 9.25 MB]                                                                                [debug]
Cache HIT cid: 8.1.17-dev-annotationfiles-1-07190c11fa2acabad3c4805ba4771846 [0.16 sec, 9.33 MB]                                                                                [debug]
Drush bootstrap phase : bootstrap_drupal_site() [0.17 sec, 10.16 MB]                                                                                [bootstrap]
Loading drushrc "/var/aegir/platforms/drupal-8.4.4-staging/sites/staging.andydev8.internal.admin.cam.ac.uk/drushrc.php" into "site" scope. [0.17 sec, 10.16 MB]                                 [bootstrap]
Initialized Drupal site staging.andydev8.internal.admin.cam.ac.uk at sites/staging.andydev8.internal.admin.cam.ac.uk [0.22 sec, 13.41 MB]                                                       [bootstrap]
Find command files for phase 2 (max=4) [0.23 sec, 10.51 MB]                                                                                [debug]
Cache HIT cid: 8.1.17-dev-install_profile-60c747bfdc14cdc330ea9d8a6124de78 [0.23 sec, 10.52 MB]                                                                                [debug]
Cache MISS cid: 8.1.17-dev-commandfiles-2-f4034f9781ca6975fd1dc0e8e667ab21 [0.23 sec, 10.53 MB]                                                                                [debug]
Cache SET cid: 8.1.17-dev-commandfiles-2-f4034f9781ca6975fd1dc0e8e667ab21 [0.23 sec, 10.54 MB]                                                                                [debug]
Drush bootstrap phase : bootstrap_drupal_configuration() [0.23 sec, 10.53 MB]                                                                                [bootstrap]
Create from request [0.23 sec, 10.57 MB]                                                                                [debug]
add service modifier [0.23 sec, 10.9 MB]                                                                                [debug]
Find command files for phase 3 (max=4) [0.23 sec, 10.9 MB]                                                                                [debug]
sql-query: SELECT 1; [0.24 sec, 11.02 MB]                                                                                [notice]
Executing: mysql --defaults-extra-file=/tmp/drush_VXDeZp --database=stagingandydev8i --host=drupal-uas1-dev1.internal.admin.cam.ac.uk --port=3306 --silent  < /tmp/drush_oplyXT
  1
sql-query: SHOW TABLES; [0.26 sec, 11.02 MB]                                                                                [notice]
Executing: mysql --defaults-extra-file=/tmp/drush_VCw2as --database=stagingandydev8i --host=drupal-uas1-dev1.internal.admin.cam.ac.uk --port=3306 --silent  < /tmp/drush_Dza84V

<<List of all the tables removed for brevity>>

Drush bootstrap phase : bootstrap_drupal_database() [0.28 sec, 11.04 MB]                                                                                [bootstrap]
Successfully connected to the Drupal database. [0.28 sec, 11.04 MB]                                                                                [bootstrap]
Find command files for phase 4 (max=4) [0.28 sec, 11.04 MB]                                                                                [debug]
This DRUSH_MAJOR_VERSION is: 8 [0.29 sec, 12.15 MB]                                                                                [notice]
Internal Drush cache cleared with drush_cache_clear_drush (1). [0.29 sec, 12.15 MB]                                                                                [notice]

Fatal error: Call to undefined function cache() in /var/aegir/.drush/registry_rebuild/registry_rebuild.drush.inc on line 159
Drush command terminated abnormally due to an unrecoverable error.                                                                                [error]
Error: Call to undefined function cache() in /var/aegir/.drush/registry_rebuild/registry_rebuild.drush.inc, line 159 [0.29 sec, 12.15 MB]

```

I believe this is a clean install of Aegir, drush and registry\_rebuild.

# Answer
> 0 votes
Thank you to @HermanvanRink for the pointer to the solution to my question.

We do have a "Rebuild Registry" task on each site page from Hosting Tasks Extra but that is not required for Drupal 8 and will not work as installed.

The actual issue here was that my predecessor had implemented the fix from #4 on https://www.drupal.org/project/provision/issues/1694792 in local drush additions so that registry\_rebuild was being called for every clone/migrate.

Added a test to avoid doing that for D8 and all is now well.

---
Tags: 8, aegir
---


# Question
Title: Optimize performance of custom pre-built option list to webform
I am looking to add a pre-built options list, based on a query. I crafted the function nicely with the below code

```
function mitacan_webform_select_options_info() {
    $items = [];
    if (function_exists('basliklariAl')) {
        $items['addresses'] = array(
            'title' => 'Stok Kodları',
            'options callback' => 'basliklariAl'
        );
    }
    return $items;
}

function basliklariAl($component, $flat, $arguments) {
    $nodes = [];
    $select = db_select('node','n')
        ->fields('n',[
            'nid',
            'title'
        ])
        ->condition('type','urun')
        ->execute()
        ->fetchAll();
    foreach($select as $n) {
        $nodes[$n->nid] = $n->title;
    }
    return $nodes;
}

```

This is very slow, mostly because there are about 10k records. What can I do to optimise the process?

# Answer
You can always cache the results as seen in the official documentation

```
  if ($cache = cache_get('my_module_cache') && REQUEST_TIME < $cache->expire) {
    $data = $cache->data;
  }
  else {
    $data = 'xxxxxxx'; //do all your time taking complex calculations here
    cache_set('my_module_cache', $data, 'cache',  REQUEST_TIME  + (3600 * 24 * 30 * 6)); //stores in cache table and expires after 6 months
  }

```

More about cache\_set and cache\_get
> 0 votes

---
Tags: 7, webforms
---


# Question
Title: Print the error message returned from the SQL query
I created a custom module where I am querying the database, for example with code similar to the following one.

```
$query = db_select('node', 'n');
$query->fields('n', array('nid'));
$nid = $query->execute()->fetchField();

```

I want to print the warning, error, and success messages after the execution of the query. How can I achieve this?

# Answer
> 2 votes
Try to follow below code..

```
   try {
        $query = db_select('node', 'n');
        $query->fields('n', array('nid'));
        $nid = $query->execute()->fetchField();
        drupal_set_message(t('Print your sucess message here'));
      }
    catch(Exception $e){
        drupal_set_message(t('Print your error message here'),'error');
    }

```

# Answer
> 1 votes
You can display drupal messages using the pre-defined function drupal\_set\_message().

**For example:**

```
$query = db_select('node', 'n');
$nid = $query->fields('n', array('nid'));
$nid = $nid->execute()->fetchField();
if(!empty($nid)){
     //Do something
     drupal_set_message(t('Your success message'), $type = 'status');
}else{
    //Do something
     drupal_set_message(t('Your error message'), $type = 'error');
}

```

For more information about messages, click here

---
Tags: 7, database
---


# Question
Title: How to add link module in Bootstrap Paragraphs?
I experiment with the xeno\_hero module and Bootstrap Paragraphs module in order to create a call to action block. I want to create an image background with a centered linked textfield.

I tried a lot of options. The option of a link is not given so I tried to add link (core module) to dependencies like this

```
dependencies:
  config:
    - field.field.paragraph.xeno_hero.xeno_background_image
    - field.field.paragraph.xeno_hero.xeno_content
    - field.field.paragraph.xeno_hero.xeno_invert
    - field.field.paragraph.xeno_hero.xeno_offset
    - field.field.paragraph.xeno_hero.xeno_overlay
    - field.field.paragraph.xeno_hero.xeno_parallax
    - paragraphs.paragraphs_type.xeno_hero
    module:
    - entity_reference_revisions
    - image
    - options
    - link

```

And copied the `link.schema.yml` file from core to custom module. So far no good.

How can I add a linked textfield?

# Answer
If you add a Simple paragraph into the Content field, you can add whatever content you want in the wysiwyg without the need for a link field modification.

Here is of the hero the Bootstrap Paragraphs demo site.
> 0 votes

---
Tags: 8, navigation, paragraphs
---


# Question
Title: How can I make a form element required with states?
I have a drop down list that displays various fields based on what is chosen and I know that I can toogle the visibility with states but when I try to use required the * span is display but it isn't actually required. What I mean is that even though it's "required" I can hit submit and not get an error message from drupal. Am I doing something wrong or is this currently broken in Drupal 7.8?

```
$form['host_info'] = [
  '#type' => 'select',
  '#title' => t("Host Connection"),
  '#options' => [
    'SSH2' => t('SSH2'),
    'Web Service' => t('Web Service'),
  ],
  '#default_value' => t(variable_get('host_info', 'SSH2')),
  '#description' => t("Specify the connection information to the host"),
  '#required' => TRUE,
];

$form['ssh_host'] = [
  '#type' => 'textfield',
  '#title' => t("Host Address"),
  '#description' => t("Host address of the SSH2 server"),
  '#default_value' => t(variable_get('ssh_host')),
  '#states' => [
    'visible' => [
      ':input[name=host_info]' => ['value' => t('SSH2')],
    ],
    'required' => [
      ':input[name=host_info]' => ['value' => t('SSH2')],
    ],
  ],
];

$form['ssh_port'] = [
  '#type' => 'textfield',
  '#title' => t("Port"),
  '#description' => t("Port number of the SSH2 server"),
  '#default_value' => t(variable_get('ssh_port')),
  '#states' => [
    'visible' => [
      ':input[name=host_info]' => ['value' => t('SSH2')],
    ],
    'required' => [
      ':input[name=host_info]' => ['value' => t('Web Service')],
    ],
  ],
];

```

# Answer
> 21 votes
You will need to validate this yourself in a custom validate function.

Everything configured by #states happens 100% in the browser, everything that it does is not visible for Drupal when the form is submitted (for example, all invisible form field are submitted and validated in the same way if there were no #states).

# Answer
> 13 votes
You can use required like this:

```
'#states'=> [
  'required' => [
    ':input[name="abroad_because[somecheckbox]"]' => ['checked' => TRUE],
  ],
],

```

# Answer
> 10 votes
Very similar to Felix Eve's answer only this is a snippet for inline element validation:

You call an element validate function the required element:

```
$form['element'] = array(
....
  '#element_validate' => array(
     0 => 'my_module_states_require_validate',
   ),
)

```

Then the validation function finds the required field and checks to see if it's has the correct form value which would reveal the field which needs to be required.

```
function my_module_states_require_validate($element, $form_state) {
  $required_field_key = key($element['#states']['visible']);
  $required_field = explode('"', $required_field_key);
  if($form_state['values'][$required_field[1]] == $element['#states']['visible'][$required_field_key]['value']) {
    if($form_state['values'][$element['#name']] == '') {
      form_set_error($element['#name'], $element['#title'].' is required.');
    }
  }
}

```

# Answer
> 3 votes
There is another way to use AFTER\_BUILD function for form and make that field optional. Here is a link for drupal 6.

Add this to your form code

```
$form['#after_build'][] = 'custom_form_after_build';

```

Implement after build, test your custom field condition

```
function custom_form_after_build($form, &$form_state) {
  if (isset($form_state['input']['custom_field'])) {
    $form['another_custom_field']['#required'] = FALSE;
    $form['another_custom_field']['#needs_validation'] = FALSE;
  }
  return $form;
}

```

In my case, #states was adding multiple * so I have to avoid it and used jquery to hide and show the span that contains *

```
$('.another-custom-field').find('span').hide();

```

And

```
$('.another-custom-field').find('span').show();

```

Based on my custom\_field value.

# Answer
> 3 votes
I was able to do it this way in Drupal 8:

```
'#states' => [
  'required' => [
    [':input[name="host_info"]' => ['value' => 'SSH2']],
  ],
],

```

Don't put `t('SSH2')` this will put the translation of it there instead of the value of the option which is an untranslated SSH2.

I suspect that this would work for Drupal 7 too.

# Answer
> 3 votes
Here's a detailed guide on Drupal 7 form #states.

This is the important bit:

```
/**
 * Form implementation.
 */
function module_form($form, $form_state) {
  $form['checkbox_1'] = [
    '#title' => t('Checkbox 1'),
    '#type' => 'checkbox',
  ];

  // If checkbox is checked then text input
  // is required (with a red star in title).
  $form['text_input_1'] = [
    '#title' => t('Text input 1'),
    '#type' => 'textfield',
    '#states' => [
      'required' => [
        'input[name="checkbox_1"]' => [
          'checked' => TRUE,
        ],
      ],
    ],
  ];

  $form['actions'] = [
    'submit' => [
      '#type' => 'submit',
      '#value' => t('Submit'),
    ],
  ];

  return $form;
}

/**
 * Form validate callback.
 */
function module_form_validate($form, $form_state) {
  // if checkbox is checked and text input is empty then show validation
  // fail message.
  if (!empty($form_state['values']['checkbox_1']) &&
    empty($form_state['values']['text_input_1'])
  ) {
    form_error($form['text_input_1'], t('@name field is required.', [
      '@name' => $form['text_input_1']['#title'],
    ]));
  }
}

```

# Answer
> 2 votes
I've just been faced with the same problem so needed to provide custom validation however I wanted this to be controlled via the #states array so I didn't have to specify the same rules twice.

It works by extracting the field name from the jQuery selector (the selector must be in the format `:input[name="field_name"]` or it won't work).

The code below is only tested in the specific scenario that I was using it in, however I though it may prove useful to someone else.

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

    // check for required field specified in the states array

    foreach($form as $key => $field) {

        if(is_array($field) && isset($field['#states']['required'])) {

            $required = false;
            $lang = $field['#language'];

            foreach($field['#states']['required'] as $cond_field_sel => $cond_vals) {

                // look for name= in the jquery selector - if that isn't there then give up (for now)
                preg_match('/name="(.*)"/', $cond_field_sel, $matches);

                if(isset($matches[1])) {

                    // remove language from field name
                    $cond_field_name = str_replace('[und]', '', $matches[1]);

                    // get value identifier (e.g. value, tid, target_id)
                    $value_ident = key($cond_vals);

                    // loop over the values of the conditional field
                    foreach($form_state['values'][$cond_field_name][$lang] as $cond_field_val) {

                        // check for a match
                        if($cond_vals[$value_ident] == $cond_field_val[$value_ident]) {
                            // now we know this field is required
                            $required = true;
                            break 2;
                        }

                    }

                }

            }

            if($required) {
                $field_name = $field[$lang]['#field_name'];
                $filled_in = false;
                foreach($form_state['values'][$field_name][$lang] as $item) {
                    if(array_pop($item)) {
                        $filled_in = true;
                    }
                }
                if(!$filled_in) {
                    form_set_error($field_name, t(':field is a required field', array(':field' => $field[$lang]['#title'])));
                }
            }

        }
    }

}

```

# Answer
> 0 votes
I have nested form fields, and a checkbox , so I needed to work a bit on Dominic Woodman's answer. In case any body else run into the same problem:

```
function my_module_states_require_validate($element, $form_state) {
  $required_field_key = key($element['#states']['visible']);
  $required_field = explode('"', $required_field_key);
  $keys = explode('[', $required_field[1]);
  $keys = str_replace(']', '', $keys);
  $tmp = $form_state['values'];
  foreach ($keys as $key => $value) {
    $tmp = $tmp[$value];
  }
  if($tmp == $element['#states']['visible'][$required_field_key]['checked']) {
    $keys2 = explode('[', $element['#name']);
    $keys2 = str_replace(']', '', $keys2);
    $tmp2 = $form_state['values'];
    foreach ($keys2 as $key => $value) {
      $tmp2 = $tmp2[$value];
    }
    if($tmp2 == '') {
      form_set_error($element['#name'], $element['#title']. t(' is required.'));
    }
  }
}

```

---
Tags: forms
---


# Question
Title: Authentication cookie in a load balanced environment
Hopefully this is a basic question. I'm going to be setting up a drupal website there there will be multiple servers in back of a load balancer. The user will hit one web server where they will authenticate and the cookie will be added to the browser's session. On subsequent requests if the user is sent to another server, will that server recognize the user as authenticated since the authentication cookie is present, or is the cookie somehow tied to the server that authenticated the user?

# Answer
Yes, if you've configured your servers correctly.

Authentication state is stored in the DB. As long as each Drupal node (app server) in your load balancer pool is configured to talk to the same database, it shouldn't matter what server the browser is talking to. Login data will persist in the database and each Drupal node should be able to find it via the user's cookie data.

The challenge is making sure all the infrastructure correctly. Those details are off topic here, but you might find *Using a load balancer or reverse proxy* on drupal.org helpful for other Drupal-specific stuff to know when dealing with Drupal behind a proxy (load balancer).
> 1 votes

---
Tags: cookies
---


# Question
Title: Get the breadcrumbs for a specific node other than the current
I have a list of nodes created by a view. Those nodes tend to have titles that are mostly the same, but since they are in a rather logical hierarchy defined by the menu I'd like to output the breadcrumb to the nodes as well.

I couldn't find a core-function that does that. Anyone an idea how to work around/on that?

# Answer
> 0 votes
Core breadcrumbs in Drupal 7 are implemented in a way that they only work for the current page. So to achieve this with core, you would have to "simulate" a page request and somehow harvest the breadcrumb. This is probably painful and not worth the effort.

In Drupal 8, you have breadcrumb builders that take a route match as an argument. This route match can be any page. So yeah, what you want would be possible in D8. But you are in Drupal 7.

In Drupal 7 with Crumbs module, breadcrumbs are calculated independently of the current page. You can see this in action on `admin/structure/crumbs/demo`.

E.g. `crumbs_get_trail()` accepts a `$path` argument, which can be any path you want. But this gives you a "trail", not a breadcrumb itself.

Unfortunately there is no one-liner to give you the breadcrumb for any page.

But here is what you can do:

```
  // Create a local version of the Crumbs service container.
  $services = new crumbs_DIC_ServiceContainer();
  $page_info = $services->page;
  $page_info->path = 'node/123';

  // Optional: Set display settings.
  $page_info->minTrailItems = 1;
  $page_info->showFrontPage = TRUE;
  $page_info->showCurrentPage = TRUE;

  // Now choose which piece of information you want.
  $trail = $page_info->trail;
  $breadcrumb_html = $page_info->breadcrumbHtml;
  $breadcrumb_data = $page_info->breadcrumbData;
  $breadcrumb_items = $page_info->breadcrumbItems;
  $raw_breadcrumb_items = $page_info->rawBreadcrumbItems;

```

This can be starting point for you to play around with.

If you use Crumbs for this purpose, you get the full package: All your breadcrumbs will now be controlled by Crumbs. Maybe this is what you want, or maybe not.

I am not aware of other breadcrumb-customizing modules which provide this functionality.

---
Tags: 7, routes, breadcrumbs
---


# Question
Title: How to add a default controller to the <front> route?
Is it possible to add a default controller to the `'<front>'` route? There's no default controller defined in `system.routing.yml`.

I'm trying to get a handle on it by using the following code:

```
<?php

namespace Drupal\mymodule\Routing;

use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;

/**
 * Listens to the dynamic route events.
 */
class RouteSubscriber extends RouteSubscriberBase {

  /**
   * {@inheritdoc}
   */
  protected function alterRoutes(RouteCollection $collection) {
    // Get front page and set controller.
    if ($route = $collection->get('<front>')) {
      $route->setDefault('_controller', '\Drupal\mymodule\Controller\MyModuleController::MyModuleMethod');
    }
  }

}

```

But it doesn't seem to do anything. However this code works when replacing `'<front>'` with another route like `help.main`. Why is that? Do I have to *add* the controller instead of *setting* it? (D8)

# Answer
`<front>` is not really a route that can be resolved for an incoming request, it's just a helper for building a URL.

It works in the opposite way, you create a controller at whatever path you want, and then you set the frontpage to that path on the system information page aka in the system.site configuration object.
> 1 votes

---
Tags: 8, routes, page-controller
---


# Question
Title: How can I alter the list of available layouts in the Panels IPE?
I'm trying to hide or remove several layouts from the layout selectors, so that users can only select from an approved list. I can do this successfully with `hook_form_alter()` code, but the Panels IPE isn't using a form for its layout selection tray. It seems the best method would be to use LayoutPluginManagerInterface somehow, so that *any* function that displays a list of available layouts will have the same list available, but so far I haven't figured it out. Is there a way to do this?

# Answer
> 1 votes
I've been trying to curate the Panels IPE more to my liking, and so far, it seems like overriding the controller is a decent way to go.

Say you're wanting to do this in my\_example module:

* Inside your custom module, create src/Controller/CustomPanelsIPEController.php. We want to extend from panels\_ipe/src/Controller/PanelsIPEPageController.php into this file, and change the namespace declaration and change the class name to match:

```
<?php

namespace Drupal\my_module\Controller;

use Drupal\panels_ipe\Controller\PanelsIPEPageController;

/**
 * Contains all JSON endpoints required for Panels IPE + Page Manager.
 */
class MyModuleIPEController extends PanelsIPEPageController {
...

```
* Now, we need to have our routing subscriber tune in to panels IPE being called, and re-route it to our new method. Create src/Routing/MyExampleRoutingSubscriber.php, and add the following:

```
namespace Drupal\my_example\Routing;

use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;

/**
 * Listens to the dynamic route events.
 */
class MyExampleRoutingSubscriber extends RouteSubscriberBase {
  /**
   * {@inheritdoc}
   */
  protected function alterRoutes(RouteCollection $collection) {
    if ($route = $collection->get('panels_ipe.block_plugins')) {
      $route->setDefault('_controller', '\Drupal\my_example\Controller\MyModuleIPEController:getBlockPlugins');
    }
  }
}

```

So now what will happen is our Panels IPE is now calling our method.

So now, we can do some more precise altering. For a simple example, when it comes to creating blocks, let's say we wanted to only give users a single module called 'awesome\_blocks' for their choices when creating content.

```
public function getBlockPluginsData($panels_storage_type, $panels_storage_id) {
   $panels_display = $this->loadPanelsDisplay($panels_storage_type,
   $panels_storage_id);

   // Get block plugin definitions from the server.
   $definitions = $this->blockManager->getDefinitionsForContexts($panels_display->getContexts());

   // Assemble our relevant data.
   $blocks = [];
   foreach ($definitions as $plugin_id => $definition) {
     if ($definition['provider'] == "awesome_blocks") { // Added this logic
     ...

```

In this simple example, I've altered the logic to ONLY show blocks from the awesome\_blocks module. Now of curse, I was altering the blocks, and you were asking about the layouts. The layouts can be altered the same way! Inside of the `getLayoutsData()` function that is in this same class, you could implement custom logic. To alter the layouts in the same way, we could add another function inside our custom Routing controller, inside the alterRoutes() method:

```
    if ($route = $collection->get('panels_ipe.layouts')) {
        $route->setDefault('_controller', '\Drupal\my_example\Controller\MyModuleIPEController:getLayouts');
    }

```

Now, just implement custom logic in the getLayouts method:

```
public function getLayoutsData($panels_storage_type, $panels_storage_id) {
    $panels_display = $this->loadPanelsDisplay($panels_storage_type, $panels_storage_id);

    // Get the current layout.
    $current_layout_id = $panels_display->getLayout()->getPluginId();

    // Get a list of all available layouts.
    $layouts = $this->layoutPluginManager->getDefinitions();
    $base_path = base_path();
    $data = [];
    foreach ($layouts as $id => $layout) {
        if ($layout['provider'] == 'my_layout_module') { // Added logic check here
        ...
        }

```

Hope this helps!

# Answer
> 1 votes
I have found that with the latest versions (8.3 +) you can simply unset the ones you aren't using with (must be in a module, doesn't work in (our) theme):

function \[my\_module\_name\]\_layout\_alter(&$definitions) { // Disable default layouts. unset($definitions\['layout\_onecol'\]); unset($definitions\['layout\_twocol'\]); unset($definitions\['layout\_twocol\_bricks'\]); unset($definitions\['layout\_threecol\_25\_50\_25'\]); unset($definitions\['layout\_threecol\_33\_34\_33'\]); } (This will error on any layout that you are currently using (hint: one-column is default). Referenced from here: https://www.drupal.org/project/panels/issues/2812999

Then, all you have to do is provide layouts of your own using the Drupal Core Layout Discovery (formerly Layouts plugin): https://www.drupal.org/docs/8/api/layout-api/how-to-register-layouts#simplest-case

Using Category names, you can make the UI just how it is provided, except it will use your own custom layouts.

---
Tags: 8, plugins
---


title: Panes' Title translation

text:
# Question
Title: Panes' Title translation
I need to translate the Label of the panes in a page. For example, Title and Body are not translated in my pages.

Note: I do not mean the content of panes! I only mean their label! Which is generally called TITLE.

# Answer
Sounds like *i18n\_panels* would be overkill. You can do it like this:

```
/**
 * Preprocess panels panes to translate their title.
 */
function MY_THEME_preprocess_panels_pane(&$variables) {
  $pane_config = $variables['pane']->configuration;
  if (!empty($pane_config['override_title'])) {
    // Translate pane title via t().
    $variables['title'] = t($pane_config['override_title_text']);
  }
}

```

Or, if appropriate, just:

```
/**
 * Preprocess panels panes to translate their title.
 */
function MY_MODULE_preprocess_panels_pane(&$variables) {
  $variables['title'] = t($variables['title']);
}

```

The first will process the title only if defined in the pane settings as a title override. The second will translate the title regardless of whether it's the override title or original title from elsewhere.

Tested under Drupal 7, the same or similar approach would probably work for Drupal 8.
> 0 votes

---
Tags: 7, panels, i18n-l10n
---


# Question
Title: Module to edit field data on multiple instances/nodes (in bulk)
I've a need to allow my client to easily edit the price field for the projects (content type). In total there're about 1.5k nodes and he wants to change the price once and that it would be applied to all the 1.5k projects/nodes.

Is there a way to do it using some of the existing modules in an easy way, so that an amateur could make the change? Or can it be achieved by custom module, if so could you give some instructions in terms of how should it be done programatically?

I'm not a developer, but will pass it to my colleague, who's a developer. He tried to code a custom module, but it takes about 18min to update the field data for 1.5k nodes... So apparently something is not right.

Thanks.

# Answer
For Drupal 7 you will need views bulk operations which packages this and other bulk operations. For Drupal 8 you need Bulk Update Fields

Below the procedure is for Drupal 8 but very similar for Drupal 7

Install the module and modify the **Admin content** view found by going to `admin/structure/views/view/content` or perhaps you can use any view that you want.

`add field` and search for `Node operations bulk form` to add and make sure you enable

**Selected actions: Bulk Update Fields to Another Value**

With this when on the view page you can select 1 or more nodes and modify fields in bulk
> 1 votes

---
Tags: 7, nodes, entities
---


# Question
Title: "drush cron" doesn't work anymore after moving the site to a new server
After moving a site to a new server, `drush cron` stopped working and now I am getting the following error:

> \[Symfony\Component\Console\Exception\CommandNotFound\]
> Command "cron" is not defined.

What am I missing?

# Answer
> 0 votes
The issue was fairly simple to solve.

I had forgotten to create a settings.php for each site. I was able to find out by running the following command:

```
drush --local -d -r /var/www/testproject/build/html status

```

And from the output I was able to see:

```
[debug] Could not find a Drupal settings.php file at sites/default/settings.php. [0.14 sec, 10.8 MB]

```

That was it

---
Tags: 8, drush
---


title: How do I change the default height?

text:
# Question
Title: How do I change the default height?
9 rows is just way too small by default. Is this a text-editor for ants?

# Answer
> 6 votes
Like the comments to the previous answer mention, changing the amount of text area rows displayed in the form display doesn't change the height of the CKEditor attached to those fields. I haven't found any place yet to change the height settings through the UI so we have to do it in code.

To do this, create a simple new custom module **ckeditor\_change\_height** with these two files (or add the code under ckeditor\_change\_height.module to an existing one):

**ckeditor\_change\_height.module**

```
/**
 * Change the ckeditor's settings.
 *
 * Implements hook_editor_js_settings_alter().
 */
function ckeditor_change_height_editor_js_settings_alter(array &$settings) {
  foreach (array_keys($settings['editor']['formats']) as $text_format_id) {
    if ($settings['editor']['formats'][$text_format_id]['editor'] === 'ckeditor') {
      $settings['editor']['formats'][$text_format_id]['editorSettings']['height'] = '350px';
    }
  }
}

```

**ckeditor\_change\_height.info.yml**

```
name: CKEditor - Change height
type: module
description: Change CKEditor height
package: CKEditor
core: '8.x'
version: '8.x-1.0'

```

Just set that 350px to be any height you want, enable the module & flush your cache.

# Answer
> 9 votes
I rolled a module for that now: https://www.drupal.org/project/ckeditorheight

> This module changes all ckeditor text fields to respect the "rows" setting of the field. How rows translate into pixels is a global setting, configured via a pixel factor and offset.

# Answer
> 5 votes
Anyone using Drupal 8-- this has changed now that Autogrow is built into core, but is still useful if you want to set the default minHeight and maxHeight. See my code below to replace code found in **ckeditor\_change\_height.module**:

```
    function ckeditor_change_height_editor_js_settings_alter(array &$settings) {
      foreach (array_keys($settings['editor']['formats']) as $text_format_id) {
        if ($settings['editor']['formats'][$text_format_id]['editor'] === 'ckeditor') {
          $settings['editor']['formats'][$text_format_id]['editorSettings']['autoGrow_minHeight'] = '100';
        }
      }
    }

```

# Answer
> 3 votes
Check out the Autogrow module/plugin. Works pretty slick. I do recommend changing the default of 600 down to maybe 400.

Update:

It appears autogrow will be included by default starting in 8.3.x

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

---
Tags: 8, wysiwyg
---


# Question
Title: How do I display labels in checkbox grid table?
I managed to create table grid with checkboxes, however I can't get the label to display in first column. What am I missing, could you guys help ?

Thanks!

This is what I have in backend

Update:

Drupal issue: https://www.drupal.org/project/webform/issues/2951650

# Answer
I was able to figure this out by creating a new custom element. My solution can be downloaded on my Github https://github.com/minnur/webform\_checkboxes\_table
> 0 votes

---
Tags: webforms
---


# Question
Title: Running an immutable setup in production
I'm looking into using Docker to streamline my Drupal development workflow. One approach would be to locally create a Docker image for my Drupal installation (not the database, just the Drupal files default found under /var/www/html), and deploy that image to production.

This approach would imply that all changes to the Drupal installation, i.e. all changes to anything under /var/www/html, would be considered immutable or read-only in production. Any changes here would be gone when the next deployment comes along.

I assume the content created by our content creators logged into our production server, is stored in the database, not in the Drupal installation itself.

My question is: Is there any reason why the Docker installation (i.e. files under /var/www/html) would need to be changed when deploying to production, or can these files remain consistent across environments (dev, test, prod)?

Note that I'm quite new to Drupal.

# Answer
The file containing the credentials for accessing the database, and other site configurations (e.g. the proxy settings, the trusted domains), is inside the server document root (for example, sites/default/settings.php). The answer to *Is there any reason for which the content of the server document root would need to be changed when deploying to production?* is then *yes*.

Add to this the fact that the directory for the public files (e.g. the uploaded images attached to nodes) is by default sites/default/files, you have a reason more to preserve one or more directories under the server document root directory in the production environment.
> 0 votes

---
Tags: deployment
---