Динамический шаблон WordPress

в 9:16, , рубрики: javascript, php, wordpress, веб-дизайн, шаблоны, метки: , ,

При разработке одного из проектов столкнулся с необходимостью настроить вывод постов в двух вариантах:

  • Расширенный — Название, крупное изображение, анонс, некоторые ссылки
  • Компактный — Название, маленькое изображение

Динамический шаблон Wordpress

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

Общий алгоритм следующий:

  1. При загрузке страницы проверяется состояние параметра style в базе
  2. В зависимости от параметра посты выводятся в том или ином формате
  3. При нажатии на флажок переключения вида запускается функция getPage
  4. Функция getPage принимает значение переключателя и отправляет данные на обработку и ОЖИДАЕТ ЗАВЕРШЕНИЯ ОБРАБОТКИ
  5. Файл style_updater.php принимает данные и обновляет Базу данных.
  6. После этого функция getPage перезагрузит страницу


Пример, вы можете протестировать на моём сайте — game.tobefun.org (Переключатель доступен после авторизации)
Итак, как же это реализовать?

Изменение Базы данных

Чтобы выбранный стиль сохранялся для каждого пользователя, необходимо в базе данных, в таблицу wp-user добавить ещё одно поле 'style' принимающее значения 1 или 0. (По умолчанию 0).

Изменение главного цикла

В главном цикле вашего шаблона, после

<?php if ( have_posts() ) : ?>

Замените ваш цикл на следующий код

<?php $current_user = wp_get_current_user();     // Получение данных авторизованного пользователя 

if ( 1 == $current_user->style ) {               // Если в базе данных значение параметра style = 1
 while ( have_posts() ) : the_post();            // Запустить цикл
get_template_part( 'content', 'min' );           // Где каждая запись будут формироваться файлом content-min.php
endwhile; }                                      // И закончить цикл

else {	                                         // Если значение параметра style != 1
while ( have_posts() ) : the_post(); 	         // Запустить цикл
get_template_part( 'content', 'max' );           // Где каждая запись будут формироваться файлом content-max.php
endwhile; }                                      // И закончить цикл 
?>

Создание content-min.php и content-max.php

content-min.php и content-max.php формируют исключительно один пост и поскольку они стоят в цикле то запускаются многократно.
Пример:

<a href="<?php the_permalink(); ?>">
<div class="min">
<h3><?php the_title(); ?></h3>
<div class="image">
	<?php
		$thumb = get_post_thumbnail_id();                   // Получение ID изображения установленного как миниатюра
		$img_url = wp_get_attachment_url( $thumb,'full' );  // Получение ссылки на полный формат изображения
		$image = aq_resize( $img_url, 170, 120, true );     // Уменьшение изображения до размеров 170х120.
	?>
<img width="170px" height="120px" src="<?php echo $image ?>"/>
		</div></div>
</a>

Данный код будет запускаться столько раз, сколько записей нужно будет отобразить на странице.

Функция aq_resize()

Создайте в корне вашей темы файл aq_resizer.php со следующим содержанием:

aq_resizer.php

<?php

/**
* Title		: Aqua Resizer
* Description	: Resizes WordPress images on the fly
* Version	: 1.1.3
* Author	: Syamil MJ
* Author URI	: http://aquagraphite.com
* License	: WTFPL - http://sam.zoy.org/wtfpl/
* Documentation	: https://github.com/sy4mil/Aqua-Resizer/
*
* @param string $url - (required) must be uploaded using wp media uploader
* @param int $width - (required)
* @param int $height - (optional)
* @param bool $crop - (optional) default to soft crop
* @param bool $single - (optional) returns an array if false
* @uses wp_upload_dir()
* @uses image_resize_dimensions()
* @uses image_resize()
*
* @return str|array
*/

