Создание страницы настроек для WordPress-темы

Создание страницы настроек для WordPress-темы

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

Шаг 1. Выясняем, какие настройки нам необходимы.

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

Еще один вопрос, который нужно иметь в виду: «Кто будет изменять данные настройки?» Если пользователь знаком с WordPress и PHP, то разумно было бы ожидать, что он сможет самостоятельно внедрить код Google Analytics в тему, но вы не должны требовать этого от графического дизайнера, не говоря уже об авторах, которым не нужно знать ни HTML, ни CSS.

Общие идеи для компонентов, которые нужно вынести в настройки темы, включают в себя:

  • Код отслеживания Google Analytics
  • Число сайдбаров и их расположение (слева, справа, может даже вверху и внизу)
  • Ширина страниц
  • Контент в футере
  • Опции для возможностей, которые являются специфичными для темы, такие как, к примеру, форматы тизеров.

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

Настройки, создаваемые в данном руководстве

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

В редакторе элементы главной страницы будут представляться в виде списка, к которому можно добавлять новые пункты с помощью Javascript и Jquery.

Мне нравится иметь предварительный просмотр страницы администратора в консоли WordPress, когда я пишу HTML, поэтому я обычно начинаю с того, что привязываю страницу настроек к WordPress, и затем только перехожу к разработке контента страницы. Именно поэтому нашим следующим шагом будет создание пустой страницы настроек и подцепление ее к WordPress.

Шаг 2. Подцепление страницы настроек к WordPress.

Создание страницы настроек начинается с написания функции, которая устанавливает меню и подцепляет его к действию admin_menu. Это говорит WordPress о том, что нужно вызвать функцию при создании меню, чтобы все было завершено в соответствующее время. Добавьте следующий код к файлу functions.php вашей темы:

function setup_theme_admin_menus() {
    // Мы напишем контент функции очень скоро.
}  

// Она говорит WP, что нужно вызвать функцию "setup_theme_admin_menus"
// когда нужно будет создать страницы меню.
add_action("admin_menu", "setup_theme_admin_menus"); 

Теперь мы поместим код для создания страницы настроек в функцию, которую мы только что написали:

При создании страницы настроек у вас есть выбор – либо добавлять страницу в виде подменю к одной из существующих групп настроек, либо создавать свое собственное меню верхнего уровня.

Добавление подменю производится с помощью функции add_submenu_page:

<?php add_submenu_page($parent_slug, $page_title, $menu_title, $capability, $menu_slug, $function) ?>  

Здесь:

  • $parent_slug – уникальный идентификатор для меню верхнего уровня, к которому будет добавлено подменю.
  • $page_title заголовок добавляемой страницы.
  • $menu_title заголовок, отображаемый в меню (зачастую короткая версия $page_title)
  • $capability – минимальные права доступа, требуемые пользователю, чтобы получить доступ к данному меню.
  • $menu_slug – уникальный идентификатор для создаваемого меню.
  • $function – название функции, которая вызывается для обработки (и представления) данной страницы меню.

Если вы хотите добавить страницу меню в качестве подменю к уже существующей группе WordPress, вы можете использовать следующие значения в качестве параметра $parent_slug:

  • Dashboard: index.php
  • Posts: edit.php
  • Media: upload.php
  • Links: link-manager.php
  • Pages: edit.php?post_type=page
  • Comments: edit-comments.php
  • Appearance: themes.php
  • Plugins: plugins.php
  • Users: users.php
  • Tools: tools.php
  • Settings: options-general.php

Группа Appearance является хорошим кандидатом для размещения нашей страницы настроек. Давайте остановимся на ней, и попробуем создать нашу первую страницу настроек. Вот обновленная версия нашей функции установки меню:

function setup_theme_admin_menus() {
    add_submenu_page('themes.php',
        'Front Page Elements', 'Front Page', 'manage_options',
        'front-page-elements', 'theme_front_page_settings');
}  

Нам по-прежнему надо создать функцию theme_front_page_settings для работы с настройками. Вот самая простая ее форма:

function theme_front_page_settings() {
    echo "Hello, world!";
}  

Вот как это будет выглядеть в действии:

1

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

// проверяем, что пользователь может обновлять настройки
if (!current_user_can('manage_options')) {
    wp_die('You do not have sufficient permissions to access this page.');
}  

Теперь, если пользователь, которому нельзя управлять страницей настроек, зайдет на страницу настроек, он увидит обычное сообщение: «У вас нет достаточных прав, чтобы получить доступ к данной странице».

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

