Передача идентификатора поста в функцию Twig / Timber

Как передать идентификатор сообщения функции Twig / Timber, например edit_post_link?

Чтение документации на https://timber.github.io/docs/guides/functions/#function-with-arguments

Такая функция, как edit_post_link, попытается угадать идентификатор сообщения, которое вы хотите отредактировать, из текущего сообщения в The Loop. та же функция требует внесения некоторых изменений в файл, например archive.twig или index.twig. Здесь вам нужно будет явно передать идентификатор сообщения.

И вот что происходит; когда я использую это

{{ function('edit_post_link', 'Edit', '<span class="edit-link">', '</span>', post.ID) }}

в index.twig все ссылки редактирования имеют идентификатор публикации страницы, на которой отображается цикл настраиваемых типов сообщений, а не идентификатор сообщения каждого настраиваемого типа сообщения, который находится в цикле.

Я использую функцию ниже в functions.php, которая также заставляет target="_blank" при редактировании ссылок:

add_filter( 'edit_post_link', 'newwindow_edit_post_link', 10, 3 );

global $post;
$post_id = $post->ID;

    function newwindow_edit_post_link( $link, $post_id, $text ) {
        if( !is_admin() )
            $link = str_replace( '<a ', '<a target="_blank" ', $link );
        return $link;
    }

Это основной цикл на index.twig. "люди" - это стандартный настраиваемый тип записи WordPress:

 {% if people %}

            {% for person in people %}

                    <a href="{{ person.link }}">{{ person.name }}</a>

                        {{ function('edit_post_link', 'Edit', '<span class="edit-link">', '</span>', post.ID) }}

            {% endfor %}

    {% else %}

 {% endif %}

В результате все ссылки редактирования указывают на эту страницу, а не на каждый пользовательский тип сообщения «человек».

Так как мне позвонить по идентификатору поста? Нужно ли мне вызывать идентификатор сообщения в пользовательской функции типа сообщения?

В основном файле index.php есть стандартные функции Twig:

$context = Timber::get_context();
$context['posts'] = Timber::get_posts();
$templates = array( 'index.twig' );
Timber::render( $templates, $context );

person BlueDogRanch    schedule 24.10.2018    source источник
comment
Если person является объектом сообщения (WP_Post), попробуйте person.ID вместо post.ID.   -  person Sally CJ    schedule 26.10.2018
comment
Хм ... но нет, это не сработает.   -  person BlueDogRanch    schedule 26.10.2018
comment
В index.php, как вы определяете people? Можешь показать код?   -  person Sally CJ    schedule 27.10.2018
comment
Я добавил index.php, но это стандартная функция Twig. Человек CPT - это стандартный CPT WordPress.   -  person BlueDogRanch    schedule 27.10.2018
comment
Я имел в виду, разве у твоего $context нет people ($context['people'])? Если да, то где это определяется? Если нет, то откуда people? Может, вы сможете показать полный код в вашем index.twig файле? Или временно добавьте {{ fn( 'var_dump', person ) }} в ваш for цикл и поделитесь результатом.   -  person Sally CJ    schedule 27.10.2018
comment
Интересно; использование {{ dump(person) }} показало мне идентификатор, а использование {{ person.id }} - отображение идентификатора в index.twig. Но это должен быть идентификатор в нижнем регистре, а не идентификатор. Но вся функция по-прежнему не работает.   -  person BlueDogRanch    schedule 29.10.2018
comment
Я могу протестировать ваш код, но мне нужно посмотреть, как определяется people. Или это что-то вроде get_posts( 'post_type=person' )? А по функциям вы имеете в виду newwindow_edit_post_link(), верно?   -  person Sally CJ    schedule 29.10.2018
comment
Извините, я имею в виду, это {{ function('edit_post_link', ...) }} не работает, и если да, то как это не работает? Нет вывода, не ожидаемый результат, или?   -  person Sally CJ    schedule 29.10.2018
comment
Нет вывода из {{ function('edit_post_link', ...) }}   -  person BlueDogRanch    schedule 29.10.2018
comment
Попробуйте {{ function( 'get_edit_post_link', person.id ) }}, просто чтобы посмотреть, приведет ли это к правильному результату.   -  person Sally CJ    schedule 29.10.2018
comment
В качестве альтернативы, как сказано в документации, сделать edit_post_link доступным в Twig, используя Timber\Twig_Function внутри хука timber/twig. И используйте {{ edit_post_link(...) }}. Если это все еще не работает, возможно, проблема в person.id.   -  person Sally CJ    schedule 29.10.2018
comment
То, что находится в документации Twig, не работает. Нет вывода от {{ function( 'get_edit_post_link', person.id ) }}. {{ person.id }} действительно работает, поэтому я сделал ссылку для редактирования вручную, используя {% if user %} для входа в систему.   -  person BlueDogRanch    schedule 29.10.2018
comment
Не уверен, что не так в вашем случае, но я протестировал ваш код (хотя я использовал front-page.php), и у меня все сработало.   -  person Sally CJ    schedule 29.10.2018
comment
Но, конечно, edit_post_link() не вернет результат, если у текущего пользователя нет любые разрешения на редактирование сообщения.   -  person Sally CJ    schedule 29.10.2018


Ответы (3)


Так как мне позвонить по идентификатору поста?

Если people в цикле в вашем шаблоне index.twig представляет собой массив сообщений (т. Е. Каждое сообщение является экземпляром WP_Post / Timber\Post), тогда вы можете (или должны иметь возможность) получить идентификатор сообщения через person.ID или person.id (да, оба на самом деле установить). Так что у меня это сработало:

{{ function('edit_post_link', 'Edit', '<span class="edit-link">', '</span>', person.id) }}
{{ function('edit_post_link', 'Edit', '<span class="edit-link">', '</span>', person.ID) }}

