Пользовательский помощник для <picture> CakePHP

Я все еще изучаю CakePHP и хочу создать собственный помощник для тега изображения. Я уже использовал и сделал один для <source>, но теперь я не могу понять, как обернуть его внутри <picture>. Я предполагаю, что это должно быть решено с помощью какого-то массива, включая 3 <source> и 1 <img>.

Вид:

<div class = "container-fluid">
<picture>
    <?= $this->Picture->source($article, 'photolg_dir', 'photolg', '1200px'); ?>
    <?= $this->Picture->source($article, 'photomd_dir', 'photomd', '992px'); ?>
    <?= $this->Picture->source($article, 'photosm_dir', 'photosm', '768px');?>
    <?= $this->Picture->img($article, 'photo_dir', 'photo'); ?>
</picture>

Пользовательский помощник, в котором я создаю <источник> и хочу добавить <изображение>

<?php
 namespace Cake\View\Helper;

 use Cake\Core\Configure;
 use Cake\Http\Response;
 use Cake\View\Helper;
 use Cake\View\StringTemplateTrait;
 use Cake\View\View;


 class RestHelper extends Helper
 {

     use StringTemplateTrait;

     public $helpers = ['Url'];

     protected $_defaultConfig = [
         'templates' => [
             'link' => '<a href = "{{url}}"{{attrs}}>{{content}}</a>',
             'image' => '<img src = "{{url}}"{{attrs}}/>',
             'source' => '<source srcset = "{{url}}"{{attrs}}/>',
         ]
     ];

     public function __construct(View $View, array $config = [])
     {
         parent::__construct($View, $config);
         $this->response = $this->_View->response ?: new Response();
     }

    public function link($title, $url = null, array $options = [])
    {
        $escapeTitle = true;
        if ($url !== null) {
            $url = $this->Url->build($url, $options);
            unset($options['fullBase']);
        } else {
            $url = $this->Url->build($title);
            $title = htmlspecialchars_decode($url, ENT_QUOTES);
            $title = h(urldecode($title));
            $escapeTitle = false;
        }

        if (isset($options['escapeTitle'])) {
            $escapeTitle = $options['escapeTitle'];
            unset($options['escapeTitle']);
        } elseif (isset($options['escape'])) {
            $escapeTitle = $options['escape'];
        }

        if ($escapeTitle === true) {
            $title = h($title);
        } elseif (is_string($escapeTitle)) {
            $title = htmlentities($title, ENT_QUOTES, $escapeTitle);
        }

        $confirmMessage = null;
        if (isset($options['confirm'])) {
            $confirmMessage = $options['confirm'];
            unset($options['confirm']);
        }
        if ($confirmMessage) {
            $options['onclick'] = $this->_confirm($confirmMessage, 'return true;', 'return false;', $options);
        }

        $templater = $this->templater();

        return $templater->format('link', [
            'url' => $url,
            'attrs' => $templater->formatAttributes($options),
            'content' => $title
        ]);
    }

    public function image($path, array $options = [])
    {
        $path = $this->Url->image($path, $options);
        $options = array_diff_key($options, ['fullBase' => null, 'pathPrefix' => null]);

        if (!isset($options['alt'])) {
            $options['alt'] = '';
        }

        $url = false;
        if (!empty($options['url'])) {
            $url = $options['url'];
            unset($options['url']);
        }

        $templater = $this->templater();
        $image = $templater->format('image', [
            'url' => $path,
            'attrs' => $templater->formatAttributes($options),
        ]);

        if ($url) {
            return $templater->format('link', [
                'url' => $this->Url->build($url),
                'attrs' => null,
                'content' => $image
            ]);
        }

        return $image;
    }

     public function source($path, array $options = [])
     {

         $path = $this->Url->image($path, $options);
         $options = array_diff_key($options, ['fullBase' => null, 'pathPrefix' => null]);

         if (!isset($options['alt'])) {
             $options['alt'] = '';
         }

         $url = false;
         if (!empty($options['url'])) {
             $url = $options['url'];
             unset($options['url']);
         }

         $templater = $this->templater();
         $source = $templater->format('source', [
             'url' => $path,
             'attrs' => $templater->formatAttributes($options),
         ]);

         if ($url) {
             return $templater->format('link', [
                 'url' => $this->Url->build($url),
                 'attrs' => null,
                 'content' => $source
             ]);
         }

         return $source;
     }

     public function implementedEvents()
     {
         return [];
     }
 }
?>

