Статьи

Несколько шорткодов с одной функцией: 3 примера убийцы

Мощный API-интерфейс Shortcode позволяет нам создавать «фрагменты» и включать в наши сообщения специальный контент (например, функции PHP или сложный HTML-код). Чрезвычайно распространено создание отдельных функций для каждого шорткода, но действительно ли это необходимо? В этом посте мы увидим, как мы можем использовать более одного шорткода, создав одну функцию.


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

Среди этих API мой любимый API-интерфейс Shortcode. Его логика и обоснованность ставятся под сомнение, но я твердо верю, что использование коротких кодов в WordPress имеет простую кривую обучения, и как только они изучат эти несколько простых правил о параметрах и открывающих / закрывающих тегах, даже начинающие пользователи могут пользоваться короткими кодами. Правильно, это не WYSIWYG, но новичку WordPress может быть труднее очистить беспорядок, если они сделали что-то не так в редакторе WYSIWYG и испортили HTML. Проще увидеть, что шорткод не работает, удалите его и введите его снова.

Но, конечно, это просто мое мнение. Давайте вернемся к теме: мы создаем несколько шорткодов с помощью одной функции!


На самом деле не нужно спорить о пользе этого метода — рассмотрим этот смехотворно длинный пример:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
<?php
function one_half_sc( $atts, $content = null, $tag ) {
    extract( shortcode_atts( array(
        // extra classes
        ‘class’ => »,
        ‘last’ => »
    ), $atts ) );
    if ( $class != » )
        $class = ‘ ‘ .
    if ( $last = ‘yes’ )
        $last_class = ‘ last’;
    return ‘<div class=»one_half’ . $last_class . $class . ‘»>’ .
}
add_shortcode( ‘one_half’, ‘one_half_sc’ );
  
function one_third_sc( $atts, $content = null, $tag ) {
    extract( shortcode_atts( array(
        // extra classes
        ‘class’ => »,
        ‘last’ => »
    ), $atts ) );
    if ( $class != » )
        $class = ‘ ‘ .
    if ( $last = ‘yes’ )
        $last_class = ‘ last’;
    return ‘<div class=»one_third’ . $last_class . $class . ‘»>’ .
}
add_shortcode( ‘one_third’, ‘one_third_sc’ );
  
function one_quarter_sc( $atts, $content = null, $tag ) {
    extract( shortcode_atts( array(
        // extra classes
        ‘class’ => »,
        ‘last’ => »
    ), $atts ) );
    if ( $class != » )
        $class = ‘ ‘ .
    if ( $last = ‘yes’ )
        $last_class = ‘ last’;
    return ‘<div class=»one_quarter’ . $last_class . $class . ‘»>’ .
}
add_shortcode( ‘one_quarter’, ‘one_quarter_sc’ );
  
function two_thirds_sc( $atts, $content = null, $tag ) {
    extract( shortcode_atts( array(
        // extra classes
        ‘class’ => »,
        ‘last’ => »
    ), $atts ) );
    if( $class != » )
        $class = ‘ ‘ .
    if( $last = ‘yes’ )
        $last_class = ‘ last’;
    return ‘<div class=»two_thirds’ . $last_class . $class . ‘»>’ .
}
add_shortcode( ‘two_thirds’, ‘two_thirds_sc’ );
  
function three_quarters_sc( $atts, $content = null, $tag ) {
    extract( shortcode_atts( array(
        // extra classes
        ‘class’ => »,
        ‘last’ => »
    ), $atts ) );
    if ( $class != » )
        $class = ‘ ‘ .
    if ( $last = ‘yes’ )
        $last_class = ‘ last’;
    return ‘<div class=»three_quarters’ . $last_class . $class . ‘»>’ .
}
add_shortcode( ‘three_quarters’, ‘three_quarters_sc’ );
?>

Один и тот же код (как PHP, так и HTML) используется снова и снова в каждой отдельной функции — за исключением различных классов CSS. Кроме того, атрибуты в каждой функции такие же, как и в других функциях. Это просто трудно читать. Если подумать, если бы нам когда-нибудь пришлось изменить особенность этих столбцов div , нам бы пришлось изменить одинаковые части во всех функциях.

Что если существует переменная для извлечения «тега» шорткода? Не удивительно, что переменная называется $tag и может использоваться внутри наших функций. Это позволяет нашим функциям проверять тег шорткода и вести себя в соответствии с тегом.

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

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


