Рослый add review php. Руководство по пользовательским типам записей: создание, выведение и дополнительные поля. Что такое Custom Post Types

Ответ

На основе https://toster.ru/q/276441 Понятное дело, многое зависит от проекта, поэтому данный пост стоит адаптировать под ваш случай.

* Безопасность:
- Каждый аргумент метода простого типа должен проверяться на тип в случае его проксирования и на граничные значения в случае обработки. Чуть что не так - бросается исключение. Если метод с несколькими аргументами на 80% состоит из поверки из аргументов - это вполне нормально))
- Никаких trigger_error, только исключения.
- Исключения ДОЛЖНЫ быть человеко-понятны, всякие "Something went wrong" можно отдавать пользователю, но в лог должно попасть исключение со стектрейсом и человеко-понятным описанием, что же там пошло не так.
- Каждый аргумент (объект) метода должен быть с тайпхинтингом на этот его класс, или интерфейс.
- За eval как правило жесткий выговор
- @ допускается только в безвыходных ситуациях, например проверка json_last_error.
- Перед работой с БД - обязательная проверка данных.
- Никаких == и!=. Со swtich - единственное исключение, по ситуации.
- Если метод возвращает не только bool, а еще что-то - жесткая проверка с ===, или!== обязательна.
- Никаких условий с присваиваниями внутри. while($row = ...) - тоже недопустимо.
- Магические геттеры/сеттеры разрешаются только в безвыходных ситуациях, в остальном - запрещены.
- Конкатенации в sql - только в безвыходных ситуациях.
- Параметры в sql - ТОЛЬКО через плейсхолдеры.
- Никаких глобальных переменных.
- Даты в виде строки разрешаются только в шаблонах и в БД, в пхп коде сразу преобразуется в \DateTimeImmutable (в безвыходных ситуациях разрешено \DateTime)
- Конечно зависит от проекта, но как правило должно быть всего две точки входа: index.php для web и console(или как-то по другому назваться) - для консоли.

* Кодстайл PSR-2 + PSR-5 как минимум, + еще куча более жестких требований (для начала все то что в PSR помечено как SHOULD - становится MUST)
- В PhpStorm ни одна строчка не должна подсвечиваться (исключением является typo ошибки, например словарик не знает какой-то из аббревиатур, принятых в вашем проекте). При этом разрешается использовать /** @noinspection *** */ для безвыходных ситуаций.
- Если кто-то говорит, что пишет в другом редакторе и у него не подсвечивается, все равно отправляется на доработку.

* Организация кода:
- Никаких глобальных функций.
- Классы без неймспейса разрешаются только в исключительно безвыходных ситуациях.

* Тестируемость (в смысле простота тестирования) кода должна быть высокая.
- Покрытие кода обязательно для всех возможных кейсов использования каждого публичного метода с моками зависимостей.

* Принципы MVC:
- Никаких обработок пользовательского ввода в моделях, от слова совсем.
- Никаких запросов в БД из шаблонов.
- Никаких верстки/js/css/sql-ин в контроллерах.
- В моделях НИКАКОЙ МАГИИ, только приватные свойства + геттеры с сеттерами.
- В моделях разрешено использовать метод save(при наличии такого разумеется) только в исключительных ситуациях. Во всех остальных - либо insert, либо update.

* Принципы SOLID:
- Никаких универсальных объектов, умеющих все.
- Если метод для внутреннего пользования - private, никаких public.
- Статические методы разрешаются только в случае безвыходности.

* Принцип DRY разрешено нарушать в случаях:
- Явного разделения обязанностей
- В тестах (каждый тест должен быть независимым, на сколько это возможно)

* Работа с БД:
- Запрос в цикле должен быть РЕАЛЬНО обоснован.
- За ORDER BY RAND() жесткий выговор
- Поиск не по ключам (конечно если таблица НЕ на 5 строк) запрещен.
- Поиск без LIMIT (опять же если таблица НЕ на 5 строк) запрещен.
- SELECT * - запрещен.
- Денормализация БД должна быть обоснована.
- MyISAM не используется (так уж)))
- Множественные операции обязательно в транзакции, с откатом если что-то пошло не так.
- БД не должна содержать бизнес логики, только данные в целостном виде.
- Не должно быть нецелесообразного дерганья БД там, где без этого можно обойтись.

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

* О людях:
- "Я привык писать так и буду дальше" - не вопрос, ревью пройдешь только когда поменяешь свое мнение.
- "Я пишу в vim-е и мне так удобно" - здорово, код консолью я тоже в нем пишу)) но есть требования к коду, если в них не сможешь - не пройдешь ревью.
- "Я скопировал этот страшный метод и поменял 2 строчки" - это конечно замечательно, но по блейму автор всего этого метода ты, так что давай без ерунды, хорошо?
- "Оно же работает!" - вот эта фраза переводится примерно так: "да, я понимаю, что пишу полную ерунду, но не могу писать нормально потому, что не могу", я правильно тебя понял?))
- "У меня все работает!" - рад за тебя, а как на счет продакшна?
- "Там все просто" - не используй слово "просто", от слова "совсем". Вот тебе кусок кода (первого попавшегося со сложной бизнес логикой), где там ошибка (не важно есть она, или нет)? Ты смотришь его уже 2 минуты, в чем проблема, там же все "просто"))

