twig/slim3 中带有 currenturl 的 if 语句

if statement with currenturl in twig/slim3

我有一个问题可能很简单,但我想不通:)

我有一个 slim 3 / twig 应用程序,并创建了一个全局变量,这样我就可以在 twig 中获取 currentUrl。

在模板文件中,我不想使用 if 语句检查 currentUrl 是否包含字符串“/forretter”,因此它只在 for 循环中显示这些产品。

如果我做一个简单的 {{ currentUrl }} 它会按预期打印 url - 但 if 语句似乎不接受 currentUrl 变量。

我试过 {% set url = currentUrl %} 但没有成功。

我使用的 if 语句看起来像这样{% if '/forretter' in currentUrl %}我设置的所有其他 if 语句都非常有效。

家里有人对此有想法,因为我的秃头开始长白发:)

我现在已经尝试了 Georgy Ivanov 的回答并尝试将其与我的代码相匹配 - 并且 twig 扩展有效 - 但 if 语句没有。

这是我的容器代码

<?php

use function DI\get;
use Slim\Views\Twig;
use Cart\Basket\Basket;
use Cart\Models\Product;
use Cart\Models\Edit;
use Cart\Models\Order;
use Cart\Models\Customer;
use Cart\Models\Address;
use Cart\Models\Payment;
use Slim\Views\TwigExtension;
use Slim\Views\IsInUrlExtension;
use Interop\Container\ContainerInterface;
use Cart\Support\Storage\SessionStorage;
use Cart\Support\Storage\Contracts\StorageInterface;
use Cart\Validation\Contracts\ValidatorInterface;
use Cart\Validation\Validator;

return [
    'router' => get(Slim\Router::class),
    ValidatorInterface::class => function (ContainerInterface $c) {
        return new Validator;
    },
    StorageInterface::class => function (ContainerInterface $c) {
        return new SessionStorage('cart');
    },

    Twig::class => function (ContainerInterface $c) {
        $twig = new Twig(__DIR__ . '/../resources/views', [
          'debug' => true,
          'cache' => false,
        ]);

        $basePath = rtrim(str_ireplace('index.php', '', $c->get('request')->getUri()->getBasePath()), '/');
    // Add Slim specific extension
        $twig->addExtension(new Twig_Extension_Debug());
        $twig->addExtension(new TwigExtension(
            $c->get('router'), $basePath,
            $c->get('request')->getUri()
        ));
        $twig->addExtension(new IsInUrlExtension($c->get('request')->getUri()));
        $twig->getEnvironment()->addGlobal('currentUrl',$c->get('request')->getUri());
        $twig->getEnvironment()->addGlobal('basket', $c->get(Basket::class));

        return $twig;
    },

    Product::class => function (ContainerInterface $c) {
        return new Product;
    },

    Edit::class => function (ContainerInterface $c) {
        return new Edit;
    },

    Order::class=> function (ContainerInterface $c) {
        return new Order;
    },

    Customer::class=> function (ContainerInterface $c) {
        return new Customer;
    },

    Address::class=> function (ContainerInterface $c) {
        return new Address;
    },

    Payment::class=> function (ContainerInterface $c) {
        return new Payment;
    },

    Basket::class => function (ContainerInterface $c) {
        return new Basket(
            $c->get(SessionStorage::class),
            $c->get(Product::class)
        );
    }
];

这里是带有 if 语句的树枝代码

{% extends 'templates/app.twig' %}

{% block navigation %}
  {% include 'templates/partials/navigation.twig' %}
{% endblock %}

{% block content %}
<div class="row p__top">
  {% include 'templates/partials/sidebar_left.twig'  %}
  <section class="col-sm-12 col-md-6">
    <div class="product">

      {% if is_in_url('/forretter') %}

        <div class="row">
          <div class="categori__image">
            <img class="card-img-top"  src="{{site_url}}/images/varmrogetlaks.jpg" alt="Forretter">
          </div>
          <header class="menu__block">
            <h3 class="menu__title">Forretter</h3>
          </header>
          <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
            <div class="card-deck">
              {% include 'products/dinertransportable/partials/produkter.twig' %}

            </div>
        </div>

      {% else %}
        test2
      {{ dump(currentUrl) }}

      {% endif %}


    </div>
  </section>
  {% include 'templates/partials/sidebar_right.twig'  %}
</div>
{% endblock %}

您可以创建一个 Twig 扩展,如下所示:

<?php
class IsInUrlExtension extends \Twig_Extension
{
    public function __construct($currentUrl)
    {
        $this->currentUrl;
    }

    public function getName()
    {
        return 'extName';
    }

    public function getFunctions()
    {
        return [
            new \Twig_SimpleFunction('is_in_url', [$this, 'isInUrl']);
        ];
    }

    public function isInUrl(string $substr) : bool
    {
        return strpos($this->currentUrl, $substr) !== false;
    }
}

在容器中注册 Twig 组件时添加此扩展:

// Register component on container
$container['view'] = function ($container) {
    $view = new \Slim\Views\Twig('path/to/templates', [
        'cache' => 'path/to/cache'
    ]);

    // Instantiate
    $basePath = rtrim(str_ireplace('index.php', '', $container['request']->getUri()->getBasePath()), '/');
    // Add Slim specific extension
    $view->addExtension(new Slim\Views\TwigExtension($container['router'], $basePath));
    // Add your extension
    $view->addExtension(new IsInUrlExtension($container->get('request')->getUri()));

    return $view;
};

然后您可以像这样在模板中使用它:

{% if is_in_url('/forreter') %}
// substring is in current URL
{% endif %}

此方法的好处是您不必在模板中声明全局 currentUrl 变量,并且此 strpos 逻辑未在您的模板中实现,或者更确切地说,它封装在您的 可重用 扩展中。