Чтобы добавить свою собственную группу настроек, вы должны создать страницу меню верхнего уровня, и соединить с ней страницы подменю. Вот новая версия нашей функции для создания меню. Функция add_menu_page создает меню верхнего уровня по аналогии с add_submenu_page, за исключением лишь того, что ей не нужен параметр $parent_slug.

function setup_theme_admin_menus() {
    add_menu_page('Theme settings', 'Example theme', 'manage_options',
        'tut_theme_settings', 'theme_settings_page');  

    add_submenu_page('tut_theme_settings',
        'Front Page Elements', 'Front Page', 'manage_options',
        'front-page-elements', 'theme_front_page_settings');
}  

// нам нужно добавить функцию обработки меню верхнего уровня
function theme_settings_page() {
    echo "Settings page";
}  

Если вы протестируете код и обновите консоль WordPress, то вы увидите новую группу меню, представленную в самом низу списка меню.

2

Однако пока это выглядит не совсем верно.  Щелчок по верхнему элементу меню приводит вас не к странице меню Front Page, а к странице Example theme. Это не совпадает с тем, как работают остальные меню WordPress, потому давайте сделаем еще одну вещь: изменив атрибут $menu_slug в вызове add_submenu_page на то же самое значение, что и в меню верхнего уровня, мы можем связать два меню так, чтобы выбор верхнего пункта приводил к появлению меню Front Page.

function setup_theme_admin_menus() {
    add_menu_page('Theme settings', 'Example theme', 'manage_options',
        'tut_theme_settings', 'theme_settings_page');  

    add_submenu_page('tut_theme_settings',
        'Front Page Elements', 'Front Page', 'manage_options',
        'tut_theme_settings', 'theme_front_page_settings');
}  

function theme_settings_page() {  

}  

3

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

  • $icon_url – определяет URL иконки для меню верхнего уровня.
  • $position – определяет позицию вашей группы меню в списке меню. Чем больше значение, тем ниже позиция в меню.

Шаг 3. Создаем HTML-форму для страниц настроек.

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

В данном руководстве нам нужно поле для определения, сколько элементов должно быть выведено в одной строке, и список для определения существующих элементов. Начнем с более простого: давайте создадим текстовое поле для количества элементов в одной строке. Отредактируем функцию для страницы настроек:

function theme_front_page_settings() {
?>
    <label for="num_elements">
        Number of elements on a row:
    </label>   

    <input type="text" name="num_elements" />
<?php
}  

Когда вы перезагрузите страницу настроек, вы увидите первое поле:

4

Чтобы страница настроек отвечала существующему опыту взаимодействия WordPress, и ваш плагин выглядел профессионально, нужно использовать CSS-классы и стили, которые используются в WordPress для создания базовых страниц настроек. Прекрасный способ сделать это – перейти к странице настроек и проанализировать ее исходник.

Самая важная часть нашей работы заключается в том, чтобы обернуть страницу настроек в div с классом wrap. В этом элементе div вы можете использовать многочисленные предопределенные стили для заголовков, кнопок и элементов форм. Давайте стилизуем заголовок нашей страницы настроек:

  • Мы создадим h2 для страницы (вы можете использовать заголовки от h2 до h6).
  • Мы выведем иконку страницы настроек перед заголовком (вы можете использовать предопределенные иконки WordPress с помощью функции screen_icon. Функция принимает один из следующих параметров: index, edit, upload, link-manager, pages, comments, themes, plugins, users, tools или options-general).
  • Мы поместим элемент input в форму и таблицу с классом form-table.
function theme_front_page_settings() {
?>
    <div class="wrap">
        <?php screen_icon('themes'); ?> <h2>Front page elements</h2>  

        <form method="POST" action="">
            <table class="form-table">
                <tr valign="top">
                    <th scope="row">
                        <label for="num_elements">
                            Number of elements on a row:
                        </label>
                    </th>
                    <td>
                        <input type="text" name="num_elements" size="25" />
                    </td>
                </tr>
            </table>
        </form>
    </div>
<?php
}  

5

Далее нам нужно добавить элементы.

Чтобы сделать это, мы используем jQuery, поскольку jQuery в разы проще, чем Javascript при создании чего-либо с нуля, к тому же эта библиотека поставляется вместе с WordPress. Если вы использовали уже jQuery до этого, вам нужно будет просто учесть следующее: нотация $, которую вы обычно используете в jQuery, не работает в WordPress – вам нужно вместо нее использовать все слово jQuery.