* Всякое:
ActiveRecord (это я вам как в прошлом фанат Yii говорю) - полный отстой, примите за исходную. По факту у вас бесконтрольно по проекту гуляют модельки с подключением к БД. Не раз натыкался на то, что в тех же шаблонах вызывают save, или update (за такое надо сжигать).

Основное:
1. Наличие критических ошибок и устаревших функций.
2. Использование паттернов, элегантность решений.
3. Читабельность кода, наличие коментариев, наличие доков.
4. Соблюдение парадигм и соглашений (например, нарушение MVC).

Второстепенно\непринципиально:
1. Быстродействие кода (за исключением хайлоад)
2. Потребление памяти (за исключением бигдаты)
3. Эфективность SQL запросов (за исключением совсем уж несуразных)
4. Избегание в данных момент неважных, но потенциально узких мест (например замедление работы файловой системы при большом количестве картинок в папке аплоада)
5. Новизна примененых технологий.
6. Оправданое\Неоправднанное\Избыточное Велосипедирование.

  1. Код не содержит явных и потенциальных ошибок.
  2. Код работает так, как это описано в документации, техническом задании или сопроводительных комментариях.
  3. Стиль кодирования соответствует принятым правилам кодирования
  4. Код имеет сопроводительные комментарии в соответствии с phpDoc
  5. Вложенность блоков не превышает 4-го уровня.
  6. Код не генерирует сообщения уровня Strict, Warning, Notice, Deprecated. Если этого невозможно избежать, то непосредственно перед строкой, которая это генерирует необходимо принудительно отключить error_reporting, а непосредственно после строки включить error_reporting в исходное значение (которое было до этого). Такой код должен быть задокументирован специальным образом.
  7. Закомментированный кусок кода должен быть удален.
  8. В PHP коде (за исключением phpTemplate) запрещены вставки HTML, JavaScript. Все вставки должны производиться через специальные шаблоны.
  9. Классы, функции, переменные и константы должны логически именоваться человекопонятным способом на английском языке в соответствии со стандартами кодирования. Не допускается именование транслитом на русском, либо на иных языках
  10. Область видимости переменных и методов классов всегда должна быть определена (private, protected, public).
  11. Размер одного метода не должен превышать 40-50 строк.
  12. Переменная, используемая в цикле, либо в условном блоке должна быть инициализирована заранее.
  13. Переменная в любой момент времени должна содержать только один тип. Пустая переменная должна содержать null. (не допускается $var = false; $var = "test"; . Допускается $var = null; $var = "test";).
  14. При передаче объектов классов в методы должен использоваться контроль типов.

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

Что такое пользовательские типы записей?

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

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

Зачем использовать пользовательские типы записей?

Пользовательские типы записей помогают хранить разные типы записей в разных местах. Это помогает отделить обычные посты от других. Вот и все.

Создаем плагин для пользовательского типа записи

Мы создадим плагин для пользовательского типа записи, который будет выводить лучшие кинообзоры. Начнем.

Шаг 1 . Создайте папку для WordPress плагина

Откройте папку с WordPress плагинами и создайте новую папку Movie-Reviews .

Шаг 2 : Создайте PHP файл

В созданной папке создайте PHP файл Movie-Reviews.php

Шаг 3 : Добавьте шапку

Откройте созданный файл и вставьте код для шапки сверху.

Перед тегом закрытия PHP команды введите следующую строку кода create_movie_review . При инициализации она будет запускать соответствующую пользовательскую функцию каждый раз при генерации страницы.

Add_action("init", "create_movie_review");

Шаг 5 : Выполнение функции

Код для выполнения функции create_movie_review .

Function create_movie_review() { register_post_type("movie_reviews", array("labels" => array("name" => "Movie Reviews", "singular_name" => "Movie Review", "add_new" => "Add New", "add_new_item" => "Add New Movie Review", "edit" => "Edit", "edit_item" => "Edit Movie Review", "new_item" => "New Movie Review", "view" => "View", "view_item" => "View Movie Review", "search_items" => "Search Movie Reviews", "not_found" => "No Movie Reviews found", "not_found_in_trash" => "No Movie Reviews found in Trash", "parent" => "Parent Movie Review"), "public" => true, "menu_position" => 15, "supports" => array("title", "editor", "comments", "thumbnail", "custom-fields"), "taxonomies" => array(""), "menu_icon" => plugins_url("images/image.png", __FILE__), "has_archive" => true)); }

Функция register_post_type сделает бОльшую часть работы в нашем случае. Сразу как она вызовется, она подготовит необходимую для нового пользовательского поста конфигурацию WordPress, включая дополнительные разделы для администратора. В функцию передается два типа аргументов: уникальное имя (name) пользовательского типа поста и массив с его свойствами. Это другой массив с другими метками, которые указывают какие текстовые строки будут показываться в разных частях пользовательского типа записи, например: " name " выводит название пользовательского типа записи на панели управления, " edit " и " view " выводят кнопки Edit и View . Думаю, все остальные аргументы говорят сами за себя.

Так, в следующих аргументах:

  • "public" => true задает видимость пользовательского типа записи как на панели управления администратора, так и в клиентской части.
  • "menu_position" => 15 задает, где в меню, будет находиться пользовательский тип записи.
  • "supports" => array("title", "editor", "comments", "thumbnail", "custom-fields") задает те атрибуты пользовательского типа записи, которые будут отображаться.
  • "taxonomies" => array("") создает пользовательские таксономии. В данном случае они не определены.
  • "menu_icon" => plugins_url("images/image.png", __FILE__) показывает иконку в меню администратора.
  • "has_archive" => true разрешает архивирование пользовательских типов записей.

