Problem/Motivation

Expose a list of checkboxes for each type. Ticking the checkbox should expose that base field for the selected entity types. In case a base field already exists and is not defined by us (e.g. node), it should be checked by default and be disabled. This in turn will then automatically expose a alias type plugin. At this point, we'll have achieved the goal of fully generic and automated integration with any entity type.

Proposed resolution

Add a setting, allow to enable it for every fieldable entity type, with it being enabled by default for user

Remaining tasks

* Tests
* Update function for default config?

User interface changes

API changes

Data model changes

Comments

Berdir created an issue. See original summary.

berdir’s picture

Status: Active » Needs review
StatusFileSize
new6.03 KB
berdir’s picture

Forgot about default config and schema. This passes for me.

The last submitted patch, 2: pathauto-field-configurable-2655780-2.patch, failed testing.

The last submitted patch, 2: pathauto-field-configurable-2655780-2.patch, failed testing.

berdir’s picture

Issue tags: +Needs tests
dave reid’s picture

Issue tags: +Needs screenshots
berdir’s picture

Status: Needs review » Needs work
Issue tags: -Needs screenshots
StatusFileSize
new17.67 KB

There's not much to see, just a bunch of checkboxes.

See also the referenced file_entity issue about what it means for a module that integrates with pathauto.

@todo:
* move the cache clears into a config save event listener, so it also works for config deployments and the file_entity patch can then be simplified too.
* Write a test just like the one in file_entity, with an entity_test entity.

dave reid’s picture

Title: Allow to configure path field » Allow to configure entity types to add path base fields (so that Pathauto can apply for them)
dave reid’s picture

So maybe an alternate opinion, what if, the user went to create a new pattern for the user entity type, and creating that pattern would double check that the base field exists, and created it if needed. This would minimize the need for anyone to actually use/change this setting.

berdir’s picture

It would, but then you'd get lots of options on the add pattern form that really don't make sense, like shortcut and menu links. But yes, now you get those options on the settings page.

We'd have to change for what we expose plugins, currently that only happens for entity types that have a path field.

It would make the code to check for which entity types the field should be added more complicated, same for the code that needs to detect a cache and clear caches. A bit worried about adding more dynamics and complexity there, but we can try that if you'd prefer that.

rachel_norfolk’s picture

What *should* this patch apply against? I’m trying with a git checkout from git clone --branch 8.x-1.x https://git.drupal.org/project/pathauto.git but no good.
I just want to check before re-rolling etc.
Would be *really* good to help progress pathauto against arbitrary entity type (e.g. group)

rachel_norfolk’s picture

StatusFileSize
new6.55 KB
new6.55 KB

Okay, I’ve done a little rerolling and got the attached. I think things have moved around a little since this patch applied cleanly in its original form. It does need a check to see the logic is still correct, based on the latest changes.

rachel_norfolk’s picture

Sorry - why was I thinking I made an Interdiff - I didn’t from this reroll!

rachel_norfolk’s picture

Status: Needs work » Needs review
alexdmccabe’s picture

Status: Needs review » Needs work

I found an issue while testing this. If you enable an entity type, create a pattern for it, disable that same entity type, and revisit /admin/config/search/path/patterns, you get an error that persists unless you re-enable the entity type. I tested this behavior with both the user and comment entities, so I imagine it persists across all entities.

Drupal\Component\Plugin\Exception\PluginNotFoundException: The "canonical_entities:user" plugin does not exist. in Drupal\Core\Plugin\DefaultPluginManager->doGetDefinition() (line 52 of core/lib/Drupal/Component/Plugin/Discovery/DiscoveryTrait.php).

Additionally, there were some coding standards issues with the changes being made:

src/Form/PathautoSettingsForm.php

 37 | ERROR | [ ] Missing short description in doc comment
 42 | ERROR | [ ] Missing short description in doc comment
 47 | ERROR | [ ] Missing short description in doc comment
 52 | ERROR | [ ] Missing short description in doc comment
 62 | ERROR | [ ] Missing short description in doc comment

@var blocks need a short description, and it's required to include the curly brackets when using {@inheritdoc}.

Check out https://www.drupal.org/node/1354#var and https://www.drupal.org/node/1354#inheritdoc for more on those two issues.

Bambell’s picture

Status: Needs work » Needs review
StatusFileSize
new8.56 KB
new4.22 KB

Fixed this bug by implementing FallbackPluginManagerInterface on AliasTypeManager and disabling checkboxes of entity types that currently have pattern(s) defined.

Status: Needs review » Needs work

The last submitted patch, 17: allow_to_configure-2655780-17.patch, failed testing.

The last submitted patch, 17: allow_to_configure-2655780-17.patch, failed testing.

berdir’s picture

+++ b/src/Plugin/pathauto/AliasType/Broken.php
@@ -0,0 +1,23 @@
+    return $this->t('This block is broken or missing. You may be missing content or you might need to enable the original module.');

close, but it's not a block :)

