Problem/Motivation

You currently cannot create paths like blog/% as placeholders aren't replaced with slugs.

Proposed resolution

Replace them, but don't care yet about actual arguments.

Remaining tasks

User interface changes

API changes

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

dawehner’s picture

Status: Active » Needs review
FileSize
4.09 KB

Here is a first patch.

Status: Needs review » Needs work

The last submitted patch, 1: 2352959-1.patch, failed testing.

Berdir’s picture

Are we going to support typed arguments with upcasting, or will we do that manually, later on? Like configuring somewhere that arg_1 is a taxonomy_term

tstoeckler’s picture

Status: Needs work » Needs review
FileSize
532 bytes
4.16 KB

Reviving this. Have no opinion on #3.

Status: Needs review » Needs work

The last submitted patch, 4: 2352959-4-page-manager-arguments.patch, failed testing.

tstoeckler’s picture

Status: Needs work » Needs review
FileSize
4.21 KB

Hmm... patches are weird sometimes. Maybe this will work.

Status: Needs review » Needs work

The last submitted patch, 6: 2352959-6-page-manager-arguments.patch, failed testing.

tstoeckler’s picture

Status: Needs work » Needs review
FileSize
504 bytes
4.24 KB

Meh.

tim.plunkett’s picture

  1. +++ b/src/Routing/PageManagerRoutes.php
    @@ -80,6 +86,21 @@ class PageManagerRoutes extends RouteSubscriberBase {
    +          if ($bit == '%') {
    

    Should we, like Views does, support %foo in addition to %?

    (Also, what a shame that code isn't located somewhere more useful)

  2. +++ b/tests/src/Unit/PageManagerRoutesTest.php
    @@ -161,6 +161,56 @@ class PageManagerRoutesTest extends UnitTestCase {
    +    $expected_defaults = array(
    

    If you end up rerolling, can you switch to [] syntax? Not a big deal.

Sorry for sitting on this one so long.

tim.plunkett’s picture

#2329317: Trying to use node/%node as a path should fail seems to think we should explicitly prevent this.
I agree we should either support it, or prevent it.
Other thoughts?

tim.plunkett’s picture

FileSize
3.97 KB

Rerolled with short array syntax.

dasjo’s picture

took me a while to find this one while searching for "dynamic context" support :)

just tested and works but wonder if the issue title makes sense?

rlmumford’s picture

Status: Needs review » Reviewed & tested by the community

This seems to work well. I think we can leave questions about support '%foo' up to a future arguments issue when we sort out the upcasting.

Arla’s picture

Me and @Berdir used this patch on a project, but we also needed to be able to specify the types of the arguments, so we went ahead with the attached fix. It supports any of the patterns %, %arg and %arg.type. I'm just posting it here to try to get this ball moving again. I don't want to postpone this particular issue any further, so I'm leaving it RTBC and the patch in #11 should be regarded as current.

dasjo’s picture

Posting a patch that combines #11 + #14

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 15: 2352959-page-manager-arguments-15.patch, failed testing.

saltednut’s picture

I think maybe #15 should be another issue. I've re-queued the bot and would like to move forward with getting this in if it passes.

The last submitted patch, 11: 2352959-page-manager-arguments-11.patch, failed testing.

saltednut’s picture

Looks like just PageManagerRoutesTest is failing so we should look into fixing that and moving forward with a followup to get the argument patterns from 14/15

Status: Needs work » Needs review
Berdir’s picture

Quite a lot changed, here's a reroll.

Tests will probably fail, I'll address that asap.

I also removed the incorrect argument behavior and removed the empty default value for it.

Status: Needs review » Needs work

The last submitted patch, 22: 2352959-page-manager-arguments-22.patch, failed testing.

Berdir’s picture

Status: Needs work » Closed (duplicate)

This has been implemented in #2631802: Allow explicitly configuring the type of context from parameters now, closing this as a duplicate.

In case someone was using the patch above, especially the part that allowed to specify types, you can use the following to update existing pages. It also supports to convert any path with % or %something to {something}, as % will likely not be supported anymore soon.

/** @var \Drupal\page_manager\PageInterface $page */
  foreach (Page::loadMultiple() as $page) {
    $path = $page->getPath();
    if (preg_match_all('|/%([\w+]*)\.*([\w+]*)|', $path, $matches)) {
      foreach ($matches[0] as $i => $part) {
        $name = $matches[1][$i] ?: 'arg_' . $i;
        $new = '/{' . $name. '}';
        if (!empty($matches[2])) {
          $page->setParameter($matches[1][$i], $matches[2][$i]);
        }
        $path = str_replace($part, $new, $path);
      }
      $page->set('path', $path);
      $page->save();
    }

  }
Berdir’s picture

That update function has a bug and breaks pages that override an existing path and use %. This is hacky but seems to work for me:

/**
 * Update page arguments with types, use parameters.
 */
function np8_update_update_8091() {
  /** @var \Drupal\page_manager\PageInterface $page */
  foreach (Page::loadMultiple() as $page) {
    $save = FALSE;
    $path = $page->getPath();
    if (strpos($path, '%') !== FALSE) {
      $row = \Drupal::database()
        ->query('SELECT * FROM router WHERE pattern_outline = :path LIMIT 1', ['path' => $path])
        ->fetch();
      // If the path used % and it matches a pattern outline, use the path
      // with slugs instead.
      if ($row) {
        $save = TRUE;
        $path = $row->path;
      }
    }
    if (preg_match_all('|/%([\w+]*)\.*([\w+]*)|', $path, $matches)) {
      foreach ($matches[0] as $i => $part) {
        $name = $matches[1][$i] ?: 'arg_' . $i;
        $new = '/{' . $name. '}';
        if (!empty($matches[2])) {
          $page->setParameter($matches[1][$i], $matches[2][$i]);
        }
        $path = str_replace($part, $new, $path);
      }
      $save = TRUE;
    }

    if ($save) {
      $page->set('path', $path);
      $page->save();
    }
  }
}