Cut в стиле livejournal в блоге WordPress

В WordPress откровенно не хватает ката в стиле ЖЖ, собственно кат-то там есть, но он монументален, как египетская пирамида и неумолим, как топор палача.
Тег <!--more--> можно использовать лишь один раз в посту, и все что после него уходит в подкат.


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

Удивительно, что никто эту ситуацию до сей поры не исправил, ни разработчики, ни авторы многочисленных плагинов. Конечно, попадались всякие статьи и исходники на тему «как сделать спойлер», но это были не устраивающие меня решения на javascript или ухищрения с CSS. И одно и другое плохо, во-первых, зависимостью от конкретного браузера, а во-вторых, тем, что зря занимает канал клиента, т.к. крупная картинка под спойлером или куча текста все равно будет загружена в клиентский браузер.

Итак, необходим следующий функционал:
1. Кат в стиле живого журнала, поддерживающий изменение текста ссылки на содержимое под катом, с возможностью использоваться несколько раз в одном посту для скрытия определенных его фрагментов.
2. Сделано это должно быть без javascript и CSS.

Как устроен кат в ЖЖ.

На главной странице блога область текста, находящаяся между тегами <lj-cut> и </lj-cut> заменяется на ссылку вида http://blog.livejournal.com/1234567.html#cutid1 со стандартным текстом Read more… или текстом, заданным пользователем. Где
1234567.html — страница, содержащая полный текст поста
cutid1 — якорь [4], указывающий на начало скрываемого текста на странице поста.
Правда, в такой реализации тоже есть один минус — имена якорей генерируются автоматически, в зависимости от количества участков, скрытых под катом в посту (cutid1, cutid2... cutidN).

Ну ладно, писать, так писать, подумал я и решил добавить возможность задавать осмысленные имена якорей, например, #code, #function, #ioann_grozny_killing_son_2666_x_6666 и т.д.

Как сделать в WordPress кат в стиле Живого Журнала?

