Pull to refresh

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

Reading time5 min
Views15K
При разработке одного из проектов столкнулся с необходимостью настроить вывод постов в двух вариантах:
  • Расширенный — Название, крупное изображение, анонс, некоторые ссылки
  • Компактный — Название, маленькое изображение



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

Общий алгоритм следующий:
  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" src="style_updater.js"></script>


Содержание style_updater.js

function getPage(obj) { 
$('#content').html('<h1 class="loader">Загрузка</h1>');

var numPage = 0;
if(obj.checked == true) {
	numPage = 1;
} else {
 numPage = 0; }
		$.post(
			"style_updater.php",
			{
				style: numPage,
			},
			onAjaxSuccess
		);
	}
	function onAjaxSuccess(_html) 	{
	// $("#content").html(_html);
	 location.reload();

	}


style_updater.php

<?php 
try {  

if ( ($_POST['style']==1) || ($_POST['style']==0)) { $style = $_POST['style']; }
else return;

include '../../../wp-config.php';												// Подключаем wp-config.php
include '../../../wp-includes/pluggable.php';									// Подключаем pluggable.php
$current_user = wp_get_current_user(); 
$ID = $current_user->ID;

$db = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME, DB_USER, DB_PASSWORD);  // Подключаемся к Серверу
    
$STH = $db->prepare("UPDATE `wp_users` SET `style`=? WHERE `ID`=?");			// Формируем SQL команду
$STH->execute(array($style, $ID));												// Выполняем SQL команду	
$db = null;																		// Закрываем соединение с сервером
}  
catch(PDOException $e) {  
    echo "Хьюстон, у нас проблемы.";  
    file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);  
}
?>
Tags:
Hubs:
Total votes 17: ↑8 and ↓9-1
Comments18

Articles