Вы можете узнать больше о других аргументах, используемых в пользовательских типах записей на странице WordPress Codex register_post_type .

Шаг 6 : Иконка для пользовательского типа записей

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

Шаг 7 : Активируйте плагин

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

Шаг 8 : Добавляем новую запись

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

Шаг 9 : Публикуем

Опубликуйте запись и нажмите View Movie Review , чтобы увидеть созданный кинообзор.

Создание дополнительных полей для пользовательских типов записей

Механизм дополнительных полей (метабоксов) использует встроенную в WordPress систему дополнительных полей. Это помогает добавлять поля, предназначенные исключительно для пользовательских типов записей, не используя в редакторе пользовательских полей по умолчанию.

Шаг 1 : Регистрируем пользовательскую функцию

Откройте файл Movie-Reviews.php и добавьте следующий код перед тегом закрытия. Этот код регистрирует функцию, которая будет вызываться при посещении панели администратора WordPress.

Add_action("admin_init", "my_admin");

Шаг 2 : Выполняем пользовательскую функцию

Добавьте выполнение функции my_admin , которая регистрирует дополнительные поля и связывает их с пользовательским типом записи movie_reviews .

Function my_admin() { add_meta_box("movie_review_meta_box", "Movie Review Details", "display_movie_review_meta_box", "movie_reviews", "normal", "high"); }

В данном случае функция add_meta_box используется для добавления дополнительных полей к пользовательскому типу записей. Об атрибутах:

  • movie_review_meta_box необходимый атрибут для HTML id
  • Movie Review Details текст, которые будет виден в заголовке дополнительного поля
  • display_movie_review_meta_box функция обратного вызова которая отображает содержимое дополнительных полей
  • movie_review имя пользовательского типа записи, где будут отображаться дополнительные поля
  • normal определяет где на странице будет показан блок редактирования
  • high определяет приоритет отображаемых полей

Шаг 3: Выполняем функцию display_movie_review_meta_box

ID, "movie_director", true)); $movie_rating = intval(get_post_meta($movie_review->ID, "movie_rating", true)); ?>
Movie Director
Movie Rating

Этот код выводит содержимое дополнительных полей. Здесь используется объектная переменная, которая содержит информацию о каждом из показанных на панели редактирования кинообзоров. Используя этот объект мы получили ID записи и использовали его, чтобы сделать запрос в базу данных для получения имени режиссера и рейтинга, что в свою очередь выведется в полях на экране. При добавлении новой записи, функция get_post_meta возвратит пустую строку, и в итоге дополнительные поля будут пустыми.

Шаг 4 : Регистрируем функцию сохранения записи

add_action("save_post", "add_movie_review_fields", 10, 2);

Эта функция вызывается при сохранении записи в базе данных.

Шаг 5 : Выполняем функцию add_movie_review_fields

