API Rewrite: Основы

18 января 2018

Это часть первой из двух частей, посвященных API-интерфейсу WordPress. В этом уроке мы рассмотрим, как работают перезаписываемые работы и основные методы для создания пользовательских правил перезаписи.


Что такое переписывание?

WordPress, как и все системы управления контентом, решает, какой контент отображать на основе переменных (обычно называемых переменными запроса), переданных ему. Например: http: example.com index.php? Category = 3 сообщает WordPress, что мы после сообщений в категории с идентификатором 3 и http: example.com index.php? Feed = rss сообщает WordPress, что мы хотим, чтобы фид сайта RSS формат.

К сожалению, это может оставить нас с довольно уродливыми URL-адресами:

http://example.com/index.php?post_type=portfolio&taxonomy=wordpress&portfolio=my-fancy-plugi

Здесь происходит переписывание WordPress. Это позволяет нам заменить выше:

http://example.com/portoflio/wordpress/my-fancy-plugi

Который теперь не только намного читабельнее (и запоминается), но и более дружелюбен к SEO. Это, в двух словах, то, что переписывает.


Как это работает?

Теперь http: example.com portoflio wordpress my-fancy-plugin не существует как каталог или файл. Итак, как WordPress обслуживает правильный контент? Когда WordPress получает «довольно постоянную ссылку», как указано выше, он должен преобразовать это во что-то, что он понимает, а именно объект запроса. Более просто он должен принять симпатичный URL-адрес и сопоставить соответствующие части с правильной переменной запроса. Итак, для нашего примера:

http://example.com/portoflio/wordpress/my-fancy-plugi

post_type установлен в 'portfolio'portfolio-taxonomy установлен на' wordpress'portfolio установлен на 'my-fancy-plugin' (название сообщения)

Тогда WordPress знает, что мы после сообщений типа 'портфолио', в «wordpress» «таксономия портфолио-таксономии» с названием «my-fancy-plugin». (Как вы, возможно, догадались, что первые два на самом деле излишни). Затем WordPress выполняет этот запрос, выбирает соответствующий шаблон для отображения результатов, а затем служит для просмотра. Но, очевидно, WordPress не просто угадывает, как интерпретировать URL-адреса, это нужно сказать...

Начало с.htaccess

Предполагая, что вы можете и разрешили довольно постоянные ссылки на странице настроек -> Permalinks (см. Codex для минимальных требований - для WordPress на серверах Nginx есть этот плагин) - тогда все начинается с файла.htaccess. Он играет простую и вместе с тем значительную роль. WordPress содержит в этом файле что-то похожее на следующее:

# BEGIN WordPress
<IfModule mod_rewrite.c>
    RewriteEngine O
    RewriteBase /
    RewriteRule ^index.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
</IfModule>
# END WordPress

Это просто проверяет, существует ли файл или каталог на самом деле - и если это так, вы просто принимаете его. Например:

http://example.com/blog/wp-content/uploads/2012/04/my-picture.png

Просто возьмите приложение PNG «my-picture.png». Но, как и в случае:

http://example.com/blog/portoflio/wordpress/my-fancy-plugi

Если каталог не существует, вы попадаете в файл index.php WordPress. Это тот файл, который загружает WordPress.

Интерпретация URL

В этот момент WordPress еще не знает, что вам нужно. После некоторой начальной загрузки WordPress и его параметров он запускает метод parse_request класса WP (находится в файле class-wp.php). Именно этот метод принимает portoflio wordpress my-fancy-plugin и преобразует его в понятный объект WordPress (почти, он фактически устанавливает массив query_vars, а затем $ wp-> query_posts превращает это в запрос).

Короче говоря, эта функция сравнивает полученный URL (portoflio wordpress my-fancy-plugin) с массивом «регулярных выражений». Это массив перезаписи - и он будет выглядеть примерно так:

category/(.+?)/page/?([0-9]{1,})/?$ => index.php?category_name=$matches[1]&paged=$matches[2]
category/(.+?)/?$ => index.php?category_name=$matches[1]
tag/([^/]+)/page/?([0-9]{1,})/?$=> index.php?tag=$matches[1]&paged=$matches[2]
tag/([^/]+)/?$ => index.php?tag=$matches[1]
([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/?$ => index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]
(.+?)(/[0-9]+)?/?$ => index.php?pagename=$matches[1]&page=$matches[2]

Ключи этого массива являются регулярными выражениями, и полученный URL-адрес сравнивается с каждым по очереди, пока не будет найдено совпадение с шаблоном полученного URL-адреса. Соответствующее значение - это то, как URL-адрес интерпретируется. Массив $ matches содержит захваченные значения (индексированные из 1) из соответствия.

Например, посетив веб-сайт тега blog.example.com my-tag, WordPress будет искать первый шаблон, который соответствует тегу my-tag. С указанным выше массивом он соответствует третьему шаблону: tag ([^] +)? $. Это говорит WordPress, чтобы интерпретировать URL как www.example.com blog index.php? Tag = my-tag и, соответственно, архив my-tag.

Конечно, WordPress позволяет настраивать этот массив, а остальная часть этого руководства посвящена тому, как вы это показываете.


Настройка правил перезаписи

Настройки -> Постоянная ссылка

Первым вашим портом вызова должна быть страница настроек «Постоянная ссылка». На этой странице вы можете изменить правила для типа почтовых сообщений «post» и «category» и «tag». Параметр «по умолчанию» отключен, но вы можете выбрать из списка предустановленных структур или создать настраиваемую структуру. Обратите внимание, что пользовательские структуры не должны содержать URL вашего сайта. WordPress позволяет изменять вашу структуру постоянной ссылки, добавляя в них теги, такие как% postname% (имя сообщения),% year% (год публикации публикации) и% author% (автор сообщения). Структура постоянной ссылки, такая как:

/%year%/%author%/%postname%/

Будет создавать почтовую ссылку, такую как:

www.example.com/2012/stephen/my-post

Документацию по этим параметрам можно найти в WordPress Codex. (Позже я покажу вам, как создавать свои собственные теги).

Однако предоставленные варианты весьма ограничены. В этом уроке я сосредоточусь на функциях, предоставляемых WordPress, которые предлагают больший контроль над структурами константных ссылок и как они интерпретируются. Я не буду освещать варианты перезаписи, доступные для пользовательских типов сообщений или таксономий, так как это будет рассмотрено в части 2.

Почему нужно обновить правила перезаписи?

После любого изменения правил перезаписи (например, либо с использованием одного из следующих методов, либо путем регистрации пользовательского типа сообщения или таксономии) вы можете обнаружить, что новые правила не вступают в силу. Это потому, что вам нужно сбросить правила перезаписи. Это можно сделать одним из двух способов:

Просто посетить Настройки -> Постоянная ссылка pagenCall flush_rewrite_rules () (см. Часть 2)

Что это делает? Напомним, что метод parse_request сравнивает запрос с массивом перезаписи. Этот массив находится в базе данных. Промывка правил перезаписи обновляет базу данных, чтобы отразить ваши изменения - и пока вы этого не сделаете, они не будут распознаны. Но parse_request также записывает файл.htaccess. Это делает его дорогостоящей операцией. Поэтому, хотя я не буду распространять использование flush_rewrite_rules () до части 2, я предоставлю вам это предупреждение: не называть flush_rewrite_rules при каждой загрузке страницы. Плагины должны вызывать это только тогда, когда подключаемый модуль активирован и деактивирован.

Добавить правило Rewrite

add_rewrite_rule позволяет добавлять дополнительные правила в массив перезаписи. Эта функция принимает три аргумента:

rule - регулярное выражение, с помощью которого можно сравнить URL-адрес запроса против rewrite - строку запроса, используемую для интерпретации правила. Массив $ matches содержит захваченные совпадения и начинается с индекса '1'.position -' top 'или' bottom '. Где разместить правило: в верхней части массива перезаписи или снизу. WordPress сканирует верхнюю часть массива на дно и останавливается, как только находит совпадение. Для того, чтобы ваши правила имели приоритет над существующими правилами, вы должны установить это в «top». Значение по умолчанию: «bottom'.

Примечание: если вы используете add_rewrite_rule несколько раз, каждый с позицией« верх »- первый вызов имеет приоритет над последующими вызовами.

Предположим, что у наших сообщений есть дата события, связанная с ними, и мы хотим иметь эту структуру: www.example.com blog the-olympics-begin 2012-07-27 интерпретируется как www.example.com blog index.php? Postname = the-olympics-begin &eventdate = 2012-07-27, тогда мы можем добавить это правило следующим образом:

function wptuts_add_rewrite_rules() {
    add_rewrite_rule(
        '^([^/]*)/([0-9]{4}-[0-9]{2}-[0-9]{2})/?$' // String followed by a slash, followed by a date in the form '2012-04-21', followed by another slash
        'index.php?pagename=$matches[1]&eventdate=$matches[2]',
        'top'
    );
}
add_action( 'init', 'wptuts_add_rewrite_rules' );

Следующее будет интерпретировать www.example.com olympics 2012 гребли как www.example.com index.php? P = 17 &olymyear = 2012 &game = гребля

add_rewrite_rule(
    '^olympics/([0-9]{4})/([^/]*)',
    'index.php?p=17&olymyear=$matches[1]&game=$matches[2]',
    'top'
);

Если вы не уверены в своих регулярных выражениях, вы можете найти это введение и этот инструмент полезен.

Добавить тег перезаписи

Вы можете подумать, что значение eventdate (2012-07-27 в приведенном выше примере), olymyear и game могут быть доступны из внутренних элементов WordPress через get_query_var (таким же образом, что get_query_var ('paged ') получает номер страницы, на которой вы находитесь). Однако WordPress автоматически не распознает переменную eventdate, даже если она интерпретируется как переменная GET. Существует несколько способов заставить WordPress распознавать пользовательские переменные. Один из них - использовать фильтр query_vars, как показано в разделе «Добавить пользовательскую конечную точку» ниже. Кроме того, мы можем сделать еще один шаг и использовать add_rewrite_tag для регистрации пользовательского тега, например, по умолчанию% postname% и% year%

. Эта функция принимает три аргумента:

tag name - (с начальным и конечным%), например:% eventdate % nregex - Регулярное выражение для проверки значения, например '([0-9] {4} - [0-9] {2} - [0-9] {2})' query - (необязательно) Как интерпретируется тег, например. 'EVENTDATE ='. Если это предусмотрено, оно должно заканчиваться символом '='.

function wptuts_register_rewrite_tag() {
    add_rewrite_tag( '%eventdate%', '([0-9]{4}-[0-9]{2}-[0-9]{2})');
}
add_action( 'init', 'wptuts_register_rewrite_tag');

Мало того, что get_query_var ('eventdate') возвращает значение даты в URL-адресе, но вы можете использовать тег% eventdate% в настройках -> Permalink (вместе со значением по умолчанию% year%,% postname% и т. Д.) И WordPress правильно ее интерпретирует. К сожалению, когда вы создаете постоянную ссылку, WordPress не знает, как заменить% eventdate% на соответствующее значение: так что наши постоянные сообщения заканчиваются так:

www.example.com/the-olympics-begin/%eventdate%

Нам нужно заменить% eventdate% на соответствующее значение, и мы можем сделать это, используя фильтр post_link. (В этом примере я буду считать, что значение хранится в настраиваемом поле «eventdate»).

function wp_tuts_filter_post_link( $permalink, $post ) {
    // Check if the %eventdate% tag is present in the url:
    if ( false === strpos( $permalink, '%eventdate%' ) )
        return $permalink;
    // Get the event date stored in post meta
    $event_date = get_post_meta($post->ID, 'eventdate', true);
    // Unfortunately, if no date is found, we need to provide a 'default value'.
    $event_date = ( ! empty($event_date) ? $event_date : '2012-01-01' );
    $event_date =urlencode($event_date);
    // Replace '%eventdate%'
    $permalink = str_replace( '%eventdate%', $event_date , $permalink );
    return $permalink;
}
add_filter( 'post_link', 'wp_tuts_filter_post_link' , 10, 2 );

Во второй части этой серии я расскажу о пользовательских тегах для пользовательских типов сообщений.

Добавить пользовательскую конечную точку

Конечные точки - это теги, которые добавляются к URL (трекбэк [значение] является наиболее распространенным). Он имеет несколько других потенциальных возможностей: отображение разных шаблонов в зависимости от набора значений, пользовательских уведомлений и отображения сообщений в разных «форматах» (для печати, XML, JSON и т. Д.).

Вы можете создавать конечные точки с помощью add_rewrite_endpoint. Эта функция принимает два аргумента:

ame - имя конечной точки, например. 'json', 'form' и т. д. where - маска конечной точки, определяющая, где должна быть добавлена ​​конечная точка. Это должно быть одной из констант EP_ *, перечисленных ниже (или комбинация с использованием побитовых операторов). Когда вы регистрируете пользовательские типы сообщений, вы можете создать маску для этого типа сообщения:

Маски для конечных точек по умолчанию:

EP_PERMALINK - для post permalinksEP_ATTACHMENT - для attachmentsEP_DATE - для архивов dateEP_YEAR - для архивов годаEP_MONTH - для архивов месяцев _pdf - для ' day 'archivesEP_ROOT - для корня файла siteEP_COMMENTS - для комментариевEP_SEARCH - для searchEP_CATEGORIES - для категорийEP_TAGS - для тегов EP_AUTHORS - для архива записей автора EP_PAGES - для pagesEP_ALL - для all

Конечные точки чрезвычайно гибкие, вы можете использовать их с побитовыми операторами, поэтому, например, вы можете добавить конечную точку для отправки и ссылки на страницы с помощью EP_PERMALINK | EP_PAGES.

function wptuts_add_endpoints() {
    add_rewrite_endpoint('myendpoint', EP_PERMALINK); // Adds endpoint to permalinks
    add_rewrite_endpoint( 'anotherendpoint', EP_AUTHORS | EP_SEARCH); // Adds endpoint to urls for authors or search results
}
add_action( 'init', 'wptuts_add_endpoints');

В качестве краткого примера конечные точки могут быть полезны для представлений форм. Предположим, что у нас есть страница контактной формы с контактной формой имени и с постоянной ссылкой: www.example.com свяжитесь и захотите URL-адреса:

www.example.com Успех отправки заявки - чтобы отразить успешную заявку на получение формы. www.example.com contact ошибка отправки - чтобы отразить неудачную форму представления

Это можно сделать с помощью конечных точек. Ниже приведен очень простой пример использования конечных точек, поэтому форма является невероятно простой в своих проверках (и фактически ничего не делает с данными). Обычно подобная форма лучше всего работает в подключаемом модуле, используя короткие коды, но для целей этого примера создайте страницу со следующим шаблоном и остальной частью кода, который вы можете поместить в свои функции. Php

<?php
    /**
    * Template Name: Contact Form
    */
    include('header.php');?>
    <h1> My Simple Contact Form </h1>
    <?php if ( 'success' == get_query_var( 'form' ) ): ?>
        <div class="message">
            Your message has been sent!
        </div>
    <?php elseif( 'error' == get_query_var( 'form' )): ?>
        <div class="message">
            Oops! There seems to have been an error...
        </div>
    <?php endif ?>
    <! -- Display form here -->
    <form method='post' action=''>
        <label> Your name: </label> <input type="text" name="wptuts_contact[name]" value=""/>
        <label> Your message: </label> <textarea name="wptuts_contact[message]" rows="20" cols="30"></textarea>
        <! -- Nonce field -->
        <?php wp_nonce_field('wptuts_send_message','wptuts_contact_nonce'); ?>
        <input type="hidden" name="action" value="wptuts_send_message"/>
        <! -- mmm... honey  -->
        <style scoped>.wptuts-e-mail-conformation{display:none}</style>
        <span class="wptuts-e-mail-conformation"><label for="email-confirmation">Email confirmation:</label><input type="text" name="wptuts_contact[confirmation]" value="" /></span>
        <input type='submit' name='wptuts_contact[send]' value='Send' />
    </form>
    <?php include('footer.php');?>

(В случае, если вам интересно, мед относится к этому самому основному методу улавливания спама, изложенному здесь. Это, конечно же, не доказательство дурака, но надлежащая обработка формы и защита от спама здесь не обсуждаются). Теперь мы создаем нашу конечную точку:

function wptuts_add_endpoint() {
    add_rewrite_endpoint( 'form', EP_PAGES );
}
add_action( 'init', 'wptuts_add_endpoint');

Затем мы добавляем переменную 'form' к массиву распознанных переменных:

function wptuts_add_queryvars( $query_vars ) {
    $query_vars[] = 'form';
    return $query_vars;
}
add_filter( 'query_vars', 'wptuts_add_queryvars' );

Наконец, мы предоставляем обработчик формы, который обрабатывает данные, передает форму и затем перенаправляет обратно на страницу контактов с добавленным значением конечной точки.

function wptuts_form_handler() {
    // Are we wanting to process the form
    if( ! isset( $_POST['action'] ) || 'wptuts_send_message' != $_POST['action'] )
        return;
    // ID of the contact form page
    $form_id = 2163;
    $redirect= get_permalink($form_id);
    // Check nonces
    $data = $_POST['wptuts_contact'];
    if( !isset($_POST['wptuts_contact_nonce'] ) || !wp_verify_nonce($_POST['wptuts_contact_nonce'],'wptuts_send_message') ) {
        // Failed nonce check
        $redirect .= 'form/error';
        wp_redirect($redirect);
        exit();
    }
    if( !empty( $data['confirmation'] ) ) {
        // Bees in the honey...
        $redirect .= 'form/error';
        wp_redirect($redirect);
        exit();
    }
    // Santize and validate data etc.
    // Then actually do something with the sanitized data
    // Successful!
    $redirect .= 'form/success';
    wp_redirect($redirect);
    exit();
}
add_action( 'init', 'wptuts_form_handler');

Разумеется, даже этот пример можно было бы значительно улучшить, предоставив более подробные сообщения об ошибках, которые расскажут о причине отказа.

Добавление пользовательского фида

При использовании довольно постоянных ссылок WordPress автоматически создает довольно URL-адреса для фида вашего сайта: www.example.com feed rss. Функция add_feed позволяет вам создать настраиваемый фид, который, если разрешены довольно постоянные ссылки, также будет иметь «красивый» URL-адрес. Эта функция принимает два аргумента:

feed name - имя фида, поскольку оно будет отображаться в канале [имя-фида] nfeed callback - функция, ответственная за отображение содержимого корма.

В качестве примера используется следующее: add_feed и предоставляет очень простой настраиваемый канал.

function wptuts_events_feed_callback() {
    $custom_feed = new WP_Query(array('meta_key' => 'eventdate'));
    header('Content-Type: ' . feed_content_type('rss-http') . '; charset=' . get_option('blog_charset'), true);
    echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>'; ?>
    <rss version="2.0">
    <chael>
        <title>My custom feed</title>
        <link><?php bloginfo_rss('url') ?></link>
        <description><?php bloginfo_rss("description") ?></description>
        <lastBuildDate><?php echo mysql2date('D, d M Y H:i:s +0000', get_lastpostmodified('GMT'), false); ?></lastBuildDate>
        <language><?php echo get_option('rss_language'); ?></language>
        <?php if($custom_feed->have_posts()): ?>
            <?php while( $custom_feed->have_posts()): $custom_feed->the_post(); ?>
                <item>
                    <title><?php the_title_rss() ?></title>
                    <link><?php the_permalink_rss() ?></link>
                    <pubDate><?php echo mysql2date('D, d M Y H:i:s +0000', get_post_time('Y-m-d H:i:s', true), false); ?></pubDate>
                    <guid isPermaLink="false"><?php the_guid(); ?></guid>
                    <description><![CDATA[<?php the_excerpt_rss() ?>]]></description>
                </item>
            <?php endwhile; ?>
        <?php endif; ?>
    </chael>
    </rss>
<?php
}
function wptuts_add_feed() {
    add_feed('events', 'wptuts_events_feed_callback');
}
add_action( 'init', 'wptuts_add_feed );

После промывки постоянных ссылок фид будет доступен на мероприятиях корма событий www.example.com.


Проверка правил перезаписи

После того, как вы добавили некоторые свои собственные правила перезаписи (и сбросили их), вы, вероятно, захотите проверить, работают ли они должным образом - и если они не являются, узнайте, что происходит неправильно. Для этого я настоятельно рекомендовал плагин Monkeyman Rewrite Analyzer, бесплатный плагин, доступный в репозитории WordPress. После активации этот плагин добавляет страницу в раздел «Инструменты», в котором перечислены все правила перезаписи.

Вы также можете протестировать правила, указав ему примерный URL-адрес, и плагин будет фильтровать правила, чтобы отображать только совпадающие шаблоны и указывая, как WordPress будет интерпретировать URL-адрес.

Получайте удовольствие и следите за частью 2, в ближайшее время!

Пожалуйста, обратите внимание: в нашем синтаксическом ярлыке есть ошибка, которая отображает «empty ()» как «emptyempty ()». Не забудьте настроить свой код соответствующим образом.