Во-первых, мы создадим элемент для редактирования настроек одного блока главной страницы, что послужит шаблоном для элементов, добавляемых пользователем. Добавьте данный код между закрывающим тегом table и закрывающим тегом form.

<?php $posts = get_posts(); ?>  

<li class="front-page-element" id="front-page-element-placeholder">
    <label for="element-page-id">Featured post:</label>
    <select name="element-page-id">
        <?php foreach ($posts as $post) : ?>
            <option value="<?php echo $post-<ID; ?>">
                <?php echo $post->post_title; ?>
            </option>
        <?php endforeach; ?>
    </select>
    <a href="#">Remove</a>
</li>

Теперь мы увидим следующее:

6

Теперь, когда у нас есть шаблон, пришло время скрыть его и создать Javascript для использования шаблона при создании новых строк популярных записей. Установим стиль для li элемента в display:none;

<li class="front-page-element" id="front-page-element-placeholder" style="display:none"> 

Затем мы создадим список для фиксирования элементов главной страницы при их добавлении, и ссылку, по которой будет щелкать пользователь при добавлении новых элементов. Я привел весь HTML-код целиком, чтобы вы могли видеть, где произошли изменения:

<div class="wrap">
    <?php screen_icon('themes'); ?> <h2>Front page elements</h2>  

    <form method="POST" action="">
        <table class="form-table">
            <tr valign="top">
                <th scope="row">
                    <label for="num_elements">
                        Number of elements on a row:
                    </label>
                </th>
                <td>
                    <input type="text" name="num_elements" size="25" />
                </td>
            </tr>
        </table>  

        <h3>Featured posts</h3>  

        <ul id="featured-posts-list">
        </ul>  

        <input type="hidden" name="element-max-id" />  

        <a href="#" id="add-featured-post">Add featured post</a>
    </form>  

<?php $posts = get_posts(); ?>
    <li class="front-page-element" id="front-page-element-placeholder"
        style="display:none;">
        <label for="element-page-id">Featured post:</label>
        <select name="element-page-id">
            <?php foreach ($posts as $post) : ?>
                <option value="<?php echo $post->ID; ?>">
                    <?php echo $post->post_title; ?>
                </option>
            <?php endforeach; ?>
        </select>
        <a href="#">Remove</a>
    </li>  

</div>  

Для реальной темы хорошая практика состоит в добавлении всего JS-кода в отдельный файл, однако для упрощения данного руководства я решил добавить JS в ту же самую функцию с HTML, сразу перед wrap div:

<script type="text/javascript">
    var elementCounter = 0;
    jQuery(document).ready(function() {
        jQuery("#add-featured-post").click(function() {
            var elementRow = jQuery("#front-page-element-placeholder").clone();
            var newId = "front-page-element-" + elementCounter;  

            elementRow.attr("id", newId);
            elementRow.show();  

            var inputField = jQuery("select", elementRow);
            inputField.attr("name", "element-page-id-" + elementCounter);   

            var labelField = jQuery("label", elementRow);
            labelField.attr("for", "element-page-id-" + elementCounter);   

            elementCounter++;
            jQuery("input[name=element-max-id]").val(elementCounter);  

            jQuery("#featured-posts-list").append(elementRow);  

            return false;
        });
    });
</script>  

JS-код выше создает функцию, которая вызывается, когда пользователь щелкает по ссылке с id= add-featured-post. Эта функция клонирует шаблон списка, который мы создали ранее, и обновляет его поля, в которых теперь содержатся уникальные id и имена. Таким образом, все они будут корректно отправляться вместе с формой, когда пользователь щелкнет Submit. Переменная elementCounter содержит в себе следующий id для добавления. Он также хранится в скрытом поле, чтобы при отправке формы мы знали, сколько элементов будет на главной странице.

Если вы щелкнете по ссылке “Add featured post” несколько раз, вы увидите, как новые элементы добавляются в список.

7

Однако когда вы щелкнете по кнопке Remove, вы увидите, что ничего не произошло. Давайте добавим функцию для удаления элементов из списка.

function removeElement(element) {
    jQuery(element).remove();
}  

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

var removeLink = jQuery("a", elementRow).click(function() {
    removeElement(elementRow);
    return false;
});