function aq_resize( $url, $width, $height = null, $crop = null, $single = true ) {
	
	//validate inputs
	if(!$url OR !$width ) return false;
	
	//define upload path & dir
	$upload_info = wp_upload_dir();
	$upload_dir = $upload_info['basedir'];
	$upload_url = $upload_info['baseurl'];
	
	//check if $img_url is local
	if(strpos( $url, home_url() ) === false) return false;
	
	//define path of image
	$rel_path = str_replace( $upload_url, '', $url);
	$img_path = $upload_dir . $rel_path;
	
	//check if img path exists, and is an image indeed
	if( !file_exists($img_path) OR !getimagesize($img_path) ) return false;
	
	//get image info
	$info = pathinfo($img_path);
	$ext = $info['extension'];
	list($orig_w,$orig_h) = getimagesize($img_path);
	
	//get image size after cropping
	$dims = image_resize_dimensions($orig_w, $orig_h, $width, $height, $crop);
	$dst_w = $dims[4];
	$dst_h = $dims[5];
	
	//use this to check if cropped image already exists, so we can return that instead
	$suffix = "{$dst_w}x{$dst_h}";
	$dst_rel_path = str_replace( '.'.$ext, '', $rel_path);
	$destfilename = "{$upload_dir}{$dst_rel_path}-{$suffix}.{$ext}";
	
	//if orig size is smaller
	if($width >= $orig_w) {
		
		if(!$dst_h) :
			//can't resize, so return original url
			$img_url = $url;
			$dst_w = $orig_w;
			$dst_h = $orig_h;
			
		else :
			//else check if cache exists
			if(file_exists($destfilename) && getimagesize($destfilename)) {
				$img_url = "{$upload_url}{$dst_rel_path}-{$suffix}.{$ext}";
			} 
			//else resize and return the new resized image url
			else {
				$resized_img_path = image_resize( $img_path, $width, $height, $crop );
				$resized_rel_path = str_replace( $upload_dir, '', $resized_img_path);
				$img_url = $upload_url . $resized_rel_path;
			}
			
		endif;
		
	}
	//else check if cache exists
	elseif(file_exists($destfilename) && getimagesize($destfilename)) {
		$img_url = "{$upload_url}{$dst_rel_path}-{$suffix}.{$ext}";
	} 
	//else, we resize the image and return the new resized image url
	else {
		$resized_img_path = image_resize( $img_path, $width, $height, $crop );
		$resized_rel_path = str_replace( $upload_dir, '', $resized_img_path);
		$img_url = $upload_url . $resized_rel_path;
	}
	
	//return the output
	if($single) {
		//str return
		$image = $img_url;
	} else {
		//array return
		$image = array (
			0 => $img_url,
			1 => $dst_w,
			2 => $dst_h
		);
	}
	
	return $image;
}

Затем в function.php добавьте

include ( 'aq_resizer.php' );

Изменение количества записей

Для того чтобы в одном из вариантов выводилось большее количество записей на странице, необходимо в function.php добавить

function change_posts_per_page( $query ) {
 $current_user = wp_get_current_user();                     // Получение данных пользователя

    if ( is_admin() || ! $query->is_main_query() )          // изменять не в админке и только главный запрос
        return;
if ( 1 == $current_user->style ) {                          // Если в базе данных значение параметра style = 1
        $query->set( 'posts_per_page', 30 );                // Выводить по 30 постов на страничке 
        return;
	}
  else {                                                    // Если в базе данных значение параметра style != 1
        $query->set( 'posts_per_page', 5 );                 // Выводить по 5 постов на страничке 
        return;
    }
}
add_action( 'pre_get_posts', 'change_posts_per_page', 1 );

Переключатель вида

Создаём на панели пользователя переключатель

<input type="checkbox" 
<?php if ( 1 == $current_user->style ) print 'checked';?>    // Проверяем состояние переключателя
 onchange="getPage(this)">                                   // Создаём событие

Дальше в шапке нашего сайта создаём обработчик события

<script type="text/javascript">
function getPage(obj) { 

var style_statys = 0;
if(obj.checked == true) {
	style_statys = 1;
} else {
 style_statys = 0; }
		$.post(
			"style_updater.php",                     // Файл который должен обработать данные отправленные методом POST
			{
				style: style_statys,                 // Первый параметр. $_POST[style]
				ID: <?php print $current_user->ID; ?>// Второй параметр. $_POST[ID] которому присваивается значение авторизованного пользователя
			},
			onAjaxSuccess                            // При успешной передаче запустить функцию onAjaxSuccess
		);
	}
	function onAjaxSuccess(_html) 	{
	 location.reload();                              // Которая обновит нашу страницу
	}
// -->
</script>
style_updater.php

<?php 
include '../../../wp-config.php';						// Подключаем wp-config.php
$link = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD); 	// Подключаемся к Серверу
mysql_select_db(DB_NAME, $link);						// Выбираем и подключаем базу данных
$query = 'UPDATE `wp_users` SET `style`='.$_POST['style'].' WHERE `ID`='.$_POST['ID']; // Формируем SQL команду	
mysql_query($query, $link);			 					// Выполняем SQL команду
mysql_close($link);				// Закрываем соединение с сервером
?> 

Автор: Kozack

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js