Шорткоды, часть 3. Вложенные шорткоды в WordPress

Shortcodes API третья часть.Вложенные шорткоды.

Понравилась статья? Оставьте оценку:

  1. 5
  2. 4
  3. 3
  4. 2
  5. 1
(0 голосов, в среднем: 0 из 5)

Это заключительная статья о шорткодах в вордпрессе, и естественно, под конец я припас кое-что интересное. Сегодня будем запиливать вложенный шорткод, вернее шорткоды. А именно — создадим табы, которые можно будет использовать прямо в записи.

Рассмотрим структуру табов. Шорткодом первого уровня будет [my_tabs], который выведет собственно обертку для наших вкладок. Внутри него будет вложен шорткод [my_tab] с помощью которого мы будем выводить каждую отдельную вкладку. Во вложенном шорткоде будет параметр title для заголовка таба и content — содержимое таба. Пример:

Листинг 1

[my_tabs]
[my_tab title="Первый таб"]Текст первого таба.[/my_tab]
[my_tab title="Второй таб"]Текст второго таба.[/my_tab]
[my_tab title="Третий таб"]Текст третьего таба.[/my_tab]
[/my_tabs]

Так, структура ясна, теперь нам нужны две функции-шорткода для отображения разметки табов. Кстати, заранее продумаем какую разметку необходимо вывести:

Листинг 2

<ul class="tabs">
	<li><a href="#tab-1" class="active">Первый таб</a></li>
	<li><a href="#tab-2">Второй таб</a></li>
	<li><a href="#tab-3">Третий таб</a></li>
</ul>
<section id="tab-1" class="tab active">Текст первого таба.</section>
<section id="tab-2" class="tab">Текст второго таба.</section>
<section id="tab-3" class="tab">Текст третьего таба.</section>

Такую разметку будут выдавать наши вложенные шорткоды. Приступим. Для удобства оформим наш функционал в виде класса, а затем подключим его в файле functions.php. Так будет гораздо читабельнее, чем если бы мы весь код громоздили в этот functions.php. В папке с темой рядом с functions.php создадим папку tabs.

Ниже я приведу листинг класса Tabs с комментариями. (его нужно будет положить в папочку tabs) Все достаточно понятно, кроме одного момента — заголовки табов будем не выводить сразу в шорткоде-табе (это невозможно), а соберем в массив и выведем целиком в шорткоде-обертке.

Листинг 3

<?php

if (!class_exists('Tabs_Shortcodes')) :

class Tabs_Shortcodes {

	private $tab_titles;
	
	function __construct() {

		add_shortcode('my_tabs', array($this, 'my_tabs_shortcode'));
		add_shortcode('my_tab', array($this, 'my_tab_shortcode'));

  }
	
	# шорткод-обертка
	function my_tabs_shortcode($atts, $content = null) {

		# создадим пустой массив для заголовков табов
		$this->tab_titles = array();
		
		extract(shortcode_atts(array(
			'open' => ''
		), $atts, 'my_tabs'));
		

		# выполним вложенный шорткод-таб
		$tab_content = do_shortcode($content);
		
		# Список навигации с заголовками табов
		$out = '<ul id="tabs" class="tabs">';
		
		# В цикле переберем массив с заголовками табов и выведем навигацию
		foreach ($this->tab_titles as $key => $title) {
			$id = $key + 1;
			$out .= sprintf('<li><a href="#%s"%s>%s</a></li>',
				'tab-' . $id,
				$id == 1 ? ' class="active"' : '',
				$title
			);
		}
		
		# Закроем список заголовков и выведем содержимое вкладок
		$out .= '</ul>';
		$out .= $tab_content;
		
		return $out;
	
	}
	
	# Шорткод для вкладки
	function my_tab_shortcode($atts, $content = null) {

	  $title = '';

		extract(shortcode_atts(array(
			'title' => ''
		), $atts, 'my_tab'));
		
		# Добавим в массив с заголовками табов заголовок этого таба
		array_push($this->tab_titles, $title);
		
		$id = count($this->tab_titles);
		
		return sprintf('<section id="%s" class="tab%s">%s</section>',
			'tab-' . $id,
			$id == 1 ? ' active' : '',
			do_shortcode($content)
		);
	
	}

}

$Tabs_Shortcodes = new Tabs_Shortcodes;

endif;

Теперь подключим наш класс в functions.php

Листинг 4

require_once('tabs/tabs-shortcodes.php');

И, в принципе, можно попробовать работоспособность шорткодов (вставьте в запись самую первую структуру Листинг 1). Шорткод уже выведет разметку для наших табов, с заголовками и контентом. Остается лишь добавить css и js код для переключения.

Листинг 5. (tabs.js:)

(function() {
	'use strict';
	
	var tabs = document.querySelectorAll('ul.tabs li a'),
		tabNumber = parseInt(tabsShortcodesSettings.open),
		num;
	
	// Set the tab number based on URL hash 'tab-#'
	if (window.location.hash) {
		tabNumber = window.location.hash.match(/\d+$/);
	}
	
	// Hide active tab
	function hideActive() {
		document.querySelector('ul.tabs a.active').removeAttribute('class');
		document.querySelector('section.tab.active').className = 'tab';
	}
	
	// Select tab
	function selectTab(ele) {
		ele.className = 'active';
	}
	
	// Select tab content
	function selectContent(selector) {
		document.querySelector(selector).className = 'tab active';
	}
	
	// Set active tab based on tab number (URL hash or shortcode parameter)
	if (tabNumber) {
		// Tab number is 0 based
		num = tabNumber - 1;
		
		// Activate the tab if it exists
		if (tabs[num]) {
			hideActive();
			
			selectTab(tabs[num]);
			
			if (window.location.hash) {
				selectContent(window.location.hash);
			}
			else {
				selectContent('#tab-' + tabNumber);
			}
		}
	}
	
	// Add event handler
	document.getElementById('tabs').onclick = function(event) {
		event.preventDefault();
		
		if (event.target.tagName.toLowerCase() === 'a') {
			hideActive();
			
			// Set new active tab
			selectTab(event.target);
			selectContent(event.target.getAttribute('href'));
		}
	};

}());

Листинг 6. tabs.css:

#tabs{
  list-style: none;
  padding: 0;
  margin: 0;
}
#tabs li{
  display: inline-block;
}
#tabs li a{
  text-decoration: none;
}
#tabs li a.active{
  text-decoration: underline;
}
.tab{
  display: none;

}
.tab.active{
  display: block;
}

Таким образом получим простенькие, но работоспособные табки, которые вы можете допилить как вам вздумается. Ниже вы можете скачать исходники табок:

Исходники табок

Оставить комментарий