Just return $this->t('Broken type').

+++ b/src/Form/PathautoSettingsForm.php
@@ -19,6 +25,53 @@ use Drupal\Core\Form\FormStateInterface;
   /**
+   * Case should be left as is in the generated path.
+   */
+  const CASE_LEAVE_ASIS = 0;
+
+  /**
+   * Case should be lowercased in the generated path.
+   */
+  const CASE_LOWER = 1;

not sure what this is, I think a copy & paste mistake from me. remove it.

Now we need tests for ($type = pick one that is not enabled by default. you might need to enable a module, e.g. block_content, comment, ..):

1. Ensure that $type is not available as an type when adding a pattern.
2. Ensure that Broken is not available there.
3. Enable the type.
4. Now create a pattern with that type.
5. Create an entity of that type, ensure the alias is generated.
6. Make sure the type can not be disabled now.
7. Delete $type from the setting through the API., call clearCachedDefinitions() on plugin manager.
8. visit the overview page, must not be broken, check for the broken type string.
9. Make sure that you can delete the pattern.
10. Enable $type again, disable it again while there is no pattern.

Bambell’s picture

StatusFileSize
new4.18 KB
new11.33 KB

Tried implementing a test, but not having much luck with assertEntityAliasExists. Apparently the comment isn't properly created (or the article). Not exactly sure why. Here's the patch for now.

Bambell’s picture

Status: Needs work » Needs review
StatusFileSize
new11.84 KB
new3.62 KB

Failing tests and #16 bug should be fixed.

Status: Needs review » Needs work

The last submitted patch, 22: allow_to_configure-2655780-22.patch, failed testing.

The last submitted patch, 22: allow_to_configure-2655780-22.patch, failed testing.

Bambell’s picture

Status: Needs work » Needs review
StatusFileSize
new13.65 KB
new1.81 KB

Added a check not to try to display "Broken" as an entity type on the aliases deletion form.

kgaut’s picture

StatusFileSize
new10.03 KB

Great patch, it's what I'm looking for.

My two cents :

By using the patch #25, I get "Broken type" for my already defined pattern for User entity type.

Broken type for user entity type

Also In the settings area I'm not seeing all my custom entity types listed, what makes one listed ?

Bambell’s picture

By using the patch #25, I get "Broken type" for my already defined pattern for User entity type.

You're going to see "Broken type" on the patterns list page if you have a pattern for an entity type that is disabled. The settings page has been modified to prevent users form disabling an entity type that already has patterns defined for it, so normally this shouldn't be seen.

kgaut’s picture

I didn't disable User entity type ;).

What I've done :

  1. Pathauto install
  2. set pattern for user, as for other entity type like nodes...
  3. Patch the module with #25
  4. see User as broken type

Let me know if I can help

berdir’s picture

Yes because user is now configurable and you have to enable it. Just go to the settings page and do that. We could add an update function to automatically make user selected by default.

The settings page shows content entity types with a canonical link template, only those are supported at the moment.

kgaut’s picture

Thanks Berdir,

The patch #25 is working great ! Thanks.

berdir’s picture