Тут на помощь придут шорткоды [1]. Можно написать плагин, реализующий такой функционал и добавляющий шорткод [lj-cut]] [[/lj-cut]

Создаем «болванку» плагина

В директории wp-content создаем поддиректорию lj-cut, а в ней файл lj-cut.php со следующим содержимым:

<?php

/*
Plugin Name: LJ-cut style cut
Description: Add Livejournal-like Cut Shortcode 
*/


function ljcut_shortcode($atts, $content=null)
{			
	
}

add_shortcode ('lj-cut','ljcut_shortcode');

?>


Информация в комментариях после Plugin Name: и Description: будет отображена в админ-панели в разделе плагинов. Plugin Name: и информация далее должна быть указана обязательно.
Функция ljcut_shortcode($atts, $content=null) обрабатывает шорткод, ей передаются движком массив с параметрами $atts и содержимое между открывающим и закрывающим тегом $content
Функция add_shortcode добавляет шорткод с указанным именем (1 параметр) и устанавливает функцию его обрабатывающую (2 параметр).

Описание и алгоритм.

Функция обработки шорткода будет вызвана каждый раз, как будет встречена в посту. Ей будут переданы параметры из массива $atts, указанные в тексте как [shortcodename param1="value1", param2="value2"].

1. Заведем 2 статических переменных:
static $cutid=0; //номер текущего cutid в посту
static $oldplink=''; //предыдущий permalink
Первая будет хранить номер текущего cutid в посту, а вторая сохранять предыдущую постоянную ссылку на пост. Переменные обязательно должны быть объявлены при помощи ключевого слова static, иначе их значения будут сброшены при каждом вызове функции.

2. Вытащим из массива $atts параметры и запишем их в соответствующие переменные. Если параметр не будет определен, то ему будет присвоено значение, указанное в кавычках после =>

extract(shortcode_atts(array(
	      'text' => 'Read more...',
	      'unicancor' => '',
	), $atts));


4. Получим URL поста, откуда была вызвана функция обработки шорткода, используя внутреннюю функцию WordPress get_permalink() [2]:
5. $plink=get_permalink(); //получаем URL текущего поста
6. Получим URL текущей страницы:
$clink=get_bloginfo('url').$_SERVER["REQUEST_URI"]; //URL текущей страницы
Функция get_bloginfo('url') получит адрес блога [3], а в элементе REQUEST_URI массива $_SERVER будет находиться значение вида /blog/post.html если пользователь читает пост на странице поста и значения вида /page/2/ (/author/tolik-punkoff/, /tag/it/), если пост читают с какой-то из страниц сайта. В первом случае необходимо показывать весь текст, во втором — заменять скрытую под катом часть на соответствующую ссылку.
7. Далее необходимо проверить, какой раз функция обработки шорткода ката вызывается из поста. Делается это путем сравнения заранее сохраненной постоянной ссылки на пост и только что полученной.
Если ранее сохраненная ссылка не такая же, как и полученная во время вызова функции, значит, мы начали обрабатывать новый пост. В таком случае отсчет текущих фрагментов, скрытых под катом, необходимо начать заново, а постоянную ссылку на новый пост сохранить в соответствующей переменной. Иначе функция была очередной раз вызвана из текущего поста, соответственно, нужно просто увеличить счетчик фрагментов под катом:

	if ($oldplink!=$plink) //пост новый, надо начать отсчет cutid заново (с 1)
	{
		$cutid=1;
		$oldplink=$plink; //и сохранить текущий 
	}
	else //мы все еще обрабатываем старый пост
	{
		$cutid++; //прибавляем значение cutid
	} 


8. Далее необходимо сравнить постоянную ссылку на пост (premalink) со ссылкой на той странице, на которой находится пользователь и если пользователь на странице поста — установить якорь [4] и вывести контент, скрытый под катом. Если пользователь на одной из страниц блога со списком постов, то выводится ссылка на пост, дополняемая указателем на якорь (http://tolik-punkoff.com/tag/it/post#ancor).
Если имя якоря задано пользователем в соответствующем параметре шорткода, то оно и используется, иначе, якорь принимает вид cutidN, где N — заранее посчитанный в переменной $cutidномер.

if ($plink==$clink)
	{
		//мы в теле поста, cut надо раскрыть и вставить якорь
		if ($unicancor=='') //если якорь не задан, используем cutidn
		{
			$ret='<a name="cutid' . $cutid . '"></a> ' .$content;
		}
		else
		{
			$ret='<a name="' . $unicancor . '"></a> ' .$content;
		}
	}
	else
	{
		//мы на одной из страниц, но не в самом посту
		//надо установить ссылку на пост и на нужный якорь в посту
		if ($unicancor=='') //если якорь не задан, используем cutidn
		{
			$ret='<a class="more-link" ' . 'href="' . $plink . '#cutid' . $cutid .
			 '">' . $text . '</a>';
		}
		else
		{
			$ret='<a class="more-link" ' . 'href="' . $plink . '#' . $unicancor .
			 '">' . $text . '</a>';
		}
	}


Сохраняем сгенерированный HTML-код в переменной $ret
9. Возвращаем сгенерированный код и завершаем функцию обработки шорткода:
return $ret;

Скачать плагин

С Pastebin
С Mega.nz
Страничка плагина на сайте HexProject
Страничка плагина на GitHub
Скачать с tolik-punkoff.com

Используемые источники

1. Шорткоды в WordPress
2. get_permalink()
3. get_bloginfo()
4. Якорь (HTML)

12 Responses to Cut в стиле livejournal в блоге WordPress

  1. Pingback: Страница со списком тегов (или рубрик) WordPress | Персональный блог Толика Панкова

  2. Классно сделано! Подскажи пожалуйста, а можно дополнить плагин функцией, чтобы при нажатии на «Read more…», текст разворачивался на главной странице как в ЖЖ?

    • Це надо уже JavaScript применять, а я не сторонник перегружать страницу скриптами без надобности. Впрочем, именно что JS-спойлеров для вордпресса просто неиллюзорное количество, когда мне было надо, я как раз хотел кат, а не спойлер.

          • И всё же спойлер — не то :)) Он не разворачивает текст, когда заходишь в пост по ссылке поста, а оставляет его в спойлере. Т.е. это не кат, а именно спойлер.. придётся всё таки искать решение как разворачивать кат на главной странице.. Буду искать дальше. Странно, что никто этой темой до сих пор не озаботился.

            • Так переделай спойлер, чтоб он еще и смотрел, откуда ссылка открывается. В JS есть полный доступ к DOM, вот оттуда и думай. Возьми саойлер и переделай (или изложи что ты хочешь, чтоб он родил, будет время — помогу).

              • Я не программист, не знаю как это сделать. Моих знаний хватило, чтобы создать сайт на css в wordpress, установить плагины, настроить и т.д., и в принципе мне больше ничего не нужно. Остались разные мелочи типа того, чтобы разворачивать посты на главной. Но как это сделать — я даже близко не представляю. Хотя, я нашел описание на англ. вот здесь: https://rudrastyh.com/wordpress/load-more-posts-ajax.html

                Если сможешь, что-то подсказать или помочь — буду должен :))
                Если говорить подробнее о том, что хотелось бы сделать — хотелось бы, чтобы тег «Далее» разворачивал пост на главной странице, при нажатии мышкой на тег «Читать дальше..», а не уводил пользователя в пост. При этом, если открыть пост по ссылке, то чтобы текст был виден полностью, а не как в спойлере в свёрнутом виде. В жж именно так работает тег «Далее».

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

  3. Pingback: Изменение внешнего вида ссылки cut’а в WordPress | Персональный блог Толика Панкова

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*