# Question
Title: Why do I get "Nothing to install or update" when I update to latest core version?
Under /admin/modules/update, Drupal core is listed as requiring update from 8.8.8 to 8.9.2. I have started my Drupal installation using the *drupal/recommended-project* project template and I used `composer update drupal/core-recommended --with-dependencies` to update Drupal core, but when I run the above command, all I get is this message.

> Nothing to install or update

Am I missing something?

This is the content of the composer.json file.

```
{
    "name": "drupal/recommended-project",
    "description": "Project template for Drupal 8 projects with a relocated document root",
    "type": "project",
    "license": "GPL-2.0-or-later",
    "homepage": "https://www.drupal.org/project/drupal",
    "support": {
        "docs": "https://www.drupal.org/docs/user_guide/en/index.html",
        "chat": "https://www.drupal.org/node/314178"
    },
    "repositories": [
        {
            "type": "composer",
            "url": "https://packages.drupal.org/8"
        }
    ],
    "require": {
        "composer/installers": "^1.2",
        "drupal/addtoany": "^1.14",
        "drupal/admin_toolbar": "^2.3",
        "drupal/better_exposed_filters": "^4.0",
        "drupal/blazy": "^2.1",
        "drupal/business_rules": "^1.0",
        "drupal/captcha": "^1.1",
        "drupal/change_pwd_page": "^1.0",
        "drupal/colorbox": "^1.4",
        "drupal/conditional_fields": "^1.0",
        "drupal/core-composer-scaffold": "^8.8",
        "drupal/core-project-message": "^8.8",
        "drupal/core-recommended": "^8.8",
        "drupal/dynamic_entity_reference": "^1.10",
        "drupal/entity_reference_revisions": "^1.8",
        "drupal/eva": "^2.1",
        "drupal/field_group": "^3.1",
        "drupal/field_permissions": "^1.0",
        "drupal/field_timer": "1.x-dev",
        "drupal/firebase": "^2.0",
        "drupal/flag": "^4.0",
        "drupal/fontawesome": "^2.16",
        "drupal/google_analytics": "^3.1",
        "drupal/jquery_ui_accordion": "^1.1",
        "drupal/jquery_ui_checkboxradio": "^1.2",
        "drupal/module_filter": "^3.1",
        "drupal/pathauto": "^1.6",
        "drupal/persistent_login": "^1.3",
        "drupal/reroute_email": "^1.2",
        "drupal/simple_fb_connect": "^3.1",
        "drupal/simplify": "^1.1",
        "drupal/sitewide_alert": "^1.3",
        "drupal/slick": "^2.2",
        "drupal/slick_views": "^2.3",
        "drupal/sms": "^1.3",
        "drupal/sms_simplegateway": "^1.1",
        "drupal/subpathauto": "^1.1",
        "drupal/telephone_validation": "^2.3",
        "drupal/token": "^1.6",
        "drupal/token_filter": "^1.1",
        "drupal/ultimate_cron": "^2.0",
        "drupal/video": "^1.4",
        "drupal/views_infinite_scroll": "^1.7",
        "drupal/webform": "^6.0",
        "drush/drush": "^10.2",
        "wikimedia/composer-merge-plugin": "^1.4"
    },
    "require-dev": {
    },
    "conflict": {
        "drupal/drupal": "*"
    },
    "minimum-stability": "dev",
    "prefer-stable": true,
    "config": {
        "sort-packages": true
    },
    "extra": {
        "merge-plugin": {
            "include": [
                "web/modules/contrib/webform/composer.libraries.json"
            ]
        },
        "drupal-scaffold": {
            "locations": {
                "web-root": "web/"
            }
        },
        "installer-paths": {
            "web/core": ["type:drupal-core"],
            "web/libraries/{$name}": ["type:drupal-library"],
            "web/modules/contrib/{$name}": ["type:drupal-module"],
            "web/profiles/contrib/{$name}": ["type:drupal-profile"],
            "web/themes/contrib/{$name}": ["type:drupal-theme"],
            "drush/Commands/contrib/{$name}": ["type:drupal-drush"],
            "web/modules/custom/{$name}": ["type:drupal-custom-module"],
            "web/themes/custom/{$name}": ["type:drupal-custom-theme"]
        },
        "drupal-core-project-message": {
            "include-keys": ["homepage", "support"],
            "post-create-project-cmd-message": [
                "<bg=blue;fg=white>                                                         </>",
                "<bg=blue;fg=white>  Congratulations, you’ve installed the Drupal codebase  </>",
                "<bg=blue;fg=white>  from the drupal/recommended-project template!          </>",
                "<bg=blue;fg=white>                                                         </>",
                "",
                "<bg=yellow;fg=black>Next steps</>:",

                "  * Install the site: https://www.drupal.org/docs/8/install",
                "  * Read the user guide: https://www.drupal.org/docs/user_guide/en/index.html",
                "  * Get support: https://www.drupal.org/support",
                "  * Get involved with the Drupal community:",
                "      https://www.drupal.org/getting-involved",
                "  * Remove the plugin that prints this message:",
                "      composer remove drupal/core-project-message"
            ]
        }
    }
}

```

**Update #1:**

I have updated my composer.json file from:

```
"drupal/core-composer-scaffold": "^8.8",
"drupal/core-project-message": "^8.8",
"drupal/core-recommended": "^8.8",

```

to:

```
"drupal/core-composer-scaffold": "^8.9",
"drupal/core-project-message": "^8.9",
"drupal/core-recommended": "^8.9",

```

**But I got the below list of errors:**

```
user@example.com [~/public_html/test.example.com]# composer update drupal/core-recommended --with-dependencies
> DrupalProject\composer\ScriptHandler::checkComposerVersion
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 package drupal/core-dev (locked at 8.8.2, required as ^8.9) is satisfiable by drupal/core-dev[8.8.2] but these conflict with your requirements or minimum-stability.
  Problem 2
    - drupal/core-recommended 8.9.2 requires drupal/core 8.9.2 -> satisfiable by drupal/core[8.9.2].
    - Conclusion: don't install drupal/core 8.9.2
    - drupal/core-recommended 8.9.1 requires drupal/core 8.9.1 -> satisfiable by drupal/core[8.9.1].
    - Conclusion: don't install drupal/core 8.9.1
    - Installation request for symfony/polyfill-php72 (locked at v1.17.0) -> satisfiable by symfony/polyfill-php72[v1.17.0].
    - drupal/core-recommended 8.9.0 requires drupal/core 8.9.0 -> satisfiable by drupal/core[8.9.0].
    - Conclusion: don't install drupal/core 8.9.0
    - drupal/core-recommended 8.9.0-beta3 requires symfony/polyfill-php72 v1.15.0 -> satisfiable by symfony/polyfill-php72[v1.15.0].
    - drupal/core-recommended 8.9.0-rc1 requires symfony/polyfill-php72 v1.15.0 -> satisfiable by symfony/polyfill-php72[v1.15.0].
    - Conclusion: don't install symfony/polyfill-php72 v1.15.0
    - drupal/core-recommended 8.9.0-beta2 requires drupal/core 8.9.0-beta2 -> satisfiable by drupal/core[8.9.0-beta2].
    - Conclusion: don't install drupal/core 8.9.0-beta2
    - drupal/core-recommended 8.9.0-beta1 requires drupal/core 8.9.0-beta1 -> satisfiable by drupal/core[8.9.0-beta1].
    - Conclusion: don't install drupal/core 8.9.0-beta1
    - drupal/sms 1.3.0 requires drupal/core >=8.6 <8.9 -> satisfiable by drupal/core[8.8.8, 8.6.0, 8.6.0-alpha1, 8.6.0-beta1, 8.6.0-beta2, 8.6.0-rc1, 8.6.1, 8.6.10, 8.6.11, 8.6.12, 8.6.13, 8.6.14, 8.6.15, 8.6.16, 8.6.17, 8.6.18, 8.6.2, 8.6.3, 8.6.4, 8.6.5, 8.6.6, 8.6.7, 8.6.8, 8.6.9, 8.7.0, 8.7.0-alpha1, 8.7.0-alpha2, 8.7.0-beta1, 8.7.0-beta2, 8.7.0-rc1, 8.7.1, 8.7.10, 8.7.11, 8.7.12, 8.7.13, 8.7.14, 8.7.2, 8.7.3, 8.7.4, 8.7.5, 8.7.6, 8.7.7, 8.7.8, 8.7.9, 8.7.x-dev, 8.8.0, 8.8.0-alpha1, 8.8.0-beta1, 8.8.0-rc1, 8.8.1, 8.8.2, 8.8.3, 8.8.4, 8.8.5, 8.8.6, 8.8.7, 8.8.x-dev].
    - drupal/sms 1.3.0 requires drupal/core >=8.6 <8.9 -> satisfiable by drupal/core[8.8.8, 8.6.0, 8.6.0-alpha1, 8.6.0-beta1, 8.6.0-beta2, 8.6.0-rc1, 8.6.1, 8.6.10, 8.6.11, 8.6.12, 8.6.13, 8.6.14, 8.6.15, 8.6.16, 8.6.17, 8.6.18, 8.6.2, 8.6.3, 8.6.4, 8.6.5, 8.6.6, 8.6.7, 8.6.8, 8.6.9, 8.7.0, 8.7.0-alpha1, 8.7.0-alpha2, 8.7.0-beta1, 8.7.0-beta2, 8.7.0-rc1, 8.7.1, 8.7.10, 8.7.11, 8.7.12, 8.7.13, 8.7.14, 8.7.2, 8.7.3, 8.7.4, 8.7.5, 8.7.6, 8.7.7, 8.7.8, 8.7.9, 8.7.x-dev, 8.8.0, 8.8.0-alpha1, 8.8.0-beta1, 8.8.0-rc1, 8.8.1, 8.8.2, 8.8.3, 8.8.4, 8.8.5, 8.8.6, 8.8.7, 8.8.x-dev].
    - drupal/sms 1.3.0 requires drupal/core >=8.6 <8.9 -> satisfiable by drupal/core[8.8.8, 8.6.0, 8.6.0-alpha1, 8.6.0-beta1, 8.6.0-beta2, 8.6.0-rc1, 8.6.1, 8.6.10, 8.6.11, 8.6.12, 8.6.13, 8.6.14, 8.6.15, 8.6.16, 8.6.17, 8.6.18, 8.6.2, 8.6.3, 8.6.4, 8.6.5, 8.6.6, 8.6.7, 8.6.8, 8.6.9, 8.7.0, 8.7.0-alpha1, 8.7.0-alpha2, 8.7.0-beta1, 8.7.0-beta2, 8.7.0-rc1, 8.7.1, 8.7.10, 8.7.11, 8.7.12, 8.7.13, 8.7.14, 8.7.2, 8.7.3, 8.7.4, 8.7.5, 8.7.6, 8.7.7, 8.7.8, 8.7.9, 8.7.x-dev, 8.8.0, 8.8.0-alpha1, 8.8.0-beta1, 8.8.0-rc1, 8.8.1, 8.8.2, 8.8.3, 8.8.4, 8.8.5, 8.8.6, 8.8.7, 8.8.x-dev].
    - drupal/sms 1.3.0 requires drupal/core >=8.6 <8.9 -> satisfiable by drupal/core[8.8.8, 8.6.0, 8.6.0-alpha1, 8.6.0-beta1, 8.6.0-beta2, 8.6.0-rc1, 8.6.1, 8.6.10, 8.6.11, 8.6.12, 8.6.13, 8.6.14, 8.6.15, 8.6.16, 8.6.17, 8.6.18, 8.6.2, 8.6.3, 8.6.4, 8.6.5, 8.6.6, 8.6.7, 8.6.8, 8.6.9, 8.7.0, 8.7.0-alpha1, 8.7.0-alpha2, 8.7.0-beta1, 8.7.0-beta2, 8.7.0-rc1, 8.7.1, 8.7.10, 8.7.11, 8.7.12, 8.7.13, 8.7.14, 8.7.2, 8.7.3, 8.7.4, 8.7.5, 8.7.6, 8.7.7, 8.7.8, 8.7.9, 8.7.x-dev, 8.8.0, 8.8.0-alpha1, 8.8.0-beta1, 8.8.0-rc1, 8.8.1, 8.8.2, 8.8.3, 8.8.4, 8.8.5, 8.8.6, 8.8.7, 8.8.x-dev].
    - Can only install one of: drupal/core[8.9.x-dev, 8.8.0].
    - Can only install one of: drupal/core[8.9.x-dev, 8.8.0-alpha1].
    - Can only install one of: drupal/core[8.9.x-dev, 8.8.0-beta1].
    - Can only install one of: drupal/core[8.9.x-dev, 8.8.0-rc1].
    - Can only install one of: drupal/core[8.9.x-dev, 8.8.1].
    - Can only install one of: drupal/core[8.9.x-dev, 8.8.2].
    - Can only install one of: drupal/core[8.9.x-dev, 8.8.3].
    - Can only install one of: drupal/core[8.9.x-dev, 8.8.4].
    - Can only install one of: drupal/core[8.9.x-dev, 8.8.5].
    - Can only install one of: drupal/core[8.9.x-dev, 8.8.6].
    - Can only install one of: drupal/core[8.9.x-dev, 8.8.7].
    - Can only install one of: drupal/core[8.9.x-dev, 8.8.8].
    - Can only install one of: drupal/core[8.9.x-dev, 8.8.x-dev].
    - Can only install one of: drupal/core[8.9.x-dev, 8.6.0].
    - Can only install one of: drupal/core[8.9.x-dev, 8.6.0-alpha1].
    - Can only install one of: drupal/core[8.9.x-dev, 8.6.0-beta1].
    - Can only install one of: drupal/core[8.9.x-dev, 8.6.0-beta2].
    - Can only install one of: drupal/core[8.9.x-dev, 8.6.0-rc1].
    - Can only install one of: drupal/core[8.9.x-dev, 8.6.1].
    - Can only install one of: drupal/core[8.9.x-dev, 8.6.10].
    - Can only install one of: drupal/core[8.9.x-dev, 8.6.11].
    - Can only install one of: drupal/core[8.9.x-dev, 8.6.12].
    - Can only install one of: drupal/core[8.9.x-dev, 8.6.13].
    - Can only install one of: drupal/core[8.9.x-dev, 8.6.14].
    - Can only install one of: drupal/core[8.9.x-dev, 8.6.15].
    - Can only install one of: drupal/core[8.9.x-dev, 8.6.16].
    - Can only install one of: drupal/core[8.9.x-dev, 8.6.17].
    - Can only install one of: drupal/core[8.9.x-dev, 8.6.18].
    - Can only install one of: drupal/core[8.9.x-dev, 8.6.2].
    - Can only install one of: drupal/core[8.9.x-dev, 8.6.3].
    - Can only install one of: drupal/core[8.9.x-dev, 8.6.4].
    - Can only install one of: drupal/core[8.9.x-dev, 8.6.5].
    - Can only install one of: drupal/core[8.9.x-dev, 8.6.6].
    - Can only install one of: drupal/core[8.9.x-dev, 8.6.7].
    - Can only install one of: drupal/core[8.9.x-dev, 8.6.8].
    - Can only install one of: drupal/core[8.9.x-dev, 8.6.9].
    - Can only install one of: drupal/core[8.9.x-dev, 8.7.0].
    - Can only install one of: drupal/core[8.9.x-dev, 8.7.0-alpha1].
    - Can only install one of: drupal/core[8.9.x-dev, 8.7.0-alpha2].
    - Can only install one of: drupal/core[8.9.x-dev, 8.7.0-beta1].
    - Can only install one of: drupal/core[8.9.x-dev, 8.7.0-beta2].
    - Can only install one of: drupal/core[8.9.x-dev, 8.7.0-rc1].
    - Can only install one of: drupal/core[8.9.x-dev, 8.7.1].
    - Can only install one of: drupal/core[8.9.x-dev, 8.7.10].
    - Can only install one of: drupal/core[8.9.x-dev, 8.7.11].
    - Can only install one of: drupal/core[8.9.x-dev, 8.7.12].
    - Can only install one of: drupal/core[8.9.x-dev, 8.7.13].
    - Can only install one of: drupal/core[8.9.x-dev, 8.7.14].
    - Can only install one of: drupal/core[8.9.x-dev, 8.7.2].
    - Can only install one of: drupal/core[8.9.x-dev, 8.7.3].
    - Can only install one of: drupal/core[8.9.x-dev, 8.7.4].
    - Can only install one of: drupal/core[8.9.x-dev, 8.7.5].
    - Can only install one of: drupal/core[8.9.x-dev, 8.7.6].
    - Can only install one of: drupal/core[8.9.x-dev, 8.7.7].
    - Can only install one of: drupal/core[8.9.x-dev, 8.7.8].
    - Can only install one of: drupal/core[8.9.x-dev, 8.7.9].
    - Can only install one of: drupal/core[8.9.x-dev, 8.7.x-dev].
    - Can only install one of: drupal/core[8.9.x-dev, 8.8.8].
    - Can only install one of: drupal/core[8.9.x-dev, 8.8.8].
    - drupal/core-recommended 8.9.x-dev requires drupal/core 8.9.x-dev -> satisfiable by drupal/core[8.9.x-dev].
    - Installation request for drupal/core-recommended ^8.9 -> satisfiable by drupal/core-recommended[8.9.0, 8.9.0-beta1, 8.9.0-beta2, 8.9.0-beta3, 8.9.0-rc1, 8.9.1, 8.9.2, 8.9.x-dev].
    - Installation request for drupal/sms (locked at 1.3.0, required as ^1.3) -> satisfiable by drupal/sms[1.3.0].

```