Как я подтвердил вышеизложенное

  1. Я установил и активировал официальную стартовую тему Timber.

  2. Я создал front-page.php:

    <?php
    $context = Timber::get_context();
    
    // Here, I defined the `people`.
    $context['people'] = Timber::get_posts( [
        'post_type'      => 'post', // yours would be 'person' and not 'post'
        'posts_per_page' => 3,
    ] );
    
    // This I used for testing only.
    $context['post'] = new Timber\Post();
    
    $templates = array( 'front-page.twig' );
    Timber::render( $templates, $context );
    
  3. Затем я создал templates/front-page.twig:

    {% extends "base.twig" %}
    
    {% block content %}
        <h2>The queried page's title: {{ post.title }}</h2>
        <p>The queried page's ID: <b>{{ post.id }}</b></p>
        {% if people %}
    
            {% for person in people %}
    
            <a href="{{ person.link }}">{{ person.name }}</a>
    
            {{ function('edit_post_link', 'Edit', '<span class="edit-link">', '</span>', person.id) }}<br>
    
            {% endfor %}
    
        {% else %}
    
        {% endif %}
    
        {% include 'partial/pagination.twig' with { pagination: posts.pagination({show_all: false, mid_size: 3, end_size: 2}) } %}
    {% endblock %}
    

И у меня все работало нормально, edit_post_link() был вызван правильно и отображает ссылку на сообщение с target="_blank" в разметке. (Я положил newwindow_edit_post_link материал в functions.php)

person Sally CJ    schedule 29.10.2018
comment
Спасибо, это должно быть так, но мне пришлось использовать ручную ссылку, такую ​​как ответ markratledge. - person BlueDogRanch; 03.11.2018
comment
Если бы я мог видеть весь код, который вы используете, я мог бы помочь вам в дальнейшем ... Но в любом случае, спасибо за награду. :) - person Sally CJ; 03.11.2018

Если посмотреть на документацию по Twig 2.x, {{ function }} функция Twig по умолчанию отсутствует. Я определенно никогда не видел этого за годы использования Symfony, поэтому подозреваю, что это что-то особенное?

Я только что погуглил "timber / twig", и на самом деле это плагин WordPress для обеспечения функциональности Twig в ваших шаблонах тем, поэтому я считаю, что вы по ошибке поместили тег Symfony в свой вопрос. Я предлагаю удалить это и вместо этого добавить wordpress, чтобы вы могли получить более полезные ответы, чем я.


Для уверенности нам нужно увидеть исходный код PHP для вашей пользовательской функции edit_post_link Twig. Однако может показаться, что вам просто нужно отобразить в своих аргументах один и тот же порядок как на стороне PHP, так и на стороне Twig. Например, если ваша функция:

function edit_post_link(string $label, string $openingHtml, string $closingHtml, int $postId) {
    // blah blah blah
}

После того, как вы зарегистрируете эту функцию в Twig (хотя Тимбер, похоже, утверждает, что вам, возможно, не нужно этого делать, проверьте), вы действительно будете использовать ее точно так, как вы написали:

{{ function('edit_post_link', 'Edit', '<span class="edit-link">', '</span>', post.ID) }}

Я чувствую, что это может быть не то, что вы имеете в виду, возможно, вам интересно, как вы вообще ухватились за post.ID. Если это так, то ваша проблема не в {{ function }}, и нам нужно будет увидеть больше из вашего источника шаблона Twig вместе с переменными, которые вы открыли для него из PHP.

person Adambean    schedule 24.10.2018
comment
Спасибо, я по ошибке пометил Симфонию. И у меня нет функции edit_post_link в functions.php Похоже, мне нужна функция, которая будет получать идентификатор сообщения? - person BlueDogRanch; 24.10.2018
comment
Если у вас нет функции PHP, зарегистрированной в Twig с псевдонимом edit_post_link, я подозреваю, что Twig выдаст это как исключение. Выполните поиск edit_post_link, чтобы убедиться, что вы еще не зарегистрировали этот псевдоним для неправильной функции по ошибке. - person Adambean; 24.10.2018
comment
Ах, у меня есть фильтр, который заставляет target = _blank; добавил к моему вопросу. Ты прав; должно быть поэтому я не получаю фатальных ошибок. Так имеет ли смысл добавлять идентификатор сообщения к этой функции? - person BlueDogRanch; 24.10.2018
comment
Да, вашему фильтру edit_post_link потребуется аргумент для получения идентификатора сообщения. Неважно, какой аргумент он предоставляет, использование вашего внешнего интерфейса Twig соответствует порядку. - person Adambean; 24.10.2018
comment
Хорошо, но теперь я не знаю, как это сделать. Похоже, мне нужен глобальный $ post; $ post_id = $ post- ›ID; чтобы получить идентификатор для каждого сообщения вне цикла. - person BlueDogRanch; 24.10.2018
comment
Да, хотя это проблема WordPress, и на этом мой опыт заканчивается. (Кажется, с вашим Twig все в порядке.) Разве нет функции PHP, такой как the_post(), для получения этой информации? - person Adambean; 25.10.2018

Это некрасиво, но если вы не можете заставить функцию edit_post_link работать в template.twig, а {{ person.id }} работает, вы можете использовать эту настройку в своем шаблоне веточки.

Он определяет, вошел ли пользователь в систему и может ли он редактировать, и если да, отображает ссылку редактирования - динамическую с {{ person.id }} - которая открывается в новой вкладке:

{% if user %}
<a class="style-me" target="_blank"
href="{{ site.url }}/wp-admin/post.php?post={{ person.id }}&action=edit">Edit</a>
{% endif %}
person markratledge    schedule 01.11.2018