Status: Needs review » Needs work
  1. +++ b/config/install/pathauto.settings.yml
    @@ -1,3 +1,5 @@
    +entity_types:
    +  user: true
    

    Lets add an update function that ensures that this is also set for existing sites to avoid the confusing broken type message when they update.

    You just have to get the editable config, set user as enabled and then save.

  2. +++ b/config/schema/pathauto.schema.yml
    @@ -1,6 +1,11 @@
       type: config_object
       mapping:
    +    entity_types:
    +      label: Enabled entity types
    +      type: sequence
    +      sequence:
    +        type: boolean
    

    Lets make the key a bit more self-explaining and name it enabled_entity_types.

    I'm also wondering if we should simplify the structure to a list of entity types instead of using them as key with a dummy boolean value. The default config would then look like this:

    enabled_entity_types:
    - user

  3. +++ b/pathauto.module
    @@ -143,9 +143,8 @@ function pathauto_field_widget_info_alter(&$widgets) {
    -  if ($entity_type->id() === 'user') {
    +  $config = \Drupal::config('pathauto.settings');
    +  if ($config->get('entity_types.' . $entity_type->id())) {
    

    it would mean that this would get a bit more complicated as we'd need an in_array() check.

  4. +++ b/src/Form/PathautoAdminDelete.php
    @@ -73,15 +73,18 @@ class PathautoAdminDelete extends FormBase {
    +      if ($id !== 'broken') {
    +        // Broken shouldn't show on the aliases list.
    

    what about the bulk update form, doesn't that need the same?

    I would recommend that we hadd a getVisibleDefinitions() method to the alias type manager and use that, then you don't have to change anything here.

    Could also be a getVisibleOptions() and just return key => label.

Bambell’s picture

Status: Needs work » Needs review
StatusFileSize
new14.28 KB
new4.22 KB

Here's a quick work in progress patch. Tests will fail.

Lets add an update function that ensures that this is also set for existing site [...]

Are you sure it's as simple as this? I would have thought that the update function should enable each entity type that already has a pattern defined.

Bambell’s picture

Bambell’s picture

Status: Needs review » Needs work
Bambell’s picture

Status: Needs work » Needs review
StatusFileSize
new15.01 KB
new10.64 KB

All changes recommended in #31 have been done. It tests fine locally. I'm posting an interdiff with #25 only, #32 should be ignored.

berdir’s picture

Status: Needs review » Needs work
Issue tags: -Needs tests

Almost there I think.

  1. +++ b/src/AliasTypeManager.php
    @@ -60,4 +60,21 @@ class AliasTypeManager extends DefaultPluginManager implements FallbackPluginMan
    +   * @return mixed[]
    +   *   An array of plugin definitions (empty array if no definitions were
    +   *   found). Keys are plugin IDs.
    

    we always return an array, so the type is just array. I think this is mixed in getDefinitions() because that can also return objects for some plugin types.

  2. +++ b/src/AliasTypeManager.php
    @@ -60,4 +60,21 @@ class AliasTypeManager extends DefaultPluginManager implements FallbackPluginMan
    +  public function getVisibleDefinitions() {
    +    $definitions = $this->getCachedDefinitions();
    +    if (!isset($definitions)) {
    +      $definitions = $this->findDefinitions();
    +      $this->setCachedDefinitions($definitions);
    +    }
    +    unset($definitions['broken']);
    +    return $definitions;
    

    No need to repeat the implementation of getDefinitions() here. Just call $definitions = $this->getDefinitions()

  3. +++ b/src/Form/PathautoAdminDelete.php
    @@ -69,22 +69,19 @@ class PathautoAdminDelete extends FormBase {
    +    // Next, iterate over all visible alias types
    +    $definitions = $this->aliasTypeManager->getVisibleDefinitions();
    

    Missing . at the end of the comment.

  4. +++ b/src/Form/PathautoSettingsForm.php
    @@ -246,21 +246,23 @@ class PathautoSettingsForm extends ConfigFormBase {
             foreach ($value as $entity_type_id => $enabled) {
    -          if (!$enabled || !empty($form['entity_types'][$entity_type_id]['#disabled'])) {
    -            unset($value[$entity_type_id]);
    +          if ($enabled) {
    +            $enabled_entity_types[] = $entity_type_id;
               }
             }
    

    This means we will now store node in the list, even though that is not actually a type that can be enabled or disabled.

    There used to be only one disabled condition (not defined by us), now there are two. This means instead of just removing this check, you need to instead do the same check as in the disabled check about, with the provider.

    Make sure you test this, by making sure that node is not saved in the config when submitting this form.

Bambell’s picture

Status: Needs work » Needs review
StatusFileSize
new15.03 KB
new2.12 KB

I addressed points 1. to 4., manually verified that node doesn't get saved in the config.

we always return an array, so the type is just array. I think this is mixed in getDefinitions() because that can also return objects for some plugin types.

Not sure which of @return array or @return string[] is better. Both seem widely used and appropriate here. I used @return array.

Status: Needs review » Needs work

The last submitted patch, 37: allow_to_configure-2655780-37.patch, failed testing.

The last submitted patch, 37: allow_to_configure-2655780-37.patch, failed testing.

Bambell’s picture

Status: Needs work » Needs review
StatusFileSize
new15.07 KB
new760 bytes

Fixing failing test.

berdir’s picture

Status: Needs review » Needs work

One last thing:

Add a comment about that fairly complex condition and explain why we're doing it like that.

Bambell’s picture

Status: Needs work » Needs review
StatusFileSize
new15.3 KB
new899 bytes

Add a comment about that fairly complex condition and explain why we're doing it like that.

Done.

berdir’s picture

Status: Needs review » Needs work

Works for me, will commit this soon.

@davereid: Not ignoring your idea to enable it automatically, but I think this is a good first step, we could still change that, but I think there would be some challenges when doing that (basically a cross-dependency between config entities and plugins that they use, which exist based on the config entities that exist).

Thinking about that, I think what would make sense is extend the descrption on the type selection and say that additional types can be enabled on the settings page, with a link that points there. Lets do that, setting back to needs work hopefully one final time for that ;)

Bambell’s picture

Status: Needs work » Needs review
StatusFileSize
new15.89 KB
new725 bytes

Thinking about that, I think what would make sense is extend the descrption on the type selection [...].

Assuming you were referring to the type selection on the pattern creation form.

berdir’s picture

Status: Needs review » Reviewed & tested by the community

Yes.

  • Berdir committed 7195889 on 8.x-1.x authored by Bambell
    Issue #2655780 by Bambell, Berdir, rachel_norfolk, Kgaut: Allow to...
berdir’s picture

Status: Reviewed & tested by the community » Fixed

Great, committed.

kgaut’s picture

awesome ! Thanks !

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.