**UPDATE #2:**

I removed the `composer.lock` file and ran: `composer install` command!

A bunch of updates ran smoothly including `drupal/core-dev (8.8.2 => 8.9.2)`, but when I visit `/admin/reports/updates/update`, I still can see update avaialble for Drupal core (`Drupal core 8.8.8 -> 8.9.2`) also in the `composer.json` file, the Drupal version is still `"drupal/core-recommended": "^8.8"` and in the `composer.lock` file the Drupal version is:

```
"name": "drupal/core-recommended",
"version": "8.8.8",
"source": {
"type": "git",
"url": "https://github.com/drupal/core-recommended.git",
"reference": "69f4e74170c35f2069baafbbb5b7717fe5ddbb66"

```

Note: After `composer install`, I did run `drush updb` and `drush cr`

# Answer
> -1 votes
I think you have to change the following lines of your `composer.json`

```
    "drupal/core-composer-scaffold": "^8.8",
    "drupal/core-project-message": "^8.8",
    "drupal/core-recommended": "^8.8",

```

with

```
    "drupal/core-composer-scaffold": "^8.9",
    "drupal/core-project-message": "^8.9",
    "drupal/core-recommended": "^8.9",

```

As the current settings constraints the drupal/core to 8.8.x version.

---
Tags: 8, composer
---


# Question
Title: How can I change the front-page title when front page is not /node?
I changed the site's front page from `/node` to another page. However, now the title of the front page is *page name* | *site name*. To clear up any confusion, by "title," I mean the phrase entered between the HTML `<title>` tags.

I tried this SO answer, but it had no effect. How can I declaratively change the name of the site's main page?

# Answer
It's not possible to change the front page title declaratively without adding a new module, such as the Metatag module. Drupal's core does not have this functionality. However, you can achieve this with a few lines of code implementing `template_preprocess_html` in your custom theme.

To achieve this dynamically in a subtheme, add this code to your `preprocess_html` function of your theme file or add if it doesn't exist.

```
function MYTHEME_preprocess_html(&$variables) {
  if (\Drupal::service('path.matcher')->isFrontPage()) {
    $variables['head_title'] = [t('Hello World')];
  }
}

```

**Note:** *Credit to @leymanx for the basis for the above code, which just needed a slight modification to update the title as originally asked, rather than just the portion of the before name of the site.*
> -2 votes

# Answer
You can use the Metatag module. It has a section for front page metatags, where you can set the title.
> 7 votes

# Answer
The default Frontpage is a view (`admin/structure/views/view/frontpage/edit`) showing a waterfall of all content that is Published and "Promoted to the Frontpage". By default, the Frontpage view's Title is "none" while the HTML Title tag is "Home | MySite.com".

So you can change the `Title` of the view there to e.g. "Start" and the HTML title will change to "Start | MySite.com".