Другой помощник, в котором я подключаюсь между представлением и RestHelper:

<?php
namespace App\View\Helper;

use Cake\View\Helper;
use Cake\View\View;

/**
 * Bild helper
 */
class PictureHelper extends Helper
{
    public $helpers = ['Rest', 'Html'];
    /**
     * Default configuration.
     *
     * @var array
     */
    protected $_defaultConfig = [
    ];

    public function picture(\App\Model\Entity\Article $article)
    {

    }

    public function source(\App\Model\Entity\Article $article, $dir, $size, $brpnt)
    {
        return $this->Rest->source('/' . $article->$dir . '/' . $article->$size, ['class' => 'img-fluid', 'alt' => 'Responsive image', 'media' => "(min-width: $brpnt)"]);
    }

    public function img(\App\Model\Entity\Article $article, $dir, $size)
    {
        return $this->Rest->image('/' . $article->$dir . $article->$size, ["class" => "img-fluid"], ["alt" => "Responsive image"]);
    }


    public function thumb(\App\Model\Entity\Article $article, $dir, $size)
    {
        return $this->Rest->image('/' . $article->$dir . '/' . 'thumbnail-' . $article->$size, ["class" => "img-fluid"], ["alt" => "Responsive image"]);
    }
}

Большое спасибо за помощь.

Ваш пример кода кажется неработающим ...

ndm 30.10.2018 14:39

Я добавил остальной код. Этот работает.

Mr.Velazquez 30.10.2018 14:54
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
2
257
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Нашел решение. Просто проверьте, заполнены ли столбцы с изображениями, которые вы хотите использовать в <изображение>, и затем вызовите функцию источника. Чтобы немного уменьшить это, просто сохраните путь как дыру в БД, а не как я сохранял папку и имя отдельно.

Помощник:

class PictureHelper extends Helper
{
    use StringTemplateTrait;

    public $helpers = ['Html', 'Url'];

    protected $_defaultConfig = [
        'templates' => [
            'source' => '<source srcset = "{{url}}"{{attrs}}/>',
        ]
    ];

    public function source($path, array $options = [])
    {

        $path = $this->Url->image($path, $options);
        $options = array_diff_key($options, ['fullBase' => null, 'pathPrefix' => null]);

        if (!isset($options['alt'])) {
            $options['alt'] = '';
        }

        $url = false;
        if (!empty($options['url'])) {
            $url = $options['url'];
            unset($options['url']);
        }

        $templater = $this->templater();
        $source = $templater->format('source', [
            'url' => $path,
            'attrs' => $templater->formatAttributes($options),
        ]);

        if ($url) {
            return $templater->format('link', [
                'url' => $this->Url->build($url),
                'attrs' => null,
                'content' => $source
            ]);
        }

        return $source;
    }

    public function thumb($what, $dir, $size)
    {
        return $this->Html->image('/' . $what->$dir . '/' . 'thumbnail-' . $what->$size, ["class" => "img-fluid"], ["alt" => "Responsive image"]);
    }

    public function picture($what, $large, $largedir, $medium, $mediumdir, $small, $smalldir, $xsmall, $xsmalldir)
    {
        //
        if (!empty($what->$large)) {
            $lg = $this->source('/' . $what->$largedir . '/' . $what->$large, ['class' => 'img-fluid', 'alt' => 'Responsive image', 'media' => "(min-width: 1200px)"]);
        } else {
            $lg = NULL;
        }

        if (!empty($what->$medium)) {
            $md = $this->source('/' . $what->$mediumdir . '/' . $what->$medium,['class' => 'img-fluid', 'alt' => 'Responsive image', 'media' => "(min-width: 998px)"]);
        } else {
            $md = NULL;
        }

        if (!empty($what->$small)) {
            $sm = $this->source('/' . $what->$smalldir . '/' . $what->$small,['class' => 'img-fluid', 'alt' => 'Responsive image', 'media' => "(min-width: 768px)"]);
        } else {
            $sm = NULL;
        }

        $img = $this->Html->image('/' . $what->$xsmalldir . $what->$xsmall, ["class" => "img-fluid"], ["alt" => "Responsive image"]);

        return "<picture> $lg $md $sm $img</picture>";
    }
}

В представлении:

<div class = "container-fluid">
    <?= $this->Picture->picture($article, 'photolg', 'photolg_dir', 'photomd', 'photomd_dir', 'photosm', 'photosm_dir', 'photo', 'photo_dir'); ?>
</div>

Другие вопросы по теме