В одной из моих первых публикаций на Wptuts + я объяснил, как использовать шорткод для встраивания видео от различных видеохостов, таких как YouTube, Vimeo и Dailymotion. Код выглядел так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
function vid_sc( $atts, $content = null ) {
    extract(
        shortcode_atts( array(
            ‘site’ => ‘youtube’,
            ‘id’ => »,
            ‘w’ => ‘600’,
            ‘h’ => ‘370’
        ), $atts )
    );
    if ( $site == «youtube» ) { $src = ‘http://www.youtube-nocookie.com/embed/’ .
    else if ( $site == «vimeo» ) { $src = ‘http://player.vimeo.com/video/’ .
    else if ( $site == «dailymotion» ) { $src = ‘http://www.dailymotion.com/embed/video/’ .
    else if ( $site == «yahoo» ) { $src = ‘http://d.yimg.com/nl/vyc/site/player.html#vid=’ .
    else if ( $site == «bliptv» ) { $src = ‘http://a.blip.tv/scripts/shoggplayer.html#file=http://blip.tv/rss/flash/’ .
    else if ( $site == «veoh» ) { $src = ‘http://www.veoh.com/static/swf/veoh/SPL.swf?videoAutoPlay=0&permalinkId=’ .
    else if ( $site == «viddler» ) { $src = ‘http://www.viddler.com/simple/’ .
    if ( $id != » ) {
        return ‘<iframe width=»‘ . $w . ‘» height=»‘ . $h . ‘» src=»‘ . $src . ‘» class=»vid iframe-‘ . $site . ‘»></iframe>’;
    }
}
add_shortcode( ‘vid’, ‘vid_sc’ );
?>

Хотя это все еще неплохая практика (за исключением 6 операторов else if ), теперь мы можем использовать на один атрибут меньше (‘ site ‘) и создавать отдельные шорткоды, например:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php
// Video embed shortcodes
function wptuts_embed_sc( $atts, $content = null, $tag ) {
    extract( shortcode_atts( array(
        ‘id’ => »,
        ‘w’ => ‘600’,
        ‘h’ => ‘370’
    ), $atts ) );
    switch( $tag ) {
        case «youtube»:
            $src = ‘http://www.youtube-nocookie.com/embed/’;
            break;
        case «vimeo»:
            $src = ‘http://player.vimeo.com/video/’;
            break;
        case «viddler»:
            $src = ‘http://www.viddler.com/simple/’;
            break;
        case «dailymotion»:
            $src = ‘http://www.dailymotion.com/embed/video/’;
            break;
    }
    if ( $id != » )
        return ‘<iframe width=»‘ . $w . ‘» height=»‘ . $h . ‘» src=»‘ . $src . $id . ‘» class=»iframevideo»></iframe>’;
    return;
}
add_shortcode( ‘youtube’, ‘wptuts_embed_sc’ );
add_shortcode( ‘vimeo’, ‘wptuts_embed_sc’ );
add_shortcode( ‘viddler’, ‘wptuts_embed_sc’ );
add_shortcode( ‘dailymotion’, ‘wptuts_embed_sc’ );
?>

Видишь, что мы сделали? Мы предоставили параметр $tag для нашей функции в первой строке (для замены атрибута » site «) и использовали условный оператор switch (для лучшего, более чистого кода). Результат для двух функций будет одинаковым, за исключением того, что теперь вы можете использовать [youtube id="..."] вместо [vid site="youtube" id="..."] .

(Я не использовал некоторые видеохосты во второй функции. Если вам нужно добавить больше хостов, вы можете добавить столько « case », сколько захотите.)


Ах, столбцы … это самая важная часть CSS-сетки, и они позволяют очень легко сделать ваш сайт более адаптивным, если они поддерживают адаптивные методы проектирования. Вы можете увидеть их почти в каждой теме WordPress на ThemeForest, и они используют шорткоды … с практикой, подобной нашему «смехотворно длинному примеру» в начале этого урока.

Как вы помните, код был практически одинаковым во всех 5 функциях в этом примере. Таким образом, было бы невероятно легко объединить их в одну функцию и позволить переменной $tag творить чудеса:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
// Column shortcodes
function wptuts_columns_sc( $atts, $content = null, $tag ) {
    extract( shortcode_atts( array(
        // extra classes
        ‘class’ => »
    ), $atts ) );
    if ( $class != » )
        $class = ‘ ‘ .
    $last = »;
    // check the shortcode tag to add a «last» class
    if ( strpos( $tag, ‘_last’ ) !== false )
        $tag = str_replace( ‘_last’, ‘ last’, $tag);
    $output = ‘<div class=»‘ . $tag . $last . $class . ‘»>’ .
    return $output;
}
add_shortcode( ‘one_half’, ‘wptuts_columns_sc’ );
add_shortcode( ‘one_half_last’, ‘wptuts_columns_sc’ );
add_shortcode( ‘one_third’, ‘wptuts_columns_sc’ );
add_shortcode( ‘one_third_last’, ‘wptuts_columns_sc’ );
add_shortcode( ‘one_quarter’, ‘wptuts_columns_sc’ );
add_shortcode( ‘one_quarter_last’, ‘wptuts_columns_sc’ );
add_shortcode( ‘two_thirds’, ‘wptuts_columns_sc’ );
add_shortcode( ‘two_thirds_last’, ‘wptuts_columns_sc’ );
add_shortcode( ‘three_quarters’, ‘wptuts_columns_sc’ );
add_shortcode( ‘three_quarters_last’, ‘wptuts_columns_sc’ );
?>

Довольно аккуратно, правда? Нам даже не нужно было использовать switch !

Мы по-прежнему дублируем строки при добавлении шорткодов. Смеете пойти еще дальше? Удалите add_shortcode() чтобы заменить на это:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
<?php
$tags = array(
    ‘one_half’,
    ‘one_half_last’,
    ‘one_third’,
    ‘one_third_last’,
    ‘one_quarter’,
    ‘one_quarter_last’,
    ‘two_thirds’,
    ‘two_thirds_last’,
    ‘three_quarters’,
    ‘three_quarters_last’,
);
foreach( $tags as $tag ) {
    add_shortcode( $tag, ‘wptuts_columns_sc’ );
}
?>

Теперь у нас есть еще более удобный код. Например; если бы мы изменили имя функции, мы бы не стали больше менять каждую строку.


Вам когда-нибудь приходилось перечислять несколько предыдущих (или будущих) статей в ваших сообщениях? Я конечно делаю. Существует множество плагинов, которые предоставляют шорткоды, но большинство из них требуют от вас использования множества атрибутов, которые могут привести к некоторому уродливому, сложному тегу, например [posts cat="5,6" author="barisunver" status="private" postsperpage="4" and="so on"] .

Как насчет того, чтобы вместо этого использовать наш любимый $tag ? Давайте попробуем:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?php
// Post list shortcodes
function wptuts_post_lists_sc( $atts, $content = null, $tag ) {
    global $post;
    $post_ID = $post->ID;
    $post_author = $post->post_author;
    extract( shortcode_atts( array(
        ‘number’ => 5,
        ‘exclude_current’ => ‘yes’,
        ‘orderby’ => ‘date’
    ), $atts ) );
    $args = »;
    switch( $tag ) {
        case «latest_posts»:
            // we don’t need any arguments to retrieve latest posts 🙂
            break;
        case «category_posts»:
            $categories = get_the_category( $post_ID );
            $first_category = $categories[0]->term_id;
            $args = ‘cat=’ .
            break;
        case «author_posts»:
            $args = ‘author=’ .
            break;
        case «future_posts»:
            $args = ‘post_status=future’;
            break;
    }
    $not_in = ‘&post__not_in[]=’ .
    if ( $exclude_current == ‘no’ )
        $not_in = »;
    $get_posts = get_posts( $args . $not_in . ‘&posts_per_page=’ . $number . ‘&orderby=’ . $orderby );
    $output = ‘<ul class=»‘ . $tag . ‘»>’;
    foreach ( $get_posts as $post ) {
        $output .= ‘<li><a href=»‘ . get_permalink() . ‘» title=»‘ . esc_attr( get_the_title() ) . ‘»>’ .
    }
    $output .= ‘</ul>’;
    wp_reset_query();
    return $output;
}
add_shortcode( ‘latest_posts’, ‘wptuts_post_lists_sc’ );
add_shortcode( ‘category_posts’, ‘wptuts_post_lists_sc’ );
add_shortcode( ‘author_posts’, ‘wptuts_post_lists_sc’ );
add_shortcode( ‘future_posts’, ‘wptuts_post_lists_sc’ );
?>

Как видите, мы можем избавиться от 3-х возможных атрибутов шорткода: « cat », « author » и « post_status ». Вы всегда можете расширить case s и добавить новые шорткоды с помощью этой единственной, относительно небольшой функции.


Как фанат шорткодов WordPress, это открытие переменной $tag для меня довольно волнительно. Кажется, что есть огромный потенциал для использования этого метода.

Что вы думаете об этой технике? Оставьте свои комментарии ниже и поделитесь своими мыслями с нами!