If, instead of using the Frontpage view, you choose a node for your home page (e.g. "node/10 ), then you can name the page "Home" and the HTML title will become "Home | MySite.com".

If you don't want the title of the page showing up in the page's content area (but you do want it in the home page's HTML `title` tag), you can hide the title block in `admin/structure/block/manage/yourtheme_page_title`.

The Metatag module, along with Token, can also be used for this and general SEO enhancements, but you said you are trying to avoid that.
> 5 votes

# Answer
You can achieve this with a few lines of code implementing `template_preprocess_html` in your custom theme.

```
/**
 * Implements template_preprocess_html().
 */
function MYTHEME_preprocess_html(&$variables) {
  if (\Drupal::service('path.matcher')->isFrontPage()) {
    $variables['head_title']['title'] = t('Hello World');
  }
}

```
> 4 votes

---
Tags: 8, meta-tags
---


title: Non-Config Menus

text:
# Question
Title: Non-Config Menus
I have this requirement where I would need to create a menu every time a user creates a new instance of a custom entity I'm building. One can easily do this with `Menu::create()` on entity creation, but there is one problem: Menus are configuration.

When one creates a menu either programmatically or via menu admin, it creates "unexported configuration" of that menu that lives in the DB. The next time code is deployed and those menus aren't exported to code, those menus either get deleted (if empty) or halt the deploy (if there are menu links present).

I was hoping to preserve the menu functionality (menu management, etc.) but have them not be config. Is there a way to create menus that aren't configuration?

# Answer
Not exactly. You could theoretically build non-config menus with a custom module, but I don't think that's what you want to do.

You can, however, keep the menus as config, but keep them from being exported / imported. You can use two contrib modules to do this.

The first module, Config ignore is **required**. This module allows to set config files that should be ignored when importing config via its UI at *admin/config/development/configuration/ignore*. Some example configuration for your situation might look like:

```
system.menu.*
~system.menu.main
~system.menu.admin

```

The first line will tell config\_ignore to prevent all menu configs from being imported. The second line tells it to unignore the main menu configuration, the third line tells it to unignore the admin menu configuration. This would prevent any of your on-the-fly menus from being deleted during import, but allow you to keep the main and admin menus managed via your configuration. Obviously, you can also unignore any number of additional menus.

One minor issue with config\_ignore is that it only prevents configuration from being imported, it doesn't stop them from being exported. So, for example, if you were to pull your prod DB down to your local environment and then export your config, all of the configuration for those new menus will be exported to the sync directory. All of those configuration files will be ignored on the import end so it doesn't hurt, but I don't like having a bunch of extra config in my sync directory that 1. isn't used and, 2. isn't an accurate representation of the actual state of the menus.

The second module, Config Split is optional, but I like to use it in this situation to help keep things tidy; it solves the minor issue with config\_ignore that I mentioned in the last paragraph.

Config split lets you split some configuration from the main sync directory to other directories. The main way I've used this is to split out environment specific configuration to environment specific directories. For example, I have one split for my local environment, a second for staging, and another for prod. However, config\_split also allows you to use a special database storage, instead of a file directory, if you don't define a split directory, i.e. leave that field empty. This is a great feature because you can use it to route all of the menu configuration files, the files that you're ignoring with config\_ignore, to the special database storage. This keeps them out of your sync directory, thus removing all that clutter!

To use this special database storage, navigate to Config Split's UI at */admin/config/development/configuration/config-split* and *Add A Configuration Split Setting*. First, give it a label, e.g. *Database Storage*. Second, in the *COMPLETE SPLIT* section, enter settings in the *Additional Configuration* field that are identical to what you entered in the config\_ignore settings. For example:

```
system.menu.*
~system.menu.main
~system.menu.admin

```

That's it. Boom! The menus that you programmatically created on prod won't be deleted when you deploy. The configuration for those items now lives totally in the database.
> 2 votes

---
Tags: 8, entities, navigation, plugins
---


# Question
Title: Remove one of the two "Apply to selected items" submit buttons with Node Bulk Operations
If you make a view and add the **Node operations bulk form**, two "Apply to selected items" boxes are automatically generated like this:

How do I get rid of one of these?

I turned on twig debugging, but the template that is outputting the button is `core/modules/system/templates/container.html.twig`, which is not something that I can easily customize to remove one of the buttons.

How I created the view:

1. Create a new view of *content* showing *fields*.
2. Add *Node operations bulk form* under **Fields**.
3. Save the view.

# Answer
This is intentional functionality for some workflows (for long lists of results).

If you wanted to get rid of the button, you could `hook_form_alter` it away. Form IDs and array structure are dynamic based on your view so you'll have to adjust accordingly based on the view & action button to remove (this can be found in the Views UI, if not known).

```
/**
 * Implements hook_form_alter().
 */
function MODULE_form_alter(&$form, FormStateInterface $form_state, $form_id) {

  // @TODO: Determine view_id / display_id / field_id for a specific VBO form:
  if ($form_id == 'views_form_' . $view_id . '_' . $display_id) {
    // HEADER ACTION BUTTON:
    //unset($form['header'][$field_id]['actions']);
    // FOOTER ACTION BUTTON:
    //unset($form['actions']['submit']);
  }

```
> 1 votes

---
Tags: views
---


# Question
Title: How can I save and exit from the middle of editing an already completed multipage webform submission?
I've got a multipage webform I'm letting users ***edit*** after they submit. There are many pages, and I don't want to force the user to go all the way to the last page to save. Is there a way to submit/save the form either with a Save Draft button, or when they use the prev/next buttons? Or is there a way to programmatically save the edited form ? That would also work.

**This question is about editing a completed submission, not creating a new submission.**

I've tried adding the submit button to every page, but it seems to function like a next button. If I set rebuild to false, the I can exit the edit process where I want, but the changes are not saved.

I've also tried manually adding a save draft button copied from the webform submission form, but that also did not work, failing the way the submit button did.

# Answer
I was able to get this to work like so:

In a form alter, make the Submit button visible, and change the name.

```
   if (stristr($form_id, 'edit_form') !== FALSE) {
    $form["actions"]["submit"]['#value'] = t('Save & Exit');
    $form["actions"]["submit"]["#access"] = TRUE;
    $form["actions"]["submit"]["#_webform_access"] = TRUE;
    // Add a custom submit function so we can redirect the edit form.
    $form['actions']['submit']['#submit'][] = 'mymodule_webform_submission_form_submit';
    $form['actions']['submit']['#validate'][] = 'mymodule_webform_submission_form_validate';

  }

```

Next, in the custom validation function:

```
  // If this is the edit form, and the submit button is the trigger, always
  // do the final submit by setting the current wizard page to the confirmation
  // page.
  $trigger = $form_state->getTriggeringElement();
  if ($trigger["#id"] == 'edit-actions-submit' &&
    stristr($form['form_id']['#value'], 'edit_form') !== FALSE) {
    $form_state->set('current_page', 'webform_confirmation');
  };

```

Finally, in the custom submit function:

```
$build = $form_state->getBuildInfo();
$callback_object = $build['callback_object'];
$entity = $callback_object->getEntity();
$source = $entity->getSourceEntity();
if (!is_null($source)) {
  $nid = $entity->getSourceEntity()->id();
  $form_state->setRedirect('entity.node.canonical', ['node' => $nid]);
  $form_state->setRebuild(FALSE);
  \Drupal::messenger()->addStatus("Your work has been saved.");
}

```

While this answers my question, it leaves me having to deal with potential errors from conditionally required fields affected by whatever changes the user is trying to save.
> 0 votes

---
Tags: 8, webforms
---


# Question
Title: Workaround for missing migrate-deregister command in Drush 10.3.1?
I'm trying to migrate and upgrade a site from Drupal 7 to Drupal 8 (version 8.9.1). The migration cannot be accomplished with the UI, since I need to make some changes to the content types and taxonomies during the process. I followed the advice at https://www.drupal.org/docs/upgrading-drupal/upgrade-using-drush and generated individual migrations using `drush migrate-upgrade --configure-only` so that I could use the YAML files it generates as the basis for a custom migration module.

After I built my module, I ran `drush migrate-status` (alias `drush ms`). I can see that my migrations are registered, but the ones generated earlier by `drush migrate-upgrade` are also there. In the past, removing them would be a simple matter of using `drush migrate-deregister` (alias `drush mdreg`), but that command, strangely, is no longer available in the current version of Drush (10.3.1).

How do I deregister the migrations that were generated by `drush migrate-upgrade --configure-only`? I am assuming that if I don't deregister them, my content will be migrated twice, and I don't want that to happen.

# Answer
> 1 votes
Those migrations are stored as configuration. When you run `drush migrate-upgrade --configure-only` the command created various `migrate_plus.migration.*` config data related to your D7 migration.

If you remove the config, you'll remove the migrations. For example:

* If you have config captured in a sync directory, do a `drush cex`, remove all `migrate_plus.migration.*` yml files, then `drush cim`. Drush will drop all migration configuration on import.
* If you'd rather delete the migration directly, `drush cdel` will let you specifically delete a migration.

Even if you delete the migration config, some migration metadata is still kept around in the database (see `migrate_map_` & `migrate_messages_` tables). They'll be re-used if you re-import migration config. If you're finally finished with your migrations, you can delete them.

---
Tags: 8, drush, migrations
---


title: Entity Browser in Forms API

text:
# Question
Title: Entity Browser in Forms API
I'm having trouble getting the entity browser widget to work correctly in a custom form. Just wondering if anyone has had any success in getting it working. I've got to the point the button is rendering, you can use the browser, select the media. The the media id is also attached to the hidden field the widget generates.

...from my digging around it looks like it never creates the right markup in the "current" div that get sent back from the ajax request that triggers on "process"

Code below...

```
      $form['entity_browser_wrapper'] = [
      '#type' => 'container',
      'widget' => [
          '#title' => t('Entity Browser'),
          '#field_name' => 'entity_browser_wrapper',
          '#field_parents' => [],
          '#required' => false,
          '#parents' => ['entity_browser_wrapper'],
          '#tree' => true,
          '#id' => 'edit-entity-browser-wrapper',
          '#type' => 'details',
          '#open' => true,
          'entity_browser' => [
              '#type' => 'entity_browser',
              '#entity_browser' => 'document_browser',
              '#cardinality' => 1,
              '#entity_browser_validators' => ['entity_type' => ['type' => 'media']],
              '#process' => [
                  ['\Drupal\entity_browser\Element\EntityBrowserElement', 'processEntityBrowser'],
                  ['\Drupal\entity_browser\Plugin\Field\FieldWidget\EntityReferenceBrowserWidget', 'processEntityBrowser'],
              ]
          ],
          'current' => [
              '#theme_wrappers' => ['container'],
              '#attributes' => [
                  'class' => 'entities-list',
              ],
              'items' => [],
          ],
      ],
  ];

```

This is based off a question I found in the entity browser issues https://www.drupal.org/node/2816881. I've looked into the suggestions that were posted and have come up blank.

Thanks

# Answer
I got a possibly easier solution. you need to have entity\_browser and entity\_browser\_block required as dependencies and installed in your module. Then in your BlockBase buildForm or LayoutDefault buildConfigurationForm you can do something like what they do in the entity\_browser\_block module in the EntityBrowserBlock.php

```
// make sure you have this at the top of your file
use Drupal\entity_browser_block\Plugin\Block\EntityBrowserBlock;

// blockForm or buildConfigurationForm
$test = EntityBrowserBlock::loadEntitiesByIDs(explode(' ',$configuration['selection']['entity_browser']['entity_ids']));
$form['selection'] = [
  '#type' => 'container',
  '#attributes' => ['id' => 'entity-browser-block-form'],
];
$form['selection']['entity_browser'] = [
  '#type' => 'entity_browser',
  '#entity_browser' => 'classes',
  '#process' => [
    [
      '\Drupal\entity_browser\Element\EntityBrowserElement',
      'processEntityBrowser',
    ],
    ['\Drupal\entity_browser_block\Plugin\Block\EntityBrowserBlock', 'processEntityBrowser'],
  ],
  '#default_value' => $test,
];

$order_class = 'entity-browser-block-delta-order';

$form['selection']['table'] = [
  '#type' => 'table',
  '#header' => [
    $this->t('Title'),
    $this->t('Operations'),
  ],
  '#empty' => $this->t('No entities yet'),
  '#tabledrag' => [
    [
      'action' => 'order',
      'relationship' => 'sibling',
      'group' => $order_class,
    ],
  ],
  '#process' => [
    ['\Drupal\entity_browser_block\Plugin\Block\EntityBrowserBlock', 'processTable'],
  ],
  '#default_view_modes' => 'default',
];

```
> 0 votes

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


title: Why doesn't my date get rendered?

text:
# Question
Title: Why doesn't my date get rendered?
In Drupal 8, I have a **Flag** entity with a date field attached.

My code looks like this:

```
function MYMODULE_flagging_presave(FlaggingInterface $flagging) {
    if ($score == 0 || $score == 1) {
      $flagging->field_date_review = date("Y-m-d", strtotime('today'));
    }
    else {
      $date = date("Y-m-d", strtotime("+$interval days"));
      $flagging->field_date_review = $date;
    }

```

I checked and the dates get stored in the database like `2020-07-02`.

I have a custom view that shows these flaggings, and I added a filter for nodes with a date field value of less than +1 days; this behaves as expected, so the Views module seems to understand the dates as I stored them.

But, when I try to add the date **field**, I get an empty display in Views.

**Further debugging**

When I render the flagging entity, the date field doesn't show a value, either.

Other fields set in \`\`hook\_flagging\_presave()\` are displayed correctly; it's only the date field that doesn't have a value.

**Configuration**

On the flagging entity's *Manage display* screen, I have set my date field to use the *Plain* format with no timezone offset. I also tried the *Default* format and several others, but nothing let me display the value.

There are no errors in the recent log messages.

To sum up: the date field has data in the database, which Views can see and use for filters. But, this date field cannot be displayed in Views or on the rendered flagging entity.

What do I need to do to get the date to be displayed?

# Answer
I found it-- the **Date** field can store *dates* or *datetimes*, and you have to change your code for each case.

When you add a **Date** field to an entity, you can choose *Date* (*date*) or *Date and time* (*datetime*) as the **Date type**.

More information in this blog post, but the basic idea is:

```
$node->set('field_date', date('Y-m-d', time()));
$node->set('field_datetime', date('Y-m-d\TH:i:s', time()));

```
> 1 votes

---
Tags: datetime
---


# Question
Title: How to programmatically print a webform block with caching enabled?
When displaying a Webform inside a normal block (using `admin/structure/block`) Drupal manage to correctly cache the page, the HTTP header displays `X-Drupal-Dynamic-Cache: HIT`.

However we need to display this webform inside a paragraph so we tried the following :

* use twig\_tweak module and `{{ drupal_block('webform_...') }}`
* programmatically put the block in a template preprocess like this :

```
$my_form = \Drupal\webform\Entity\Webform::load('contact_new');
$output = \Drupal::entityManager()
          ->getViewBuilder('webform')
          ->view($my_form);
$variables['contact_form'] = $output;

```

Both solutions seem to make the page uncacheable: `X-Drupal-Dynamic-Cache: UNCACHEABLE`.

What would be the correct way to put a block in a paragraph while make the page cacheable ?
How to mimic the standard block system to display a in our template ?

# Answer
The Dynamic Page Cache needs to placeholder the dynamic part and it can only do so when it is built in a lazy builder:

*/mymodule/src/WebformLazyBuilder.php*

```
<?php

namespace Drupal\mymodule;

use Drupal\Core\Render\Element\RenderCallbackInterface;

class WebformLazyBuilder implements RenderCallbackInterface {

  public static function buildWebform($webform) {
    return  [
      'webform' => [
        '#type' => 'webform',
        '#webform' => $webform,
      ],
    ];
  }

}

```

Then you can put the lazy builder in a template preprocess hook:

```
$variables['contact_form'] =  [
  '#lazy_builder' => ['\Drupal\mymodule\WebformLazyBuilder::buildWebform', ['contact']],
  '#create_placeholder' => TRUE,
];

```

Blocks are placed in a lazy builder by default, see BlockViewBuilder::viewMultiple.
> 3 votes

---
Tags: 8, webforms, caching
---


# Question
Title: How to filter nodes on a view based on user role shared by both nodes authors and current user?
Working on Drupal 8.9.1

I need to list nodes with Views and filter them based on user role shared by both nodes authors and current user.

If I add a relationship to content author and a contextual filter on (author)User ID with default provided by logged user ID, I only get nodes authored by the current user.

Let's say we have a role "Staff A", I need any user with this role to be able to see any nodes from any users with the same role "Staff A".

Thanks for any tip here.

# Answer
Finally, using role as contextual filter was not a good choice. It is working now but with a different option.

Using a term reference field for both user and node with the same vocabulary was my solution.

In my example, let's say I have a taxonomy field called Staff (field\_staff), related to a vocabulary called Staff too.

I have added this field to user account and content type (the one(s) I need in Views).

Then, within my View, I have added two relationships:

Content using field\_staff and

User using field\_staff with a relationship to the previous relationship (reverse\__user\__field\_staff).

Finally, I have added a contextual filter on User ID provided by default (logged in user) and with a relationship to User using field\_staff.

And voilà, the view is listing any nodes filtered by field\_staff equal to the current user field\_staff.

Hope this helps.
> 0 votes

---
Tags: 8, views
---


# Question
Title: How can I allow the current user to only see their own page?
I created a page in a custom module. I want only the current user to access this page on their behalf.

For example, I am using it with ID 51. If I go to :

```
/user/51/tasks

```

I can see this page.

If I go on :

```
/user/78/tasks

```

I must have an error 403 access denied.

How to do this ?

```
task_notify.user_page.tasks:
  path: '/user/{user}/tasks'
  defaults:
    _controller: '\Drupal\task_notify\Controller\TaskNotifyUserController::Tasks'
    _title: 'Liste des tâches'
  requirements:
    _permission: 'access content'

```

**UPDATE :**

My custom module is here :

https://git.drupalcode.org/sandbox/zenimagine-3076032

I applied kiamlaluno's answer but I have the following error :

/task\_notify/src/Controller/TaskNotifyUserController.php

```
<?php

namespace Drupal\task_notify\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Session\AccountInterface;
use Drupal\user\UserInterface;

class TaskNotifyUserController extends ControllerBase {

  public function Tasks() {
    return [
      '#theme' => 'task_notify_user_template',
    ];
  }

  public function taskAccess(UserInterface $user, AccountInterface $account) {
    return AccessResult::allowedIf($account->isAuthenticated() && $user->id() == $account->id())
      ->orIf(AccessResult::allowedIfHasPermission($account, 'administer users'))
      ->cachePerUser();
  }

}

```

# Answer
> 3 votes
*\_permission* only allows to give access to the route to the users who have that permission; it doesn't allow to give access basing on more complex conditions, as in the case of this question. As described in Custom route access checking, the route definition should be similar to the following one.

```
task_notify.user_page.tasks:
  path: '/user/{user}/tasks'
  defaults:
    _controller: '\Drupal\task_notify\Controller\TaskNotifyUserController::tasks'
    _title: 'Tasks list'
  requirements:
    _custom_access:  '\Drupal\task_notify\Controller\TaskNotifyUserController::taskAccess'
    user: \d+

```

The `TaskNotifyUserController` class would need to contain at least the following code (and other methods you need from that controller, including `tasks()`).

```
class TaskNotifyUserController extends ControllerBase {

  /**
   * Checks access for the users task page.
   *
   * @param \Drupal\user\UserInterface $user
   *   The user being viewed.
   * @param \Drupal\Core\Session\AccountInterface $account
   *   The account viewing the page.
   *
   * @return \Drupal\Core\Access\AccessResultInterface
   *   The access result.
   */
  public function taskAccess(UserInterface $user, AccountInterface $account) {
  public function taskAccess(UserInterface $user) {
    return AccessResult::allowedIf($account->isAuthenticated() && $user()->id() == $account->id())
      ->cachePerUser();
  }

}

```

If then the access to the route should be allowed also to users with a specific permission (for example, the permission to administer users), the `taskAccess()` code would be similar to the following one.

```
  /**
   * Checks access for the users task page.
   *
  /**
   * Checks access for the tasks tab.
   *
   * @param \Drupal\user\UserInterface $user
   *   The user being viewed.
   * @param \Drupal\Core\Session\AccountInterface $account
   *   The account viewing the page.
   *
   * @return \Drupal\Core\Access\AccessResultInterface
   *   The access result.
   */
  public function taskAccess(UserInterface $user, AccountInterface $account) {
    return AccessResult::allowedIf($account->isAuthenticated() && $user->id() == $account->id())
      ->orIf(AccessResult::allowedIfHasPermission($account, 'administer users'))
      ->cachePerUser();
  }

```

Don't forget to import the class used from the controller, adding the following lines at the top of the controller file.

```
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Session\AccountInterface;
use Drupal\user\UserInterface;

```

If the controller class uses other classes from different namespaces, similar lines must be added for each class.

I took the code used from Drupal core for the Tracker module as example. The Tracker module shows its tracker page on /activity/{user} using a controller to render it. See TrackerController.php.

```
  /**
   * Checks access for the users recent content tracker page.
   *
   * @param \Drupal\user\UserInterface $user
   *   The user being viewed.
   * @param \Drupal\Core\Session\AccountInterface $account
   *   The account viewing the page.
   *
   * @return \Drupal\Core\Access\AccessResult
   *   The access result.
   */
  public function checkAccess(UserInterface $user, AccountInterface $account) {
    return AccessResult::allowedIf($account->isAuthenticated() && $user
      ->id() == $account->id())->cachePerUser();
  }

```

The custom access callback is defined in tracker.routing.yml.

```
tracker.users_recent_content:
  path: '/activity/{user}'
  defaults:
    _controller: '\Drupal\tracker\Controller\TrackerController::buildContent'
    _title: 'My recent content'
  requirements:
    _permission: 'access content'
    _custom_access: '\Drupal\tracker\Controller\TrackerController::checkAccess'
    user: \d+

```

# Answer
> 0 votes
In `TaskNotifyUserController::Task` you can access the current user with `Drupal::currentUser()`. Then compare that id with the id from the current `Request`, or if you're dealing with a node, the node's author's id (`uid`). If they don't match, issue a `RedirectResponse` or regular `Response('', Response::HTTP_FORBIDDEN)`.

---
Tags: 8, routes
---


# Question
Title: Adding Constraint to entity referenced Paragraph field
I'm attempting to follow this documentation to add a custom constraint to a field in a Paragraph but I'm having trouble in adding constraint to that field.

Currently I have `book` content type with paragraph type `bibliographic_information`. This paragraph type has a field named as `field_book_edition`. This field accepts a string value. I'd like to be able to add a constraint to the field so that it accepts a certain string pattern as input.

I've created constrain and tried using `hook_entity_bundle_field_info_alter`, when ever I try to save the node I am getting the following error.

> The website encountered an unexpected error. Please try again later.

> InvalidArgumentException: Field field\_bibliographic\_information is unknown. in Drupal\Core\Entity\ContentEntityBase-\>getTranslatedField() (line 587 of core/lib/Drupal/Core/Entity/ContentEntityBase.php).

My Code is as follows :

**book\_content.module**

```
use Drupal\Core\Entity\EntityTypeInterface;

/**
 * Implements hook_entity_bundle_field_info_alter().
 */
function book_content_entity_bundle_field_info_alter(&$fields, EntityTypeInterface $entity_type, $bundle) {

  // Refer https://drupal.stackexchange.com/a/277438/

  if ($entity_type->id() === 'paragraph' && $bundle === 'bibliographic_information' && isset($fields['field_book_edition'])) {

    // Add our custom validation to the book edition field.
    $fields['field_book_edition']->addConstraint('BookContentEditionConstraint');
  }

}

```

**BookContentEditionConstraintValidator.php**

```
namespace Drupal\book_content\Plugin\Validation\Constraint;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

/**
 * Validates the Book Content constraint.
 */
class BookContentEditionConstraintValidator extends ConstraintValidator {

  /**
   * {@inheritdoc}
   */
  public function validate($entity, Constraint $constraint) {

    $node = $entity->getEntity();

    // Get referenced paragraph entities.
    $referenceItem = $node->get('field_bibliographic_information')->referencedEntities();

    foreach ($referenceItem as $data) {

      $fields = [
        'field_book_author' => $data->field_book_price->value,
        'field_book_edition'  => $data->field_book_edition->value,
        'field_book_language'  => $data->field_book_language->value,
        'field_book_pages'  => $data->field_book_pages->value,
        'field_book_price'  => $data->field_book_price->value,
        'field_book_published_year'  => $data->field_book_published_year->value,
        'field_book_synopsis'  => $data->field_book_synopsis->value,
        'field_website'  => $data->field_website->getValue()[0]['uri'],
      ];
    }

    // Check if the book edition matches or not.
    if ($fields['field_book_edition'] != 'asdfg') {

      $this->context->addViolation($constraint->invalidEdition, ['@edition' => $fields['field_book_edition']]);
    }

  }

}

```

Attached the Node and Paragraph structures screenshot.

I have gone through similar questions and read their comments/answers but coundn't find what exactly is the error in the code.

Add Constraint to Paragraph Field answer by Carlos

Adding Constraint to Paragraph field comment by 4k4

I implemented the same what is mentioned in both the links.But still it is not working.

For debugging purpose I have added the above constraint to a node field and it worked as expected.

From what I read if you provide the correct `$entity_type->id()` all the fields for the particular entity id will be rendered in `$fields` variable in `hook_entity_bundle_field_info_alter` , is my understanding is correct ?

Should I be implementing `hook_entity_bundle_field_info_alter` or `hook_form_alter` for adding a custom constraint to a paragraph field ?

**EDIT 1:**

After further debugging if I add

```
if ($node->hasField('field_bibliographic_information')) {
   \Drupal::logger('book_content')->info('Hello');
 $referenceItem = $node->get('field_bibliographic_information')->referencedEntities();
 ....remaining code.....
 }

```

in `validate` method the code inside the loop doesn't get executed.

# Answer
I am able to achieve this finally.

Basically what I was doing wrong was I was assuming the $entity is a node object and but it actually is paragraph object.

```
<?php

namespace Drupal\book_content\Plugin\Validation\Constraint;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

/**
 * Validates the Book Content constraint.
 */
class BookContentEditionConstraintValidator extends ConstraintValidator {

  /**
   * {@inheritdoc}
   */
  public function validate($items, Constraint $constraint) {

    if (!$item = $items->first()) {
      return;
    }

    $field_name = $items->getFieldDefinition()->getName();

    /** @var \Drupal\Core\Entity\EntityInterface $entity */
    $entity = $items->getEntity();

    if ($entity->hasField('field_book_edition')) {

      $edition = $entity->field_book_edition->value;

      // Check if the book edition matches or not.
      if ($edition != 'asdfg') {

        $this->context->addViolation($constraint->invalidEdition, ['@edition' => $edition]);
      }

    }

  }

}

```
> 2 votes

---
Tags: 8, forms, plugins
---


title: Programmatically set a datetime field

text:
# Question
Title: Programmatically set a datetime field
I already asked a question like this (Set date field in D8).

Ok duplicate entry? NO!

Now i have also to set a time and i'm using a array. My code looks like this.

```
$field_array = [
##begin of creating node
'uid' => $new_old_uid["new_uid"],
'type' => $content_type,
'langcode' => $lang,
'status' => (!empty($import_node->status)) ? $import_node->status : 0,

#### How to create date with times?
#Every Version causes that error -> Array to string conversion in ....
### Version 1
'field_event_date_start' => [[ "value"=> date('Y-m-d H:i:00',$imported_date) ]],
'field_event_date_end' => [[ "value"=> date('Y-m-d H:i:00',$imported_date) ]],
### Version 2
'field_event_date_start' => [ "value"=> date('Y-m-d H:i:00',$imported_date) ],
'field_event_date_end' => [ "value"=> date('Y-m-d H:i:00',$imported_date) ],

### How to add a url?
'field_event_url' => (!empty($import_node->field_event_url)) ? array('value'=> $imported_url) : null,
];

```

UPDATE: Another try for datetime field:

```
'field_event_date_start' => array(
    "value" => array(
        "date" => date('Y-m-d',$imported_date),
        "time" => date('H:i:00',$imported_date)
    ),
),

```

Now I'm getting following error: Placeholders must have a trailing \[\] if they are to be expanded with an array of values.

# Answer
> 18 votes
Datetime fields in Drupal 8 are stored as strings. So you need to convert it into string.

You can use the format method, e.g.

```
$formatted_date = $date->format('Y-m-d H:i:s');

```

Refer Inserting the value from Datetime field form

You can also use T as separator,

Like:

`\DateTime::format("Y-m-d\TH:i:s"); //need a escape character in front of T.`

Refer Why is my Datetime field not saved?

# Answer
> 9 votes
If your date field is not a **DATETIME** but a **DATE**, use a different format. And a better solution would be to use the Datime object constant to get the format.

```
constant DATETIME_STORAGE_FORMAT :: string(12) "Y-m-d\TH:i:s"
constant DATE_STORAGE_FORMAT :: string(5) "Y-m-d"

```

Working example.

```
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;

$dtime = DateTime::createFromFormat("m/d/Y - G:i", $row->Date); // not needed
$dtime->setTimezone(new \DateTimezone(DateTimeItemInterface::STORAGE_TIMEZONE));
$dtimeFormat = $dtime->format(DateTimeItemInterface::DATE_STORAGE_FORMAT);

$article->set('field_date', $dtimeFormat);

```

# Answer
> 9 votes
Since Drupal 8.5.x this works a little differently.

Firstly it's good practice to set the **timezone** explicitly so you know what is going on:

Set the timezone:

```
$timezone = new \DateTimeZone('UTC');
// Or
$timezone = new \DateTimeZone(date_default_timezone_get());
// Or
$timezone = new \DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE);

```

Then create the date object using the PHP DateTime class:

```
$date_time = new \DateTime('now', $timezone);
$drupal_date_time = DrupalDateTime::createFromDateTime($date_time);

```

Or the DrupalDateTime class:

```
$drupal_date_time = new DrupalDateTime('yesterday', $timezone);

```

I like to use `DateTime` (or `DateTimeImmutable`) and then pass into the `DrupalDateTime` wrapper. That way native methods are highlighted in the IDE and also date comparisons (e.g. `$now > $somedatetime` work reliably.

Prior to saving the **date/time** you must set the timezone to `DateTimeItemInterface::STORAGE_TIMEZONE`:

```
$drupal_date_time->setTimezone(new \DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE))

```

You can then format the date for storage using the the DateTimeItemInterface::DATETIME\_STORAGE\_FORMAT constant:

```
$drupal_date_time->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT)

```

Here is an example usage:

```
$node = $this->entityTypeManager
    ->getStorage('node')
    ->create([
      'type' => 'article',
      'title' => 'test',
    ]);
// Get the default timezone
$default_timezone = new \DateTimeZone(date_default_timezone_get());
// Set some date/time objects
$now = new \DateTime('now', $default_timezone);
$yesterday = new \DateTime('yesterday', $default_timezone);

// Compare the dates
if($yesterday < $now){
  // Do some stuff
}

// Optionally convert to DrupalDateTime if you need the custom methods, etc
$now = DrupalDateTime::createFromDateTime($now);
$yesterday = DrupalDateTime::createFromDateTime($yesterday);

// Get the storage timezone
$storage_timezone = new \DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE);

// Save the dates to the fields
$node->set(
    'field_date_now',
    $now
      ->setTimezone($storage_timezone)
      ->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT)
);
$node->set(
    'field_date_yesterday',
    $yesterday
      ->setTimezone($storage_timezone)
      ->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT)
);

$node->save();

```

---

A bonus example — find nodes with a date/time field value that matches a 24hr window:

```
$date = new \DateTimeImmutable('now - 1 month', new \DateTimeZone(date_default_timezone_get()));

$start_time = $date->modify('midnight');
$start_time = DrupalDateTime::createFromDateTime($start_time);
$end_time = $date->modify('+1 day midnight -1 second');
$end_time = DrupalDateTime::createFromDateTime($end_time);

// Find all NODES with date times that match the 24hr window
$query = \Drupal::entityQuery('node')
  //      ->condition('status', 1)
  ->condition('type', 'event')
  ->condition(
    'field_date',
    $start_time
      ->setTimezone(new \DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE))
      ->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT),
    '>='
  )
  ->condition(
    'field_date',
    $end_time
      ->setTimezone(new \DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE))
      ->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT),
    '<='
  )

```

# Answer
> 5 votes
This is what worked for me:

```
$timestamp = \Drupal::time()->getRequestTime();
$date = DrupalDateTime::createFromTimestamp($timestamp, 'UTC');
$entity->field_date = $date->format("Y-m-d\TH:i:s");

```

# Answer
> 2 votes
This works great for date fields, as noted. However, if you need to update a timestamp based field use something like:

```
 $entityref->set('field_timestamp_field', $source_date->getTimestamp());

```

---
Tags: 8, nodes
---


title: Editable table column data

text:
# Question
Title: Editable table column data
In drupal 8, I am writing a custom module and in one of the function in controller -I am fetching data from an external API, then displaying it in table format using -

```
 foreach($rec as $data) {
    ksm($data);
    $rows[] = [// mydata
]};

return [
    '#type' => 'table',
    '#header' => $header,
    '#rows' => $rows,

  ];

```

This is working correctly.

But I want table cells to be editable and when user edits the data, a listener gets invoked (or provide an update button for the user). Now this listener would do some stuff with updated data(make external API call). My doubt is how can we do this with tables? Is there any way to make some columns of table editable and register a listener in Drupal.

Would I need to create a node for each row of this table data? If a node is required, then how to do ?

I am new to Drupal 8, just started a month ago, kindly help. Thanks in advance.

# Answer
What you can do is first create nodes using the API data and create a table view. so that the views fields can be referenced to nodes and they can be updated. By this way you wont be needing any additional event handlers.

To Create Nodes you can use the following snippet:

```
use \Drupal\node\Entity\Node;

$node = Node::create([

       'type' => 'new_content_type',

       'title' => 'Creating a new node',

       'body' => 'Body of the node',

       'field_mail'=>'email@gmail.com',

       'field_link'=>'http://www.example.com',

       'field_date'=>[ '2017-07-22', ],

]);
$node->enforceIsNew();
$node->save();

```
> 1 votes

---
Tags: views, nodes, hooks
---


# Question
Title: Set a datetime field configured as date-only
I'm developing a module where I have to set a user profile date\_field. I tried several methods to implement this but not one worked for me.

This is the code I am using.

```
private function updateUser($user_import,$uid = null) {
  if (!$uid) {
    return false;
  }

  $roles = $this->matchRoles($user_import->roles);
  $birthday = $this->birthdayDate($user_import->profile_geburtsdatum);
  $language = \Drupal::languageManager()->getCurrentLanguage()->getId();

  $user = \Drupal\user\Entity\User::load($uid);
  // $user->setPassword($this->randomPassword());
  $user->setEmail($user_import->mail);
  $user->setUsername($user_import->name);
  $user->enforceIsNew(false);

  // Optional settings
  $user->set("init", $user_import->init);
  $user->set("langcode", $language);
  $user->set("preferred_langcode", $language);
  $user->set("preferred_admin_langcode", $language);

  foreach ($roles as $role) {
    $user->addRole($role);
  }

  $user->set("field_profile_geburtsdatum", array('#default_value' => $birthday));
  $user->activate();
  $user->save();

  drupal_set_message("UPDATE: User " . $user_import->name . ' ( '. $user_import->mail . ')');
}

private function birthdayDate($import_date) {
  $date = null;
  if (!empty($import_date)) {
    $date = strtotime($import_date->day.'.'.$import_date->month.'.'.$import_date->year);
    $date = date('Y-m-d 00:00:00',$date);
    $date = new \Drupal\Core\Datetime\DrupalDateTime($date, 'Europe/Berlin');

    /* $date = array(
         'year' => date('Y',$date),
         'month' => date('m',$date),
         'day' => date('d',$date),
       );
     */
  }

  return $date;
}

```

# Answer
> 9 votes
Assuming `field_profile_geburtsdatum` is configured as a singular date-only datetime field, the following are all equivalent in the Field API (in order of my preferred usage):

```
$user->field_profile_geburtsdatum = '1999-12-31';
$user->field_profile_geburtsdatum->value = '1999-12-31';
$user->field_profile_geburtsdatum->set(0, '1999-12-31');
$user->set('field_profile_geburtsdatum', ['1999-12-31']);

```

The value you set should be a string in the `DATETIME_DATE_STORAGE_FORMAT`, which is `'Y-m-d'`, and not a DrupalDateTime object. That is used internally by the field type.

# Answer
> 3 votes
Since Drupal 8.5.x this works a little differently.

Firstly it's good practice to set the **timezone** explicitly so you know what is going on:

Set the timezone:

```
$timezone = new \DateTimeZone('UTC');
// Or
$timezone = new \DateTimeZone(date_default_timezone_get());
// Or
$timezone = new \DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE);

```

Then create the date object using the PHP DateTime class:

```
$date_time = new \DateTime('now', $timezone);
$drupal_date_time = DrupalDateTime::createFromDateTime($date_time);

```

Or the DrupalDateTime class:

```
$drupal_date_time = new DrupalDateTime('yesterday', $timezone);

```

I like to use `DateTime` (or `DateTimeImmutable`) and then pass into the `DrupalDateTime` wrapper. That way native methods are highlighted in the IDE and also date comparisons (e.g. `$now > $somedatetime` work reliably.

Prior to saving the **date/time** you must set the timezone to `DateTimeItemInterface::STORAGE_TIMEZONE`:

```
$drupal_date_time->setTimezone(new \DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE))

```

You can then format the date for storage using the the DateTimeItemInterface::DATETIME\_STORAGE\_FORMAT constant:

```
$drupal_date_time->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT)

```

Here is an example based on above use case:

```
$timezone = new \DateTimeZone('Europe/Berlin');

// geburtsdatum = 'date of birth' :-)
$birthday_import_object = $user_import->profile_geburtsdatum;

$day = $birthday_import_object->day;
$month = $birthday_import_object->month;
$year = $birthday_import_object->year;

$birthday = new \DateTime($day.' '.$month.' '.$year, $timezone);

// Optionally convert to DrupalDateTime if you need the custom methods, etc
$birthday = DrupalDateTime::createFromDateTime($birthday);

$user->set(
  'field_profile_geburtsdatum',
  $birthday
    ->setTimezone(new \DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE))
    ->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT)
);

```

# Answer
> 0 votes
```
$user->set('field_profile_geburtsdatum', [['value' => $birthday]]);

```

There are two issues with the call to `set` in the question.

1. A field requires to set an indexed array of values. This will call FieldItemBase::setValue().
2. Each array within the values array should be keyed by the properties of that field. In this case `value`, not `#default_value`.

It is understandably confusing because as of this time there is no clear documentation around setting field items in either the Entity API section of Develop for Drupal or on api.drupal.org.

---
Tags: 8, entities, datetime
---


title: Why is my Datetime field not saved?

text:
# Question
Title: Why is my Datetime field not saved?
I use the following code to create a node.

```
    $datetime = "2016-08-01 12:30:00";
    $values = array(
      'title' => $data['title'],
      'body' => $data['body'],
      'field_client' => $uid,
      'field_appointment_date_time' => $datetime,
      'type' => 'appointment'
   );

  $appointment = Node::create($values);
  $appointment->save();

```

The problem is that field\_appointment\_date\_time (a Datetime field) is not been saved.

Why does this happen?

# Answer
> 11 votes
The above code is correct, date time was saved into DB. the problem is frontend.

frontend expected this format:

```
"2016-08-01T12:30:00", need a "T" as separator.

```

here is how to put that T as separator,

```
\DateTime::format("Y-m-d\Th:i:s"), need a escape character in-front of T.

```

**2016-01-22 update:**

By the way, I have found out in Drupal 8 , correct way to store datetime is follow:

```
1> first , find out current user timezone, \Drupal::currentUser()->getTimezone()

2> $given = new \Drupal\Core\Datetime\DrupalDateTime("2016-08-01T12:30:00",$user->getTimezone());

3> $given->setTimezone(new \DateTimeZone("UTC"));

4> then get back formated datetime string $given->format("Y-m-d\Th:i:s");

```

# Answer
> 4 votes
I had the same problem, please try this

```
$dateTime = \DateTime::createFromFormat('Y-m-d','2000-01-30');
$newDateString = $dateTime->format('Y-m-d\TH:i:s');
$node = \Drupal\node\Entity\Node::create(array(
          'type' => 'article',
          'title' => 'The title',
          'langcode' => 'en',
          'uid' => 1,
          'status' => 1,
          'body' => array('The body text'),
          //'field_date' => array("2000-01-30"),
          'field_date' => $newDateString,
    ));
$node->save();

```

I've picked it from here:https://www.drupal8.ovh/en/tutoriels/64/create-a-node-date-field

I hope it helps you.

# Answer
> 0 votes
Since Drupal 8.5.x this works a little differently.

Firstly it's good practice to set the **timezone** explicitly so you know what is going on:

Set the timezone:

```
$timezone = new \DateTimeZone('UTC');
// Or
$timezone = new \DateTimeZone(date_default_timezone_get());
// Or
$timezone = new \DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE);

```

Then create the date object using the PHP DateTime class:

```
$date_time = new \DateTime('now', $timezone);
$drupal_date_time = DrupalDateTime::createFromDateTime($date_time);

```

Or the DrupalDateTime class:

```
$drupal_date_time = new DrupalDateTime('yesterday', $timezone);

```

I like to use `DateTime` (or `DateTimeImmutable`) and then pass into the `DrupalDateTime` wrapper. That way native methods are highlighted in the IDE and also date comparisons (e.g. `$now > $somedatetime` work reliably.

Prior to saving the **date/time** you must set the timezone to `DateTimeItemInterface::STORAGE_TIMEZONE`:

```
$drupal_date_time->setTimezone(new \DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE))

```

You can then format the date for storage using the the DateTimeItemInterface::DATETIME\_STORAGE\_FORMAT constant:

```
$drupal_date_time->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT)

```

Here is an example based on above use case:

```
$datetime_string = "2016-08-01 12:30:00";

// Get the default timezone
$timezone = new \DateTimeZone(date_default_timezone_get());
// Or set the timezone explicitly to match the $datetime_string
$timezone = new \DateTimeZone('Europe/London');

// Create the DateTime object
$datetime = new \DateTime($datetime_string, $timezone);

// Optionally convert to DrupalDateTime if you need the custom methods, etc
$datetime = DrupalDateTime::createFromDateTime($datetime);

// Create and save the node
$node = Node::create([
  'type' => 'appointment'
  'title' => $data['title'],
  'body' => $data['body'],
  'field_client' => $uid,
  'field_appointment_date_time' => $datetime
    ->setTimezone(new \DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE))
    ->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT),

]);

$node->save();

```

---
Tags: nodes, 8
---


# Question
Title: Pitfalls when updating a site without entering maintenance mode?
Assuming there are no module updates that require doing a database update, if it's just an update to a newer minor release of Drupal core, as well as of contrib and custom modules, what potential pitfalls should I watch out for when updating without entering maintenance mode?

We have 3 load-balanced web servers that all point to the same database and file server. The updates are generally done by first putting all the 3 Drupal instances into maintenance mode, waiting for a minute or two (not sure if this is necessary), then literally overwriting the entire application root directory with the newer version on each server, then clearing the caches on each of the servers, then exiting maintenance mode.

Is it safe to do this overwriting of the files while the site is live, without entering maintenance mode? I've heard of people doing this, but they have brochureware sites with not a lot of traffic and not a lot of logged-in user sessions (which we do have). Does doing so become more or less safe if you have multiple load-balanced web servers, use APC, use Varnish in front of the web servers, use nginx, use Memcache (which also stores sessions) between the web servers and the DB, have all pages using SSL, etc?

It would be great to seamlessly roll over to a new version without having to enter maintenance mode, but it feels risky to me. Are there edge cases where if your new files take a couple of minutes to overwrite the old files in the application root, then maybe some users are getting loading one module from the old set of files and one module from the newly-copied set of files, leading to strange and non-reproducible errors?

# Answer
> 1 votes
As you said there:

> but they have brochureware sites with not a lot of traffic and not a lot of logged-in user sessions (which we do have)

If accessibility is very important to your website I would suggest you do *NOT* take the risk to directly overwrite files for upgrading while the website is still up and serving. It may lead to corrupt data or broken response.

One approach could be take one web server out of the load-balance group, upgrade it while your website is still up and serving. After upgrade and test, put it back then upgrade another one, until all are done. In this way you can seamlessly upgrade without shutting down the service. It may sound complicated and boring, but it could be highly automated by writing some scripts I think.

# Answer
> 0 votes
It *is* risky and should generally not be attempted. Drupal code makes assumptions about the database structure and should generally not be run when the accompanying database updates have not been applied.

Currently, the best you can do is:

* Make sure your site uses a mechanism that symlinks the PHP code in the correct location.
* Copy over all code for the new release to a fresh location
* Enter the site into maintenance mode
* Switch over the symlink to the new code (this is much quicker than copying or even rsyncing over the new code); you are likely to need to restart your web server for it to pick up the new symlink
* Run database updates and hope they do not take a long time
* Disable maintenance mode

For lengthy update processes, you can check if they really need to run during maintenance mode. If you are e.g. just updating content and there is no great damage in running the site without the updates applied everywhere, you can consider stopping the actual update short (maybe patch the update hook to just return TRUE), and devising something to run the update script while the site is live. Of course, you will need to take greater care of the load this would cause and if it doesn't interfere with regular site operations. Unfortunately, Drupal does not contain such a mechanism.

When running something like Varnish, there are definitely ways to minimise the number of occasions where users actually *see* the maintenance page, e.g. have Varnish serve cached content when it finds the backend is not available. It would be rather out of scope here to go into that very deeply, though, I guess.

---
Tags: drush, updating, maintenance-mode
---


# Question
Title: Options set in dynamic multiple select field with ajax are not preserved
I am working on a dynamic set of three multiple select list which will function as one field which can be placed inside a form. The options in the second and third select lists will be set based upon the selection in the first and second selects.

Here is how I create the widget:

```
function multiselect_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
    $options_first = multiselect_first_dropdown_options();
    $value_dropdown_first = isset($form_state['values']['dropdown_first']) ? $form_state['values']['dropdown_first'] : key($options_first);

    $form['dropdown_first'] = array(
        '#type' => 'select',
        '#multiple' => TRUE,
        '#title' => 'First Dropdown',
        '#options' => $options_first,
        '#default_value' => $value_dropdown_first,
        '#ajax' => array(
            'event' => 'change',
            'callback' => 'multiselect_school_ajax_callback',
            'wrapper' => 'dropdown_second_replace',
        ),
    );
    $form['dropdown_second'] = array(
        '#type' => 'select',
        '#multiple' => TRUE,
        '#title' => 'Second Dropdown',
        '#prefix' => '<div id="dropdown_second_replace">',
        '#suffix' => '</div>',
        '#options' => multiselect_second_dropdown_options($value_dropdown_first),
        '#default_value' => isset($form_state['values']['dropdown_second']) ? $form_state['values']['dropdown_second'] : '',

        '#ajax' => array(
            'event' => 'change',
            'callback' => 'multiselect_class_ajax_callback',
            'wrapper' => 'dropdown_assignment_replace',
        ),
      );
      $form['dropdown_assignment'] = array(
        '#type' => 'select',
        '#multiple' => TRUE,
        '#title' => 'Second Dropdown',
        '#prefix' => '<div id="dropdown_assignment_replace">',
        '#suffix' => '</div>',
        '#options' => multiselect_second_dropdown_options($value_dropdown_first),
        '#default_value' => isset($form_state['values']['dropdown_second']) ? $form_state['values']['dropdown_second'] : '',
      );

  return $form;
}

```

And here is an example of one of my ajax callbacks:

```
function multiselect_school_ajax_callback($form, $form_state) {
      global $classes;
      $index = array_shift(array_values($form_state['values']['dropdown_first']));
      $selected_school = $form['dropdown_first']['#options'][$index];
      $class_array = multiselct_get_subgroups($selected_school, 'organization_group');
      $form['dropdown_second']['#options'] = $class_array;
      $classes = $class_array;
      return $form['dropdown_second'];
    }

```

When I set the options of the dropdown\_second in my ajax callback, it causes the widget to be re-rendered with the correct contents but when I examine the value stored in $form\['dropdown\_second'\]\['#options'\] from any other hook the values I set are not preserved. If I set $form\['dropdown\_second'\]\['#options'\] from hook\_form\_alter() the values are preserved but hook\_form\_alter is not called after my ajax call. Is there some way to make these changes stick around from my ajax callback or force a hook\_form\_alter?

# Answer
You can refer the following example for creating Dependent select list

```
function multiselect_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
    $options_first = multiselect_first_dropdown_options();
    $value_dropdown_first = isset($form_state['values']['dropdown_first']) ? $form_state['values']['dropdown_first'] : key($options_first);

    $form['dropdown_first'] = array(
        '#type' => 'select',
        '#multiple' => TRUE,
        '#title' => 'First Dropdown',
        '#options' => $options_first,
        '#default_value' => $value_dropdown_first,
        '#ajax' => array(
            'event' => 'change',
            'callback' => 'multiselect_school_ajax_callback',
            'wrapper' => 'dropdown_second_replace',
        ),
    );
    $form['wrapper'] = array(
        '#prefix'  => '<div id="dropdown_second_replace">',
        '#suffix'  => '</div>',
    );
    if(!empty($form_state['values']['dropdown_first'])){
        // Code here or call function for  fetching value second and third dropdown
    }
    $form ['wrapper']['dropdown_second'] = array(
        '#type' => 'select',
        '#multiple' => TRUE,
        '#title' => 'Second Dropdown',
        '#prefix' => '<div id="dropdown_second_replace">',
        '#suffix' => '</div>',
        '#options' => multiselect_second_dropdown_options($value_dropdown_first),
        '#default_value' => isset($form_state['values']['dropdown_second']) ? $form_state['values']['dropdown_second'] : '',

        '#ajax' => array(
            'event' => 'change',
            'callback' => 'multiselect_class_ajax_callback',
            'wrapper' => 'dropdown_assignment_replace',
        ),
    );
    $form['wrapper']['dropdown_assignment'] = array(
        '#type' => 'select',
        '#multiple' => TRUE,
        '#title' => 'Second Dropdown',
        '#prefix' => '<div id="dropdown_assignment_replace">',
        '#suffix' => '</div>',
        '#options' => multiselect_second_dropdown_options($value_dropdown_first),
        '#default_value' => isset($form_state['values']['dropdown_second']) ? $form_state['values']['dropdown_second'] : '',
    );
    return $form;
}

```

The basic idea about above example is that use wrapper as a div which will have your second and third dropdown so on change of first drop down form state will be set so it will go into if condition than that will give you the value for the secoond and third drop down
> 1 votes

# Answer
**For Drupal 8 it is not working**

```
$form['wrapper'] = array(
        '#attributes' => array('id' => array('districts-to-update')),
    );

$form['wrapper']['district'] = array(
'#type' => 'select',
'#title' => t('District'),
'#required' => TRUE,
'#options' => $district_opt_records,
'#attributes' => array('id' => array('districts-to-update')),
'#validated' => TRUE,
// '#default_value' => setInConfigandGEtVAlue,
'#ajax' => array('callback' => array($this, 'getMunicipality'), 'event' => 'change',
'method' => 'html',
'wrapper' => 'municipality-to-update',
'progress' => array(
'type' => 'throbber',
'message' => NULL,),),);

```

Kindly suggest me to solve the issue. Ajax calling first time it it working but second time while fetching Municipality list under district not able to get it. (not working Ajax call second time )
> 0 votes

---
Tags: forms, ajax
---


# Question
Title: Forena Reports, does not appear in the Drupal menu Structure
I installed the downloaded the 8.x-1.x-dev version of the Forena module, and it installs correctly. When I go to the menu Structure to start creating the report, the *Forena Reports* link doesn't appear.

How can I solve this problem?

I also have the Forena UI sub-module enabled, but Forena's Release Notes include this:

> Basic rendering of reports and document types are complete, however the GUI version of the report writer has not yet been ported. Sufficed to say, this version can be used by Drupal 8 report writers who are comfortable writing .frx files and sql elements by hand.

# Answer
> 0 votes
This is, pretty sure, a permission issue. So go check if the user has the relevant permissions granted. If not that's why the link is not shown either.

Some more debugging hints:

* just enter relative URL `/reports` and see what happens next (it may be available, even though the menu item is still missing for some reason).
* temporary logon with `user/1` (to bypass any potential permission issues).

BTW, the GUI version of the Forena report writer is just a user interface to facilitate the design (construction) of Forena report specifications (saved in so called *FRX* files). So for sure that is not related in any way to your missing menu item, which if shown lists the available reports that you can execute, e.g. the sample reports.

Documentation and examples are included in the module you installed / enabled. For an illustration of that, still D7, refer to this online demo, which also includes:

Disclosure: I'm a co-maintainer of (the D7 version of) this module.

---
Tags: 8, forena
---


# Question
Title: How to pass pagination value to drupal view programatically?
I have a view with contextual filter and I render the view through program as below

```
$args=[$id];
$view = Views::getView('schedule');
$render_array = $view->buildRenderable('rest_export_1',$args);
$rendered = \Drupal::service('renderer')->renderRoot($render_array);

```

The view is paged with 5 results in each page. How do I pass the value to get results from the second page of the view?

# Answer
> 1 votes
I found setCurrentPage more suitable for my use case

```
$view = Views::getView('schedule');
$view->setCurrentPage($pageNum);

```

---
Tags: 8, views
---


# Question
Title: Implement variable in node confirmation popup
I want to add a confirmation popup for node form. The message should be changed dynamically.

The code below worked fine in form\_alter.

```
$form['actions']['submit']['#attributes']['onclick'] = 'if(!confirm("Really Save?")){return false;}';

```

But the popup didn't show up if I include a variable in the code like this:

```
$text = "Really save?";
$form['actions']['submit']['#attributes']['onclick'] = 'if(!confirm({$text})){return false;}';

```

Is there any way to change the text dynamically?

# Answer
> 1 votes
It works!

```
$text = "Really save?";
$form['actions']['submit']['#attributes']['onclick'] = 'if(!confirm("' . $text .'")){return false;}';

```

---
Tags: 8
---


# Question
Title: The "dictionary_term" entity type does not exist. in Drupal\Core\Entity\EntityTypeManager->getDefinition()
I followed How to create a custom entity in Drupal 8 to create a module. When I installed it, I got the following error.

> Drupal\Component\Plugin\Exception\PluginNotFoundException: The "dictionary\_term" entity type does not exist. in Drupal\Core\Entity\EntityTypeManager-\>getDefinition() (line 150 of /var/www/html/core/lib/Drupal/Core/Entity/EntityTypeManager.php).

What do I need to change in the following code?

### dictionary/Entity/Term.php

```
/**
 * @file
 * Contains \Drupal\content_entity_example\Entity\ContentEntityExample.
 */

namespace Drupal\dictionary\Entity;

use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\user\UserInterface;
use Drupal\Core\Entity\EntityChangedTrait;

/**
 * Defines the ContentEntityExample entity.
 *
 * @ingroup dictionary
 *
 *
 * @ContentEntityType(
 * id = "dictionary_term",
 * label = @Translation("Dictionary Term entity"),
 * handlers = {
 * "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
 * "list_builder" = "Drupal\dictionary\Entity\Controller\TermListBuilder",
 * "form" = {
 * "add" = "Drupal\dictionary\Form\TermForm",
 * "edit" = "Drupal\dictionary\Form\TermForm",
 * "delete" = "Drupal\dictionary\Form\TermDeleteForm",
 * },
 * "access" = "Drupal\dictionary\TermAccessControlHandler",
 * },
 * list_cache_contexts = { "user" },
 * base_table = "dictionary_term",
 * admin_permission = "administer dictionary_term entity",
 * entity_keys = {
 * "id" = "id",
 * "uuid" = "uuid",
 * "user_id" = "user_id",
 * "created" = "created",
 * "changed" = "changed",
 * "pl" = "pl",
 * "en" = "en",
 * },
 * links = {
 * "canonical" = "/dictionary_term/{dictionary_term}",
 * "edit-form" = "/dictionary_term/{dictionary_term}/edit",
 * "delete-form" = "/dictionary_term/{dictionary_term}/delete",
 * "collection" = "/dictionary_term/list"
 * },
 * field_ui_base_route = "entity.dictionary.term_settings",
 * )
 */
class Term extends ContentEntityBase {

  use EntityChangedTrait;

  /**
   * {@inheritdoc}
   *
   * When a new entity instance is added, set the user_id entity reference to
   * the current user as the creator of the instance.
   */
  public static function preCreate(EntityStorageInterface $storage_controller, array &$values) {
    parent::preCreate($storage_controller, $values);
// Default author to current user.
    $values += array(
      'user_id' => \Drupal::currentUser()->id(),
    );
  }

  /**
   * {@inheritdoc}
   *
   * Define the field properties here.
   *
   * Field name, type and size determine the table structure.
   *
   * In addition, we can define how the field and its content can be manipulated
   * in the GUI. The behaviour of the widgets used can be determined here.
   */
  public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {

// Standard field, used as unique if primary index.
    $fields['id'] = BaseFieldDefinition::create('integer')
      ->setLabel(t('ID'))
      ->setDescription(t('The ID of the Term entity.'))
      ->setReadOnly(TRUE);

// Standard field, unique outside of the scope of the current project.
    $fields['uuid'] = BaseFieldDefinition::create('uuid')
      ->setLabel(t('UUID'))
      ->setDescription(t('The UUID of the Contact entity.'))
      ->setReadOnly(TRUE);

// Name field for the contact.
// We set display options for the view as well as the form.
// Users with correct privileges can change the view and edit configuration.
    $fields['pl'] = BaseFieldDefinition::create('string')
      ->setLabel(t('Polish'))
      ->setDescription(t('Polish version.'))
      ->setSettings(array(
        'default_value' => '',
        'max_length' => 255,
        'text_processing' => 0,
      ))
      ->setDisplayOptions('view', array(
        'label' => 'above',
        'type' => 'string',
        'weight' => -6,
      ))
      ->setDisplayOptions('form', array(
        'type' => 'string_textfield',
        'weight' => -6,
      ))
      ->setDisplayConfigurable('form', TRUE)
      ->setDisplayConfigurable('view', TRUE);

    $fields['en'] = BaseFieldDefinition::create('string')
      ->setLabel(t('English'))
      ->setDescription(t('English version.'))
      ->setSettings(array(
        'default_value' => '',
        'max_length' => 255,
        'text_processing' => 0,
      ))
      ->setDisplayOptions('view', array(
        'label' => 'above',
        'type' => 'string',
        'weight' => -4,
      ))
      ->setDisplayOptions('form', array(
        'type' => 'string_textfield',
        'weight' => -4,
      ))
      ->setDisplayConfigurable('form', TRUE)
      ->setDisplayConfigurable('view', TRUE);

// Owner field of the contact.
// Entity reference field, holds the reference to the user object.
// The view shows the user name field of the user.
// The form presents a auto complete field for the user name.
    $fields['user_id'] = BaseFieldDefinition::create('entity_reference')
      ->setLabel(t('User Name'))
      ->setDescription(t('The Name of the associated user.'))
      ->setSetting('target_type', 'user')
      ->setSetting('handler', 'default')
      ->setDisplayOptions('view', array(
        'label' => 'above',
        'type' => 'author',
        'weight' => -3,
      ))
      ->setDisplayOptions('form', array(
        'type' => 'entity_reference_autocomplete',
        'settings' => array(
          'match_operator' => 'CONTAINS',
          'size' => 60,
          'placeholder' => '',
        ),
        'weight' => -3,
      ))
      ->setDisplayConfigurable('form', TRUE)
      ->setDisplayConfigurable('view', TRUE);

    $fields['created'] = BaseFieldDefinition::create('created')
      ->setLabel(t('Created'))
      ->setDescription(t('The time that the entity was created.'));

    $fields['changed'] = BaseFieldDefinition::create('changed')
      ->setLabel(t('Changed'))
      ->setDescription(t('The time that the entity was last edited.'));

    return $fields;
  }

}

```

# Answer
Drupal doesn't find the entity class because the file containing its implementation has been put in the wrong directory. If *dictionary* is the directory containing the module, the *Term.php* file for that entity must be in *dictionary/src/Entity/Term.php*, not *dictionary/Entity/Term.php*. That is what PSR-4 namespaces require, in Drupal 8, as described in PSR-4 namespaces and autoloading in Drupal 8.

> 1. Each module has a namespace that corresponds to its module name.
> Here: `Drupal\vegetable\`
> 2. The module's namespace is mapped to the ./src/ folder in the module directory. Here: `Drupal\vegetable\``modules/vegetable/src/`

Note that the example in that page **doesn't** mean you have to create a *modules* directory inside the directory containing the module. It just shows the parent directory of the directory containing the module (which in the example is *vegetable*). It doesn't even mean the parent directory of the directory containing the module must necessarily be *modules*.

To have a confirm of the correct directory, it's sufficient to see where Drupal core places the files for its entity classes.

Leaving out *core/modules*, which is where all Drupal core modules are places, it's clear that, for example, the file containing the `Node` class is placed in the *src/Entity* directory inside the directory containing the *node.module* file.
> 0 votes

---
Tags: 8, entities
---


title: Confused about Entity bundles

text:
# Question
Title: Confused about Entity bundles
I'm trying to convert a Drupal 7 site to Drupal 9 before D7 reaches EOL, and I had a custom module that had a lot of custom tables defined in Hook Schema, that would be joined together in different ways to handle a multi-step form made with the ctools form wizard. This site was originally created in Drupal 6, and updated to Drupal 7 while doing the minimum changes to the custom modules, so it predates the concept of Entities. The database structure of those tables is normalized, in 3rd normal form, because if you flattened it, would your end with millions of rows with mostly redundant information. The problem was that those tables existed in their own microcosm, not accessible to the rest of the site.

I've decided to rebuild everything from the ground up when doing the site upgrade, and I've also decided to drupalize this so the contents of these tables can be accessed by regular views, avoiding content duplication. This means that every old table will have to have it's own entity type. Fields will be basefields for performance, since I will need 50-100 fields in total, and every fiend added through the UI requires a join as far as I understand. If I need to add fields in the future, I will do it through a module update, not by adding them through the UI, so I don't need the entities to be fieldable.

After giving you this context, my actual question is, if I will only ever need 1 type of every entity bundle, do I really need entity bundles? What would entity bundles do for me?

# Answer
> 0 votes
> After giving you this context, my actual question is, if I will only ever need 1 type of every entity bundle, do I really need entity bundles? What would entity bundles do for me?

No, you don't need bundles. Configurable fields are stored in bundles. Since you don't want to configure fields you don't need bundles.

> I still wonder, if I will have only one bundle per entity type, do I need to set up a configuration entity for the the bundle?

The core user entity is an example for a bundleless entity type for which you can configure bundle fields. It looks like having one bundle but there is no bundle config entity. The bundle fields use the entity type id as placeholder.

So even if you later need to add configurable fields, through UI or YAML, you don't need to set up a configuration entity for the bundle. See Adding Field To Bundle-less Entity On Installation Not Working

---
Tags: entities
---


title: Adding a suffix to a form element

text:
# Question
Title: Adding a suffix to a form element
I have a form which has an input field for which i want to add a suffix.

```
function myapp_preprocess_form_element(&$variables) {
  if ($variables["element"]["#attributes"]["id"] == 'edit-keys') {
    $variables['#suffix'] = '<div>Some text</div>';
  }
}

```

I've looked into the `form-element.html.twig` file and it does have a `suffix` varaible, but it's not rendering.

Any ideas?

# Answer
```
/**
 * Implements hook_form_FORM_ID_alter() for login.
 */
function MYTHEME_form_user_login_form_alter(&$form, &$form_state) {
  $form['register_user']['#prefix'] = "<div class=\"form-footer\"> <span>" . t("Don't have an account?") . "</span>";
  $form['register_user']['#suffix'] = "</div>";
}

```

This is how I've added a wrapper to a form element using prefix and suffix. Hope it helps.
> 0 votes

---
Tags: forms
---


title: Form Redirect before submit?

text:
# Question
Title: Form Redirect before submit?
I have a form which has 2 values prefilled (values come from a few steps the user has to take to be given the chance to get to the form I'm talking about).

My question is, how do I redirect the user back to step 1 when the form loads if the values are not present?

I have a `hook_form_alter()` and I have the logic to check whether or not the session variables are set but I cannot seem to redirect. Tried `return new RedirectResponse($url)` and `return new TrustedRedirectResponse($url)` also I've checked with the debugger to see if the returns are called and they are but the redirect is not happening and I get to the form when I should not be able to.

If it helps, it is a `group/add` form (normal entity adding).

Any ideas?

# Answer
> 1 votes
I'd use an Event Subscriber here. See My First Event Subscriber for an example if you're unfamiliar.

In this case, you'd want to subscribe to the `Symfony\Component\HttpKernel\KernelEvents::REQUEST` event. For example, you might have a *getSubstribedEvents()* method that looks like:

```
public static function getSubscribedEvents() {
  // Include Symfony\Component\HttpKernel\KernelEvents with a use statement.
  return [
    KernelEvents::REQUEST => 'myCustomMethod',
  ];
}

```

Then define *myCustomMethod()* to check for your session variables and redirect if needed. For example:

```
public function MyCustomMethod(GetResponseEvent $event) {
  $route_name = $event->getRequest()->attributes->get('_route');
  // I'm not sure what the route name is here. (You also don't need
  // to check against a route name, thought it's probably a good idea.)
  if ($route_name == 'GROUP_ADD_ROUTE') {
    // Check whatever to see if you must redirect.
    if (myRedirectCondition()) {
      // Set these response headers so browsers don't cache the redirect.
      $response_headers = [
        'Cache-Control' => 'no-cache, no-store, must-revalidate',
      ];

      // Build your response.
      $response = new TrustedRedirectResponse(MY_REDIRECT_URL, '302', $response_headers);
      // You'll have to determine how your redirect should be cached and add
      // appropriate cache dependencies, tags, contexts, etc. There is a
      // session cache context, but I'm not familiar with that particulars of
      // exactly how it works. Alternatively, you could use \Drupal::service('page_cache_kill_switch')->trigger();
      // inside your route_name if statement.
      $response->addCacheableDependency();
      $event->setResponse($response);
    }
  }
}

```

Related: Disabling Page Cache for Redirect Response

---
Tags: forms
---


# Question
Title: Tokens missing in Webform Emails after upgrading
Currently running Drupal 7.69 / PHP 7.3 (+ CiviCRM)

I have recently updated some Modules : Webform, Views Bulk Operations, i18n, and Content Access. Since then, my Webform Emails do not show the pertaining tokens (but they just show the token titles) :

All those tokens are not populated : \[submission:completed\_date:long\], \[submission:user\], \[submission:values\], \[submission:url\]

Any help is welcome

# Answer
I could solve the problem, but an issue still remains.

I have disabled Token and Entity Tokens Modules (and requested associated Modules)

... then reactivated :

The probem comes from the Advanced User Management Module : when it is enabled, most of the tokens cannot be browsed (among which the default proposed ones in the mail content).

... So, I cannot use this Module any more.
> 0 votes

---
Tags: views, webforms, i18n-l10n, tokens
---


# Question
Title: Unable to add patches via composer when we run "composer install" or "composer update"
I am facing an issue wherein I have added a single patch in my composer.json under "extras"

```
   "patches": {
            "drupal/field_validation": {
                "Declaration of (...)FieldValidationRuleAddForm::buildForm": "https://www.drupal.org/files/issues/2941006-php-incompatible-buildform-signature.patch"
            },
            "drupal/ubercart": {
                "Not_yet_ported (missing)": "https://www.drupal.org/files/issues/2020-05-28/ubercart_remove_not_yet_ported.patch"
            }
        },
        "enable-patching": true

```

After adding the patch under composer.json I ran

```
composer install

```

but still it does not apply the patches listed.

# Answer
The solution was

```
composer require cweagans/composer-patches

```

we need to be sure that above package is included

After adding the above I was able to add patches via composer.json
> 1 votes

---
Tags: 8, composer
---


# Question
Title: How to insert form into existing page template
Working in D8, I am trying to insert a form into an already created page/template file.

I am using webforms, and on the webform submission page (that lists the submission details), I am trying to insert a custom form to do some additional stuff. I already have the form generated, but I cannot find the correct way to insert the form into the template/page.

I tried using `\Drupal::formBuilder()->getForm(form_name)` in the twig template where I wanted it, but Drupal didn't like that.

I then tried to use `hook_page_bottom` and `hook_page_top`, but that quite literally attaches it to the very top of the page, or very bottom of the page (outside of the bounds of the theme/template), not where I want it to be.

I am already overriding the template using the naming convention **webform-submission--webform-machine-name.html.twig**.

I am assuming since you can override the default templates for webform submissions, that the webform module implements `hook_theme` or some other similar hook. Is there a way I can hook into this hook and pass the form off as a variable, then just render it in the actual template using `{{ form }}`, or do I need to create my own override and pass both the submission data and the form data into it?

I miss the days when I could just use `$form = drupal_get_form();` and print `render($form);` inside of the template exactly where I wanted it.

# Answer
> 0 votes
I was able to resolve this myself using `template_preprocess()` and generating the form from there

---
Tags: 8, theming
---


# Question
Title: My site only listens to the event after I clear all caches
I have a module with an event subscribe that I use to redirect to an age verification page if a cookie is not set, and as long as the current request is not the age verification uri.

```
if(!isset($_COOKIE['age_gate_ok']) && $request != '/age-verification')
{
    $welcome = new\Symfony\Component\HttpFoundation\RedirectResponse("/age-verification");
    $welcome->send();
}

```

Problem: the event seems to listen once only, and that is when I use drush to clear cache. To further explain, I use clear site cache using drush and when I reload the page, it redirects me to the correct page(/age-verification) and then I pass the gate. However, if I open the inspector to clear cookies and refresh the page, the site does not redirect me to the age verification url.

How do I have to clear cache in order to have the age verification working?

# Answer
> 4 votes
You need to use a Trusted Redirect Response and properly set cache metadata for your response. This is mostly documented in an answer to a related question, Disabling Page Cache for Redirect Response. However, in your case, you'll need to manually build a CacheableMetadata object, so I'll show that here.

```
// Tell the browser not to cache the redirect by setting these headers.
$response_headers = [
  'Cache-Control' => 'no-cache, no-store, must-revalidate',
];

$response = new TrustedRedirectResponse($url, '302', $response_headers);
// We need to add cache metadata to the response so it can be properly cached by
// Drupal. If redirecting was based on a $node or entity, you could simply call
// $response->addCacheableDependency($node) and addCacheableDependency() would
// automagically pull the correct cache tags, contexts, etc from the object.
// Since your redirect depends on a cookie, you'll have to build a
// \Drupal\Core\Cache\CacheableMetadata object manually.
$cache_metadata = new CacheableMetadata();
// Since you just want to cache the response based on whether they have a cookie
// you can use just the cookies:NAME cache context.
$cache_metadata->setCacheContexts(['cookies:age_gate_ok']);
// Add the metadata to your response.
$response->addCacheableDependency($cache_metadata);

$event->setResponse($response);

```

---
Tags: event-subscribers
---


# Question
Title: In my Simplenews twig template how do I get the URL of the page I am emailing?
When a single test newsletter is sent, Drupal provides me with the expected URL as follows:

```
{% set foo = url('<current>') %}
<p class="link-to-page">
<a href="{{ foo|render|replace({'simplenews':  ""}) }}">{{ 'You can view this news article in your web browser' }}</a>
</p>

```

Or by using the `trim` Twig function

But when sending the actual newsletter issue to subscribers, the batch process causes the `url(‘current’)` to provide a batch url like `https://my-site.uk/batch`

How can I obtain the one I want (to direct newsletter recipients to the page). Will a preprocess theme function see the same `url` values as twig or can I reliably capture the node’s real URL there Somehow?

# Answer
This is better!

```
<p class="link-to-page">
  <a href=" {{ url('entity.node.canonical', {'node': node.id}) }}">
      You can view this news article in your web browser
  </a>
</p>

```
> 1 votes

---
Tags: theming
---