function add_movie_review_fields($movie_review_id, $movie_review) { // Check post type for movie reviews if ($movie_review->post_type == "movie_reviews") { // Store data in post meta table if present in post data if (isset($_POST["movie_review_director_name"]) && $_POST["movie_review_director_name"] != "") { update_post_meta($movie_review_id, "movie_director", $_POST["movie_review_director_name"]); } if (isset($_POST["movie_review_rating"]) && $_POST["movie_review_rating"] != "") { update_post_meta($movie_review_id, "movie_rating", $_POST["movie_review_rating"]); } } }

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

Шаг 6 : Отключаем стандартные пользовательские поля

Создавая пользовательский тип записи, мы задали функцию create_movie_review . Удалите элемент custom-fields из массива supports , поскольку он нам больше не понадобиться. Теперь, если вы сохраните файл и откроете панель редактирования Movie Reviews , вы увидите два поля в дополнительных полях: Movie Author и Movie Rating . Вы можете добавить другие элементы тем же способом.

Создание шаблона для пользовательского типа записи

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

Шаг 1 : Регистрируем функцию запуска шаблона

Откройте файл Movie-Reviews.php и перед тегом закрытия добавьте следующий код. Этот код регистрирует функцию, которая будет вызываться при посещении панели администратора WordPress.

Add_filter("template_include", "include_template_function", 1);

Шаг 2 : Выполняем функцию

function include_template_function($template_path) { if (get_post_type() == "movie_reviews") { if (is_single()) { // checks if the file exists in the theme first, // otherwise serve the file from the plugin if ($theme_file = locate_template(array ("single-movie_reviews.php"))) { $template_path = $theme_file; } else { $template_path = plugin_dir_path(__FILE__) . "/single-movie_reviews.php"; } } } return $template_path; }

Здесь проверяется, есть ли в текущей папке темы шаблон типа single-(post-type-name).php . Если его там нет, то проверяется наличие шаблона в папке с плагином, куда мы и поместим наш шаблон, как часть плагина. Событийный обработчик (хук) template_include используется, чтобы изменить обычное выполнение программы и принудительно запустить специальный шаблон.

Шаг 3 : Создаем файл шаблона Single Page

Сохранив ранее открытый файл с плагином, создайте другой файл с именем single-movie_reviews.php и вставьте в него следующий код.

"movie_reviews",); $loop = new WP_Query($mypost); ?> have_posts()) : $loop->the_post();?>
>
Title:
Director:
Rating: "; } else { echo ""; } } ?>

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

Внимание : необходимо создать новую страницу из панели управления используя созданный шаблон.

Шаг 4: Изображения

Сохраните два изображения с иконками для звездочек размером 32x32 пикселя в вашу папку с плагином. Назовите их соответственно icon.png и grey.png . Вот и все, теперь кинообзоры показываются на отдельной странице и отсортированы по дате.

"Барс" "компрессор" "Питер-Пласт" "Промтек", Барнаул "Рабочая одежда" "Экспедиция", Китай "Красный Маяк" (вроде...) "Уральские самоцветы", Екатеринбург 444 ВКФ 720 Armour acmepower Active Leisure Adidas AGU Ajungilak AKU Alexika Alpina alpine equipment AMV sport AMVsport Answer Aquapac Artiach asolo ATEMI Atomic Author AVL axio Axon B"TWIN Baseg Bask BBB Beal BERCUT, Санкт-Петербург Biemme Big Agnes Big Pack Black Diamond Boblbee BOBSTER BodyDry bolle Bonfire Boreal Brubeck CamelBak CAMP Camping Gas Campus Canadian Camper Canon Canondale Capricorn Cascade designs Casio Cassida CatManDo (China) Cenda.Ru офисной мебели Chain ChainPower Chinook CITIZEN Climbing Technology Cobra Electronics Coflach Coleman Columbia Columbia River Knife and Tool (CRKT) Comazo compaq Contour Corcoran Cricket Curver CycleDesign Dagger Daiwa Dakine Deuter Doite Dolomite Duofold (Ireland) DuPont Duracell Duraflex Dynastar ECCO EKA EKUD Endura Ericson Ericsson Eurotrail EVA-Sport Exped Exustar FavourLite Fenix Ferrino (Italy) Fillon FINO 40S PANORAMA fire-maple Fisher Fiskars Five Ten Fizan Fjallraven Fjord Nansen fjordboat Fortuna Fovour Light FoxRiver Freetime Front Limit gaerne Gala Sport GARMIN GARMONT Garsing (Гарсинг) Genimap Gerber (USA) Gist GORDINI GoSystem GoSystem/Karrimor GP Grangers Gravel Grisport GRIVEL Gronell Gruppa 99 Guahoo HAGLOFS (Sweden) Haier Halti Hama Hamilton Global Management Hangzhou EXCO Industrial Co Ltd Hannah Hanwag Happy Outdoor Helly Hansen Helsport High Peak High Peak (Best Camp) HighGear HIKO Sport Hilleberg Hobbit http://sanek99.s19.webhost1.ru/ Husky I/O Magic Icepeak ICOM JackWolfskin Jetboil, Inc. Jinyang JJ-GROUP Jofa Julbo JVC KAISER SPORT Kama Karrimor KATZ KAYLAND KED KEEN Kefas Kongur Kovea La Sportiva Lafuma Lake Leatherman Led Lenser Leki Levron Lifeproof Linton LIOD lma lmaouterwear Loop Lorpen LOTOS LOWA LoweAlpine Lowepro Luo Tuo Mace MackSack Made in China Mammut Mango March road Marcill Markill Marmot Marpetti Masters Maxpedition McKinley Medico MEINDL Mellert Merida Merrell Midland Millet Milo Minolta montrail Mora of sweden Morgan Mills Motorola Mountain Hardware (MHW) MSR MTE Mund Mustek MusucBag N1 Исландия NANO ESTTE Neve/Commandor Nike Nikko Nikon Nikwax Nokia noname Nordway outdoor Norfin Normal NorMark NorthWave Norveg Novatour Novus NRS oceAnco Octopus ODLO Okula Olympus Ontario Knife USA OOO Худобару7 ooo"юкон" Opinel OPTIMUS ORDANA Osprey Otterbox Outdoor Project Outventure Ozon Panasonic Patagonia Peak-1 Pentax Pentax Optio 33 WR PETZL Philips Pinguin Polar Adventure Polifoam Pretec Prijon Primus Princeton Tec Prival prosofta Puma Qualcomm USA QUARANTASEI QUECHUA Raftmaster Raichle Rainbow Red Fox Reed Chill Cheater Ltd Reima Retki (финляндия) Robson Rock Front Rock Pillars Rockland ROGER Rollei (вроде) Rossignol RUBIN Salewa SALMO Salomon Samsung Sanmarco Satila Scarpa Scott USA Sea to Summit Seintex SELA Sevylor Shimano SHIMANO INC. Китай. ShredReady SIDI Siemens Sievert Silva Silvretta Simex Sport Simms Simond Sivera Sixsixone 661 Smith SneVXULY SnowPeak Sol SOLBEI sonim Sony SOTO Specialized Sportful Sprayway Spyderco Stayer Sun Valley Sunroad Suunto Swan SwissoEye Talberg Tatonka Tecnica Telit Telit Italy Terra TerraIncognita, Киев Tescoma The North Face Therm-a-Rest Thermos Time Trial title2 TNP Tramontina Tramp Trezeta Trezetta Trimm Trаvel Extrem Житомир Украина TSL Tubbs Tuckland Ultra-bright Universal UNOMAT UVEX Varta Vasque Vaude Vector, Корея Vertical Verticale Victorinox Viking Viper visu ski Voile Volkshammer Vosonic Voxtel vsrAdfpl Wechsel Tents Windmill X-Bionic XCH Yaesu Yukon Zamberlan Zebra ZebraLight Zippo, США Акваграфика АКМЕ АКМЕ-NORMAL АЛВО-ТИТАНИУМ Альпиндустрия АН «ГЛОБАЛ»-недвижимость в Тольятти Английский производитель Армия РФ ас артс Атеми Аэрогеодезия Беларусь Бескид Бундесвер В. Бойцов Вампирчик-Сан Вача-Труд Век Венто Видео курс Видео-Тренинг "Золотой Актив" Воронеж ВостокСервис Все известные мне 2-км карты на район г.Малошуйка ГалаТур Германия Главное управление геодезии и картографии при совете министров СССР Горная Страна Дельта-7 Джет Спорт Джет-Спорт Дискавери доска объявлений Еврогаз Ейск з-д Октябрь. г. Ворсма ЗАО "Карта" ЛТД ЗАО "Петрохим" С\Пб ЗЛАТОУСТ Знакомства в Сибири Илакс ИП Чирко Н.Е., г. Санкт-Петербург Ирбис Испания Италия Казань Кемерово Кизляр кинофильм Китай Китай/Турция КМЗ им. Зверева Корея Котлы "CITIZEN" Красно Солнышко Красный Треугольник КУКРИ Кулик ЛОМО Манарага Маяк(Кировская обл) Мегатест-сервис министерство обороны России Мито ("Таргет") Москва Московский Компас Мукачево МФК Национальная спортивная компания «ЭФСИ» Не помню неизвестно НЕОПРО Нерис (Киев) Нова Тур ОАО "ЭРА" Октопус ООО "Аэрозоль Новомосковск" ООО "Биогпрд", Москва ООО "Велоклуб.ру" ООО "столица - новый век" ООО "ФОРНЕЛ", Россия, г. Москва ООО "Альбатрос", г. Ворсма ООО Stelz - Санкт-Петербург ооо Леситекс ООО Монополия ООО Похудать.рф7 Отеч. хим. пром. палатка Пермь-19 ПИК-99 пищевая промышленность Прайм-А Проффи респ.Беларусь Россия Ростов на Дону Санкт-Петербург Сварог? Синтез БА Синтепон СИНТО Синто (Тургалантерея) Словения Снаряжение сноуборд Lamar Сплав СПЛАВ, ОКГ Спортивное питание от Scott USA ссср Сталкер Сталкер (Чернецкий Михаил) Стрим Судоверфь Таймень Терра Техно-Авиа (г. Москва) ТМ Ваш комфорт Тритон труд - вача Турион Турлан Урал-экспедиция Фабрика 1 мая, Уфа Федеральная служба геодезии и Картографии Фирма "Арбалет", издательство "Ультра ЭКСТЕНТ" флесна ФМК Фумакилла, Индонезия Харьков Украина Хитон Хоббит ХСН (Чебоксары) Череповецкая фабрика Что-то в Новгороде чудовская спичечная фабрика Шведский неизвестный Шульц Экипаж - Т экспедиция ЭЛФ Мукачево Ярославрезинотехника другой:

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

| Скачать исходники |

Что такое Custom Post Types?

Предположим, вы хотите сделать на вашем блоге отдельный раздел для кино-рецензий. Используя пользовательские типы записей, вы можете создать новый тип вроде Записи или Страницы , который будет содержать другой набор данных. У него будет свое меню администратора, отдельные страницы редактирования, своя таксономия и другие возможности, необходимые для полноценных публикаций.

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

Зачем использовать пользовательские типы записей?

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

Пример создания плагина Custom Post Type

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

Шаг 1. Создаем папку WordPress плагина

Откройте свою папку с WordPress плагинами и создайте новую под названием Movie-Reviews .

Шаг 2. Создаем PHP файл

Откройте папку и создайте PHP файл под названием Movie-Reviews.php .

Шаг 3. Добавляем шапку

Откройте файл и добавьте код шапки плагина.

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

Add_action("init", "create_movie_review");

Шаг 5. Выполнение функции

Выполнение функции create_movie_review :

Function create_movie_review() { register_post_type("movie_reviews", array("labels" => array("name" => "Movie Reviews", "singular_name" => "Movie Review", "add_new" => "Add New", "add_new_item" => "Add New Movie Review", "edit" => "Edit", "edit_item" => "Edit Movie Review", "new_item" => "New Movie Review", "view" => "View", "view_item" => "View Movie Review", "search_items" => "Search Movie Reviews", "not_found" => "No Movie Reviews found", "not_found_in_trash" => "No Movie Reviews found in Trash", "parent" => "Parent Movie Review"), "public" => true, "menu_position" => 15, "supports" => array("title", "editor", "comments", "thumbnail", "custom-fields"), "taxonomies" => array(""), "menu_icon" => plugins_url("images/image.png", __FILE__), "has_archive" => true)); }

Функция register_post_type делает за нас большинство работы. Как только она вызывается, она готовит среду WordPress к новому пользовательскому типу записи, включая разные разделы в админ. части.

Эта функция принимает два аргумента : первый - уникальное имя пользовательского типа записей, а второй - массив, который представляет свойства нового пользовательского типа записей. Вот другой массив, который содержит разные метки, которые обозначают, какие текстовые строки будут отображаться в разных частях пользовательского типа записей, например "name " отображает название пользовательского типа записей в консоли, "edit " и "view " отображаются соответственно в кнопках Edit и View . Думаю, остальное говорит само о себе.

Аргументы :

  • "public" => true - определяет видимость пользовательского типа записи и в панели администратора, и в клиентской части.
  • "menu_position" => 15 - обозначает позицию меню пользовательского типа записи.
  • "supports" => array("title", "editor", "comments", "thumbnail", "custom-fields" ) - определяет характеристики пользовательского типа записей, которые будут отображаться.
  • "taxonomies" => array(" ") - создает пользовательские таксономии. Здесь они не определены.
  • "menu_icon" => plugins_url( "images/image.png", __FILE__ ) - отображает иконку меню администратора.
  • "has_archive" => true - включает архивирование пользовательского типа записи.

На странице WordPress Codex о функции register_post_type вы можете прочесть больше об аргументах, которые используются в пользовательских типах записи.

Шаг 6. Иконка для пользовательского типа записи

Сохраните иконку размером 16 x 16 px в папку вашего текущего плагина. Это необходимо для иконки пользовательского типа записи в консоли.

Шаг 7. Активируем плагин

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

Шаг 8. Добавление новой записи

Щелкните по Add New , чтобы перейти в редактор пользовательского типа записи. Напишите название фильма, рецензию и миниатюру для записи.

Шаг 9. Публикация

Опубликуйте запись и щелкните по View Movie Review , чтобы увидеть созданную кино-рецензию.

Создание полей Meta Box для пользовательских типов записей

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

Шаг 1. Регистрация пользовательской функции

Откройте файл Movie-Reviews.php и добавьте следующий код перед закрывающимся PHP тегом. Это регистрирует функцию, которая будет вызвана, когда будет посещен интерфейс администратора WordPress.

Add_action("admin_init", "my_admin");

Шаг 2. Выполнение пользовательской функции

Добавьте выполнение функции my_admin , которая регистрирует мета-блоки и связывает их с пользовательским типом записей movie_reviews .

Function my_admin() { add_meta_box("movie_review_meta_box", "Movie Review Details", "display_movie_review_meta_box", "movie_reviews", "normal", "high"); }

Здесь функция add_meta_box использована для добавления мета-блоков в пользовательские типы записей.

Атрибуты :

  • movie_review_meta_box - необходимый HTML атрибут id .
  • Movie Review Details - текст, видимый в верхней части мета-блока.
  • display_movie_review_meta_box - обратный вызов, который отображает содержимое мета-блока.
  • movie_reviews - это имя пользовательского типа записей, где будет отображаться мета-блок.
  • normal - определяет часть страницы, где должен быть отображен блок редактирования.
  • high - определяет приоритет в контексте, в котором будут отображаться блоки.

Шаг 3. Выполнение функции display_movie_review_meta_box

ID, "movie_director", true)); $movie_rating = intval(get_post_meta($movie_review->ID, "movie_rating", true)); ?>
Movie Director
Movie Rating