Перед тем, как перейти к сохранению формы, нам нужно сделать еще одну вещь. Мы используем jQuery-плагин ui.sortable, чтобы сделать элементы главной страницы сортируемыми путем перетаскивания их по странице. Чтобы включить функциональность сортировки, нам нужно подключить соответствующий JS-файл (который также поставляется с WordPress). Сделать это можно при помощи следующей строки кода в самом конце functions.php:

if (is_admin()) {
    wp_enqueue_script('jquery-ui-sortable');
} 

Затем мы добавим следующий JS сразу перед (или после) функцией jQuery(“#add-featured-post”).click, определенной выше:

jQuery("#featured-posts-list").sortable( {
    stop: function(event, ui) {
        var i = 0;  

        jQuery("li", this).each(function() {
            setElementId(this, i);
            i++;
        });  

        elementCounter = i;
        jQuery("input[name=element-max-id]").val(elementCounter);
    }
});  

Данный фрагмент делает список сортируемым и добавляет событие, которое вызывается тогда, когда пользователь закончит сортировку. Обработчик события обновляет все id для элементов, чтобы новый порядок был принят при сохранении формы (это станет понятно, когда мы реализуем сохранение). При написании остановки обработчика я отметил, что код задания id для контента шаблона дублировался в двух местах, так что я реструктурировал его в функцию, которую поместил сразу перед строкой с jQuery(document).ready():

function setElementId(element, id) {
    var newId = "front-page-element-" + id;      

    jQuery(element).attr("id", newId);                 

    var inputField = jQuery("select", element);
    inputField.attr("name", "element-page-id-" + id);   

    var labelField = jQuery("label", element);
    labelField.attr("for", "element-page-id-" + id);
}  

Теперь, когда добавление элементов, их сортировка и удаление работает, пришло время к сохранению данных. Последний штрих: добавим кнопку Submit сразу перед закрывающим тегом form:

<p>
    <input type="submit" value="Save settings" class="button-primary"/>
</p> 

Шаг 4. Сохраняем форму.

Страница параметров выглядит прекрасно, однако кое-что в ней отсутствует: она ничего не делает. Пришло время сохранить некоторые данные. WordPress обеспечивает простую систему сохранения параметров темы и плагинов – пару ключей для базы данных в виде функций get_option и update_option. Данные, сохраняемые этими функциями, могут быть настолько простыми, как цифровые значения, или настолько сложными, как массивы, вложенные несколько раз друг в друга.

Обработка формы совершается той же функцией, что и рендеринг формы. Чтобы понять, была ли форма отправлена или нет, мы добавим скрытое поле, update_settings, к форме, и затем проверим, было ли отправлено данное поле или нет, в функции обработки:

if (isset($_POST["update_settings"])) {
    // делаем сохранение
}  

Скрытое поле, идущее вместе с формой, выглядит следующим образом:

<input type="hidden" name="update_settings" value="Y" />  

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

$num_elements = esc_attr($_POST["num_elements"]);
update_option("theme_name_num_elements", $num_elements);  

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

<input type="text" name="num_elements" value="<?php echo $num_elements;?>" size="25" />  

И на случай, когда мы ничего не сохраняем, нам нужно получить текущее значение для опций; давайте добавим следующий код, который будет выполняться тогда, когда форма не была отправлена.

$num_elements = get_option("theme_name_num_elements");  

Когда форма сохранена, важно уведомить пользователя о том, что все прошло удачно. Давайте создадим простое уведомление, Settings saved, сразу после update_option:

?>
    <div id="message" class="updated">Settings saved</div>
<?php  

8

Теперь давайте сохраним элементы главной страницы. Самое большое значение id для элементов главной страницы передается как element-max-id, так что мы можем получить это значение и перебрать в цикле все элементы до этого id, сохраняя их данные в массив в корректном порядке:

$front_page_elements = array();  

$max_id = esc_attr($_POST["element-max-id"]);
for ($i = 0; $i < $max_id; $i ++) {
    $field_name = "element-page-id-" . $i;
    if (isset($_POST[$field_name])) {
        $front_page_elements[] = esc_attr($_POST[$field_name]);
    }
}  

update_option("theme_name_front_page_elements", $front_page_elements);  

Здесь мы сохраняем данные, однако нам нужно представить значения на странице настроек. Давайте сделаем то же самое, что мы делали с полем num_elements – загрузим стандартные опции в самом начале функции:

$front_page_elements = get_option("theme_name_front_page_elements");  

Теперь выведем существующие элементы при выполнении формы:

<?php $element_counter = 0; foreach ($front_page_elements as $element) : ?>
    <li class="front-page-element" id="front-page-element-<?php echo $element_counter; ?>">
        <label for="element-page-id-<?php $element_counter; ?>">Featured post:</label>
        <select name="element-page-id-<?php $element_counter; ?>">  

        <?php foreach ($posts as $post) : ?>
            <?php $selected = ($post->ID == $element) ? "selected" : ""; ?>
            <option value="<?php echo $post->ID; ?>" <?php echo $selected; ?>>
                <?php echo $post->post_title; ?>
            </option>
        <?php endforeach; ?>  

        </select>  

        <a href="#" onclick="removeElement(jQuery(this).closest('.front-page-element'));">Remove</a>
    </li>  

<?php $element_counter++; endforeach; ?>  

Нам также нужно задать начальное значение для переменной elementCounter, используемой в JS, при помощи задания начального значения для скрытого поля в PHP и считывания его при инициализации JS-переменной:

<input type="hidden" name="element-max-id" value="<?php echo $element_counter; ?>" />

Вот часть JS:

var elementCounter = jQuery("input[name=element-max-id]").val();  

Шаг 5. Используем параметры в теме.

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

В данном разделе изменения затронут index.php. Во-первых, мы считываем опции в переменные:

<?php
    $num_elements = get_option("theme_name_num_elements");
    $elements = get_option("theme_name_front_page_elements");
?>

Затем циклически проходим по списку $elements, группируя элементы в строки с числом $num_elements блоков в каждой строке.

<div id="front-page-element-container">  

    <div class="front-page-element-row">
        <?php foreach($elements as $post_id) : ?>
            <?php if ($num == $num_elements) : ?>
                </div>
                <div class="front-page-element-row">
            <?php endif; ?>  

            <!-- Render element here -->  

        <?php endforeach; ?>
    </div>  

</div>  

И затем, используя данные, сохраненные для каждого элемента, мы заполняем часть рендеринга элементов:

<?php $element_post = get_post($post_id); ?>  

<div class="front-page-element">
    <div class="thumbnail-image">
        <?php if (has_post_thumbnail($post_id)) : ?>
            <?php echo get_the_post_thumbnail($post_id, 'tutorial-thumb-size'); ?>
        <?php endif; ?>  

        <a class="title" href="<?php echo get_permalink($post_id); ?>"><?php echo $element_post->post_title;?></a>
    </div>
</div>  

С несколькими элементами страница будет иметь следующий вид:

9

По-прежнему некрасиво. У записей нет миниатюр и нет стилизации. Чтобы сделать их вид лучше, давайте добавим для начала поддержку миниатюр. Делается это с помощью подцепления новой функции, которая регистрирует миниатюры сразу после того, как тема будет загружена.

function setup_theme_features() {
    if (function_exists('add_theme_support')) {
        add_theme_support('post-thumbnails');
    }  

    if (function_exists("add_image_size")) {
        add_image_size('tutorial-thumb-size', 200, 200, true);
    }
}  

add_action('after_setup_theme', 'setup_theme_features');  

Функция setup_theme_features включает миниатюры записей, используя функцию add_theme_support, чтобы WordPress мог добавить данную функциональность к странице сохранения записи. На странице записи мы можем теперь добавить миниатюру, выбрав пункт Use as featured image.

10

Функция также определяет новый размер изображения, tutorial-thumb-size, который используется при получении миниатюр в коде обработки.

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

11

Наконец, давайте добавим стили к style.css, чтобы миниатюры и записи на главной странице смотрелись привлекательнее:

.front-page-element-row {
    overflow: auto;
}  

.front-page-element {
    float: left;
    margin: 10px 10px 10px 10px;
    padding: 0px;  

    width: 200px;
    height: 200px;
}  

.thumbnail-image {
    width: 200px;
    height: 200px;  

    background: #eee;
    position: relative;
}  

.thumbnail-image .title {
    position: absolute;
    bottombottom: 20px;  

    display: block;
    background: #000;
    color: #fff;
    padding: 10px;  

    font-family: Arial;
    font-size: 12pt;
    text-decoration: none;
}  

12

Заключение

Мы создали страницу настроек для произвольной темы. Конечно, тема далеко не завершена; я надеюсь, что данное руководство поможет вам создать свои собственные настройки для изменения элементов в вашей новой WP-теме.

Источник: wp.tutsplus.com

Сохранено из oddstyle.ru

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

%d такие блоггеры, как: