German "Umlaut" in url

On my blog I have categories that I can assign to articles. All categories are displayed on the start page of the blog. If a user clicks on a category, he will be directed to a page where all articles of the category are listed. But I have problems with german umlauts. If you click on a category with a “Ü”, I get an error.

Listing of categories on the blog home page

    <div class="flex flex-no-wrap ml-4">
      <?php foreach($categories as $category): ?>
        <a class="rounded-full border border-secondary-600 py-2 px-4 hover:bg-secondary-300 ml-4" href="<?= $site->url() . '/blog/' . urldecode($category) ?>"><?= urldecode($category) ?></a>
      <?php endforeach ?>
    </div>

Blog-Controller

<?php
  return function ( $site, $pages, $page ) {

    $articles = $page->children()->listed();
    $categories = $articles->pluck( 'category', ',', true);

    if ( $category = urldecode( param( 'category' ) ) ) {
      $articles = $articles->filterBy( 'category', $category, ',' )->sortBy( 'date' )->flip();
    } else {
      $articles = $articles->sortBy( 'date' )->flip();
    }

    return compact( 'articles', 'categories', 'category');

  };
?>

Shouldn’t it be urlencode($category) at this point?

As @Adspectus wrote plus the second call to urldecode() (for printing the category) in that same line is superfluous.

urlencode doesn’t work :confused:

Not urlencode what you print out but the anker href as @Adspectus wrote.

Sure @textnixe, but the urlencode doesn’t work also in the href.

<a class="rounded-full border border-secondary-600 py-2 px-4 hover:bg-secondary-300 ml-4" href="<?= $site->url() . '/blog/' . urlencode($category) ?>"><?= $category ?></a>

Well, the other issue is that you are not using a parameter in your url, but then try to filter by parameter.

But I would like to have a separate page with a template for each category. So I would not like to do that over it. Anyway, this is the question how to deal with umlauts in the URL.

Well, urlencoding is the way to go. But if you want to use the category as a url part rather then a parameter, then your controller won’t work and you have to filter via routes instead: https://getkirby.com/docs/cookbook/content/filter-via-route

The encoded url looks ok to me, what is the issue?

I forgot to say that I basically have everything as it is in your linked thread. Well, it works on routing. But only not if an umlaut is in the category. There I get the error that the pages cannot be found. With other categories I get the articles from the category displayed.

But with the urlencode the link looks like it is broken.

'routes' => [
        [
          'pattern' => 'blog/(:any)',
          'action'  => function ($category) {
            if (in_array($category, page('blog')->children()->listed()->pluck('category', ',', true))) {
                // if that is the case, we return a virtual page

                return Page::factory([
                    'slug' => $category,
                    'template' => 'category',
                    'model' => 'category',
                    'content' => [
                        'title' => 'Alle Artikel in ' . '<span class="t-text-focus">' . ucfirst($category) . '</span>',
                    ]
                ]);
            }
            $this->next();
          }
        ]
    ]

Ok, in this case, if the category is urlencoded, your in_array() check will of course fail, because the value inside the array is not urlencoded. The alternative to using urlencoding would be to sluggify the category (would look nicer and more in line with URL slugs in Kirby), but in any case, you need to map the sluggified/urlencoded version to the real array.

1 Like