Этот код отображает содержимое мета-блока. Здесь мы использовали объектную переменную, которая содержит информацию о каждой кино-рецензии, которая отображается в редакторе. Используя этот объект, мы получили ID записи и использовали его для запроса в базу, чтобы получить связанное имя режиссера и рейтинг, что привело к отображению полей на экране. Когда новая запись добавлена, get_post_meta возвращает пустую строку, что приводит к отображению пустых полей в мета-блоке.

Шаг 4. Регистрация функции Save Post

add_action("save_post", "add_movie_review_fields", 10, 2);

Эта функция вызывается, когда записи сохраняются в базе данных.

Шаг 5. Вызов функции add_movie_review_fields

function add_movie_review_fields($movie_review_id, $movie_review) { // Check post type for movie reviews if ($movie_review->post_type == "movie_reviews") { // Store data in post meta table if present in post data if (isset($_POST["movie_review_director_name"]) && $_POST["movie_review_director_name"] != "") { update_post_meta($movie_review_id, "movie_director", $_POST["movie_review_director_name"]); } if (isset($_POST["movie_review_rating"]) && $_POST["movie_review_rating"] != "") { update_post_meta($movie_review_id, "movie_rating", $_POST["movie_review_rating"]); } } }

Эта функция выполняется, когда записи сохраняются или удаляются из панели администратора. Здесь после проверки типа полученных данных записи на предмет того, является ли это пользовательским типом записи, проверяется, были ли прикреплены значения к элементам мета-блоков, и затем, наконец, сохраняются значения в эти поля.

Шаг 6. Отключение стандартных пользовательских полей

При создании пользовательского типа записи мы определили функцию create_movie_review . Удалите элемент custom-fields из массива supports , потому что это больше не нужно. Сейчас если вы сохраните файл и откроете редактор Movie Reviews , вы заметите два поля в мета-блоке под названием Movie Author и Movie Rating . Таким же образом вы можете добавить и другие элементы.

Создание пользовательского шаблона для пользовательского типа записи

Правильный способ отображения данных пользовательского типа записи - это использование пользовательских шаблонов для каждого пользовательского типа записи. Здесь мы должны создать шаблон, который отображает все кино-рецензии, добавленные с использованием пользовательского типа записи Movie Review .

Шаг 1. Регистрируем функцию для шаблона

Откройте файл Movie-Reviews.php и добавьте перед тегом закрытия PHP следующий код. Он зарегистрирует функцию для вызова, когда будет посещен интерфейс администратора WordPress.

Add_filter("template_include", "include_template_function", 1);

Шаг 2. Выполнение функции

function include_template_function($template_path) { if (get_post_type() == "movie_reviews") { if (is_single()) { // checks if the file exists in the theme first, // otherwise serve the file from the plugin if ($theme_file = locate_template(array ("single-movie_reviews.php"))) { $template_path = $theme_file; } else { $template_path = plugin_dir_path(__FILE__) . "/single-movie_reviews.php"; } } } return $template_path; }

Здесь код ищет шаблон single-(post-type-name ).php в папке текущей темы. Если его там нет, он ищет в папке плагина шаблон, который мы предоставили как часть плагина. Зацепка template_include была использована для изменения стандартного поведения и применения специфического шаблона.

Шаг 3. Создание файла шаблона Single Page

После сохранения открытого файла плагина создайте другой PHP файл под названием single-movie_reviews.php и вставьте в него следующий код.

"movie_reviews",); $loop = new WP_Query($mypost); ?> have_posts()) : $loop->the_post();?>
>
Title:
Director:
Rating: "; } else { echo ""; } } ?>

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

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

Шаг 4. Изображения

Вам нужно сохранить два изображения иконок 32 x 32 px в папке вашего плагина. Назовите их icon.png и grey.png . Все, теперь кино-рецензии отображаются на отдельной странице, отсортированные по дате.

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

Однажды Вы решили создать свой сайт или блог, а для системы управления Вы выбрали WordPress…Прошло время ваш сайт становится все более и более читаемым и тут, вы поняли, что для ещё большей популярности необходимо добавить немного функционала к сайту или же просто автоматизировать какое-то действие.

Вы идете на «склад» плагинов для wordpress и обнаруживаете, что необходимого плагина для Вас нету. Что же делать? Как быть? Если вы хотя бы немного знакомы с азами программирования на php, верстке, то Вам не составит труда Самому написать плагин для WordPress .

А теперь отправимся на «кухню» для приготовления нашего плагина.

P.s. Если знаний в php и верстке нету… не расстраивайтесь, попросите кого-либо написать Вам нужный функционал 🙂

Прежде чем начать писать плагин необходимо обратится в документацию WordPress где описаны основные принципы написания плагинов и некоторые примеры кода.

Я не буду дублировать эту информацию, а сразу перейду непосредственно к написанию кода.

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

Первое, что мы сделаем, это придумаем уникальное название нашему плагину - «AdvUserReviews «.

Далее создадим в директории Вашего сайта «/wp-content/plugins/» новую директорию «advuserreviews». И в ней создадим файл «advuserreviews.php». Это будет основной файл, который будет отвечать за общею инициализацию. (Желательно используйте кодировку для файлов UTF-8).

В самом начале файла необходимо указать основную информацию о плагине

Теперь, если перейти в панель управления, то можно увидеть, что система нашла новый плагин и предлагает его активировать. Но пока что это делать рано.

Наш новый плагин мы будем писать в стиле ООП и вся обработка данных будет находится в одном файле. Создадим основной каркас файла.

// Stop direct call if(preg_match("#" . basename(__FILE__) . "#", $_SERVER["PHP_SELF"])) { die("You are not allowed to call this page directly."); } if (!class_exists("AdvUserReviews")) { class AdvUserReviews { // Хранение внутренних данных public $data = array(); // Конструктор объекта // Инициализация основных переменных function AdvUserReviews() { } } } global $rprice; $rprice = new AdvUserReviews();

Теперь конструктор объекта дополним следующим кодом:

Function AdvUserReviews() { global $wpdb; // Объявляем константу инициализации нашего плагина DEFINE("AdvUserReviews", true); // Название файла нашего плагина $this->plugin_name = plugin_basename(__FILE__); // URL адрес для нашего плагина $this->plugin_url = trailingslashit(WP_PLUGIN_URL."/".dirname(plugin_basename(__FILE__))); // Таблица для хранения наших отзывов // обязательно должна быть глобально объявлена перменная $wpdb $this->tbl_adv_reviews = $wpdb->prefix . "adv_reviews"; // Функция которая исполняется при активации плагина register_activation_hook($this->plugin_name, array(&$this, "activate")); // Функция которая исполняется при деактивации плагина register_deactivation_hook($this->plugin_name, array(&$this, "deactivate")); // Функция которая исполняется удалении плагина register_uninstall_hook($this->plugin_name, array(&$this, "uninstall")); }

В конструкторе объекта мы используем 3 «хука» или «зацепки» (что это?): register_activation_hook , register_deactivation_hook и register_uninstall_hook - это функции, которые выполняются при активации, деактивации плагина и его удаления соответственно.

Теперь непосредственно реализуем эти функции.

/** * Активация плагина */ function activate() { global $wpdb; require_once(ABSPATH . "wp-admin/upgrade-functions.php"); $table = $this->tbl_adv_reviews; // Определение версии mysql if (version_compare(mysql_get_server_info(), "4.1.0", ">=")) { if (! empty($wpdb->charset)) $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset"; if (! empty($wpdb->collate)) $charset_collate .= " COLLATE $wpdb->collate"; } // Структура нашей таблицы для отзывов $sql_table_adv_reviews = " CREATE TABLE `".$wpdb->prefix."adv_reviews` (`ID` INT(10) UNSIGNED NULL AUTO_INCREMENT, `review_title` VARCHAR(255) NOT NULL DEFAULT "0", `review_text` TEXT NOT NULL, `review_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `review_user_name` VARCHAR(200) NULL, `review_user_email` VARCHAR(200) NULL, PRIMARY KEY (`ID`))".$charset_collate.";"; // Проверка на существование таблицы if ($wpdb->get_var("show tables like "".$table.""") != $table) { dbDelta($sql_table_adv_reviews); } } /** * Деактивация плагина */ function deactivate() { return true; } /** * Удаление плагина */ function uninstall() { global $wpdb; $wpdb->query("DROP TABLE IF EXISTS {$wpdb->prefix}adv_reviews"); }

Переменная $wpdb отвечает за запросы к базе Данных. Функция dbDelta анализирует текущую структуру таблицы, сравнивает ee с желаемой структурой таблицы, и либо добавляет или изменяет таблицу по мере необходимости.

Соответственно, при активации плагина создается структура таблицы для хранения отзывов. При деактивации плагина не происходит никаких действий, а вот при удалении мы удаляем нашу таблицу. Более подробно действия можно понять по исходному коду.

Основная структура нового плагина готова. Теперь необходимо приступить к написанию функциональной части. Для этого в конструктор класса нам необходимо добавить следующие строчки кода:

// Если мы в адм. интерфейсе if (is_admin()) { // Добавляем стили и скрипты add_action("wp_print_scripts", array(&$this, "admin_load_scripts")); add_action("wp_print_styles", array(&$this, "admin_load_styles")); // Добавляем меню для плагина add_action("admin_menu", array(&$this, "admin_generate_menu")); } else { // Добавляем стили и скрипты add_action("wp_print_scripts", array(&$this, "site_load_scripts")); add_action("wp_print_styles", array(&$this, "site_load_styles")); add_shortcode("show_reviews", array (&$this, "site_show_reviews")); }

Разберем подробнее данный участок кода. Начнем с панели администрирования.
Функция «is_admin » проверяет в каком режиме сейчас мы работаем - на сайте или в панель управления.
Далее используется несколько хуков, для функций:

  • wp_print_scripts - Добавляем необходимые javascript файлы
  • wp_print_styles - Добавляем необходимые стили
  • admin_menu - Добавляем новое меню в панели управления

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

/** * Загрузка необходимых скриптов для страницы управления * в панели администрирования */ function admin_load_scripts() { // Регистрируем скрипты wp_register_script("advReviewsAdminJs", $this->plugin_url . "js/admin-scripts.js"); wp_register_script("jquery", $this->plugin_url . "js/jquery-1.4.2.min.js"); // Добавляем скрипты на страницу wp_enqueue_script("advReviewsAdminJs"); wp_enqueue_script("jquery"); } /** * Загрузка необходимых стилей для страницы управления * в панели администрирования */ function admin_load_styles() { // Регистрируем стили wp_register_style("advReviewsAdminCss", $this->plugin_url . "css/admin-style.css"); // Добавляем стили wp_enqueue_style("advReviewsAdminCss"); }

Здесь используются следующие функции.

Каждое действие зависит от переданного параметра «action», соответственно «edit» -редактирование отзыва, «submit» - сохранение отредактированного отзыва и «delete» - удаление отзыва.

Обмен данными со страницами отображения происходит через свойство объекта «data». Исходный код этих страниц будет выложен в архиве с данным модулем в конце статьи. Тут я их не буду вставлять, так как топик уже оказался достаточно большим.

На этом с панелью администрирования заканчиваем и переходит к отображению и добавлению отзывов со стороны пользователей.

Что бы указать wordpress, когда вызывать наш плагин, необходимо зарегистрировать «shortcode», что и было сделано в конструкторе нашего класса. Подробнее об этом .

Add_shortcode("show_reviews", array (&$this, "site_show_reviews"));

Теперь на любой странице сайта можно разместить вот такой код и это заставит выполнить указанную нами функцию (передается вторым параметром). Ниже представлен исходный код данной функции.

/** * Список отзывов на сайте */ public function site_show_reviews($atts, $content=null) { global $wpdb; if (isset($_POST["action"]) && $_POST["action"] == "add-review") { $this->add_user_review(); } // Выбираем все отзывы из Базы Данных $this->data["reviews"] = $wpdb->get_results("SELECT * FROM `" . $this->tbl_adv_reviews . "`", ARRAY_A); ## Включаем буферизацию вывода ob_start (); include_once("site_reviews.php"); ## Получаем данные $output = ob_get_contents (); ## Отключаем буферизацию ob_end_clean (); return $output; } private function add_user_review() { global $wpdb; $inputData = array("review_title" => strip_tags($_POST["review_title"]), "review_text" => strip_tags($_POST["review_text"]), "review_user_name" => strip_tags($_POST["review_user_name"]), "review_user_email" => strip_tags($_POST["review_user_email"]),); // Добавляем новый отзыв на сайт $wpdb->insert($this->tbl_adv_reviews, $inputData); }

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

Вот собственно и все. Теперь можно посмотреть, что у нас получилось. А скачать плагин и исходные коды можно вот .

Само собой это только пример создания плагина, но и сойдет как простая гостевушка, если ее немного доработать, например, добавить защиту от ботов и постраничный вывод. Удачного кодинга:)

Форма на сайте:

Панель управления плагином:

Редактирование отзыва:

Возможно также вам будет интересно: