Wordpres post type создание родительских отношений между типами. (hierarchical)

101

Задача заключается в том чтобы сделать родительское отношение, аналогично тому как работают pages (статические страницы).
В интернете много странных решений вплоть до функций преобразования URL.
Как реализовать иерархию через таксономию я до конца не разобрался.

Моя ситуация.
Есть проекты — projects. Необходимо сформировать разделы проектов по их категориям. Например design. А подкатегория дизайна — фирменный стиль, firm-style.

Итого конечный урл моего проекта должен быть /projects/design/firm-style/my-project-name.

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

Создаем post type. Ключевые параметры hierarchical, rewrite, supports

add_action( 'init', 'register_type_project' );
function register_type_project() {
   register_post_type( 'project', [
      'labels'             => [
         'name'               => 'Проекты',
         'singular_name'      => 'Проект',
         'menu_name'          => 'Проекты',
         'name_admin_bar'     => 'Проекты',
         'add_new'            => 'Добавить',
         'add_new_item'       => 'Добавить ',
         'new_item'           => 'Новый Проект',
         'edit_item'          => 'Редактировать Проект',
         'view_item'          => 'Открыть Проект',
         'all_items'          => 'Проекты',
         'search_items'       => 'Найти Проект',
         'parent_item_colon'  => 'Родительский Проект',
         'not_found'          => 'Проект не найден',
         'not_found_in_trash' => 'В корзине ничего нет'
      ],
      'public'             => true,
      'publicly_queryable' => true,
      'show_ui'            => true,
      'show_in_menu'       => true,
      'show_in_rest'       => true, // убирает гутенберг
      'show_in_admin_bar'  => false,
      'query_var'          => true,
      'capability_type'    => 'post',
      'capabilities'       => [
         'edit_post'          => 'edit_pages',
         'read_post'          => 'edit_pages',
         'delete_post'        => 'edit_pages',
         'edit_posts'         => 'edit_pages',
         'edit_others_posts'  => 'edit_pages',
         'publish_posts'      => 'edit_pages',
         'read_private_posts' => 'edit_pages',
      ],
      'has_archive'        => true,
      'menu_position'      => 10,
      'menu_icon'          => 'dashicons-screenoptions',
      'hierarchical'       => true, // иерархия
      'supports'           => [ 'page-attributes', 'title', 'thumbnail','editor' ], // page-attributes - блок редактирования родительского элемента
      'rewrite'            => [
         'slug' => 'projects',
      ]  // слаг для post type
   ] );
}

У нас появились проекты. Тут я уже сделал заранее разделы.

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

По нему можно выстроить иерархию среди категорий.
И соответственно добавляем наш проект в саму нижнюю категорию. Url преобразуется согласно иерархии.
Получили необходимый результат /projects/design/firm-style/my-project-name.
!ВАЖНО.
При работе с post-type и rewrite необходимо перезагрузить настройки ссылок через настройки Постоянные ссылки. Просто зайти и сохранить ничего не изменяя.

0
 

WordPress carbon fields как вывести поле в сайдбар

99

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

Положение контейнера определяется двумя параметрами.

Context.
Это часть страницы на которой контейнер должен отобразиться. По дефолту значение ‘normal’.
Но нам нужно положение ‘side’. Поэтому в отдельном контейнере переносим поле.

Container::make('post_meta', 'Доп поля (сайдбар)')
    ->set_context( 'side' )
    ->set_priority( 'low' )
    ->add_fields([
        Field::make( 'select', 'catalog_product_category', "Категория" )
            ->set_options( $cat_array )

    ]);

Priority. Это второй параметр, который видно по коду. Исходя из названия — приоритетность. То есть положение относительно других блоков, в частности дефолтных таких как: блок публикации, категории и тд.

Более подробно в документации.

https://docs.carbonfields.net/learn/containers/post-meta.html

Он же в свою очередь ссылается на стандартную функцию wordpress add_meta_box().

https://developer.wordpress.org/reference/functions/add_meta_box

0
 

WordPress установить CORS

98

Сниппет выглядет так. Добавляем общий фильтр с разрешенными сайтами.

/**
 * COORS
 */

add_filter('allowed_http_origins', 'add_allowed_origins');
function add_allowed_origins($origins)
{
    $origins[] = 'https://yourdomain.com';

    return $origins;
}
0
 

WordPress Carbon fields пофиксить кнопку «Выбрать изображениe»

112

Есть небольшая проблема с руссифицированным отображением поля картинки. Например:

Как видно кнопка выбрать изображение не совсем корректно помещается в поле. Конечно далее логичным шагом будет расширить поле по ширине.
Field::make('image', 'some-image', 'Изображение')
    ->set_width(100),
Мы видим, что поле расширилось. Но внутренний контейнер остался таким же. Не могу сказать с чем это связано. Но логично, что эта область например должна растянуться по ширине поля.
Немного пофиксим CSS. CSS класс называется .cf-file__inner. Он изолирован и будет относиться к изображениям и файлам, что будет так же актуально.

Добавим кастомный CSS для админки.

function my_admin_style() {
    echo  get_stylesheet_directory_uri().'/assets/css/myadmin.css';
    wp_enqueue_style('admin-styles', get_stylesheet_directory_uri().'/assets/css/myadmin.css');
}
add_action('admin_enqueue_scripts', 'my_admin_style');

И также код css.

.cf-file__inner{
    width: 100% !important;
}

Получаем результат.

0
 

Установка WordPress Мультисайт(multisite) на локальном сервере. Режим поддоменов.

408

Добрый день. Сегодня расскажу как поставить мультисайт на локальном сервере.

Для чего он нужен? Для организации подразделов или поддоменом, при этом используя только один инстанс WordPress (т.е один каталог CMS). Более подробно вы можете ознакомиться в документации.

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

Проблема

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

Итого мы имеем чисто установленный вордпресс на localhost.

Хорошо. Теперь переходим к установки мультисайта по документации.
Заходим в wp-config.php и проставляем объявление:

define( 'WP_ALLOW_MULTISITE', true );

Теперь у нас в панели инструментов появилась настройка сети.

Переходим. И тут мы и сталкиваемся с проблемой.
По идее по гайду у нас должен появится выбор между двумя режимами: поддомены и подкаталоги
https://wp-kama.ru/wp-content/uploads/2016/09/multisite-install2.png.

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

Решение

Я не нашел явного решения через локалхост и через MAMP. Возможно есть какой то подход.

Мое решение выглядет так. Не понимаю в чем ограничение localhost, возможно это связано с зарезервированым названием. Мы изменяем нашу сборку Docker.
В сервисе wordpress мы прописываем hostname — с названием нашего произвольного сайта.

version: '3'
services:
  db:
    image: mysql:8
    container_name: mysql
    restart: always
    command: "--default-authentication-plugin=mysql_native_password"
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: wpdb
      MYSQL_USER: user
      MYSQL_PASSWORD: password


  wordpress:
    image: wordpress:4.9.8
    container_name: wordpress
    restart: always
    volumes:
      - ./:/var/www/html/
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_NAME: wpdb
      WORDPRESS_DB_USER: user
      WORDPRESS_DB_PASSWORD: password
    hostname: mysite.ru
    ports:
      - 80:80
      # - 443:443

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    restart: always
    ports:
      - 3333:80
    environment:
      PMA_HOST: db
      MYSQL_ROOT_PASSWORT: password

Перзапускаем докер.
Отлично. Но нужно прописать алиас на локальной машине для нашего сайта. В Mac/Linux заходим директорию etc и выбираем файл hosts.

sudo nano /etc/hosts

Прописываем алиас и сохраняем от имени администратора.

Отлично теперь наш сайт доступен по урлу mysite.ru (или тот который вы прописали).

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

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

Жмем установить идем дальше по инструкции

После установки появляется стандартная панель по управлению сайтами.

Для проверки давайте добавим поддомен. У меня это будет test.
Его соответсвенно надо зарегистрировать в /etc/hosts

Все поддомен активен.

0
 

Установка WordPress через Docker. Простой docker-compose. (Install wordpress with docker-compose)

378

Создаем файл docker-compose.yml

Наша сборка будет состоять из 3-ех стандартных сервисов:

  • Сервис WordPress. Будет включать в себя сервер и файлы CMS
  • Сервис для БД, в нашем случае MySQL
  • Ну и так же поставим phpMyAdmin

Службы будут описаны и указаны в файле docker-compose.yml, который сначала необходимо создать в нашем каталоге:

mkdir wordpress-docker
cd wordpress-docker
touch docker-compose.yml

Можем открыть папку в любом удобном редакторе

У нас должен быть пустой файл docker-compose.yml внутри папки wordpress-docker. Открываем файл и прописываем сервис для mysql.

version: '3'
services:
  db:
    image: mysql:8
    container_name: mysql
    restart: always
    command: "--default-authentication-plugin=mysql_native_password"
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: wpdb
      MYSQL_USER: user
      MYSQL_PASSWORD: password

В разделе сервисов мы добавили первое, которое называется db. Этот сервис связан образом mysql и, следовательно, предоставляет необходимый экземпляр базы данных MySQL.

command: "--default-authentication-plugin=mysql_native_password"

Эта команда

Эта команда позволяет нам запустить базу с включенной собственной аутентификацией по паролю.
Кроме того, нам нужно установить следующие переменные среды: MYSQL_ROOT_PASSWORD, MYSQL_DATABASE, MYSQL_USER и MYSQL_PASSWORD. Можете прописать свои.

Добавляем WordPress сервис

Добавляем соотвествующий кусок кода описывающий сервис

wordpress:
    image: wordpress
    container_name: wordpress
    restart: always
    volumes:
      - ./:/var/www/html/
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_NAME: wpdb
      WORDPRESS_DB_USER: user
      WORDPRESS_DB_PASSWORD: password
    ports:
      - 8080:80
      - 443:443

Здесь мы используем образ wordpress. Вы можете указать любую версию вида wordpress:4.9.8. Я буду использовать последнюю актуальную.


Свойство volumes используется для подключения каталога /var/www/html контейнера к локальной папке приложения. Все изменения, которые мы будем вносит в файлы папки нашего приложения буду отображать сразу в контейнере.


Кроме этого, мы снова используем раздел environment для установки значений для четырех переменных: WORDPRESS_DB_HOST, WORDPRESS_DB_NAME, WORDPRESS_DB_USER и WORDPRESS_DB_PASSWORD.
Значение, присвоенное WORDPRESS_DB_HOST, должно быть идентификатором сервиса базы данных ( в нашем случае db).

И мы обязательно сопоставим внутренний порт 80 с внешним портом 8080, чтобы WordPress был доступен через http://localhost:8080.

Добавляем phpMyAdmin

Вставляем код

phpmyadmin:
    image: phpmyadmin/phpmyadmin
    restart: always
    ports:
      - 3333:80
    environment:
      PMA_HOST: db
      MYSQL_ROOT_PASSWORT: password

Здесь мы используем образ phpmyadmin/phpmyadmin (https://hub.docker.com/r/phpmyadmin/phpmyadmin).
Включаем доступ к базе данных для phpMyAdmin. Устанавливаем две переменные среды для этой службы:
PMA_HOST: необходимо указать имя службы базы данных (в нашем случае db)
MYSQL_ROOT_PASSWORD: необходимо установить пароль root MySQL (в нашем случае это просто password)

Внутренний порт 80 (на котором по умолчанию доступен phpMyAdmin) сопоставлен с внешним портом 3333, чтобы мы могли получить доступ к веб-интерфейсу пользователя phpMyAdmin с помощью URL http://localhost:3333 позже.

Итоговый файл docker-compose.yml

Это полная версия получившегося файла:

version: '3'
services:
  db:
    image: mysql:8
    container_name: mysql
    restart: always
    command: "--default-authentication-plugin=mysql_native_password"
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: wpdb
      MYSQL_USER: user
      MYSQL_PASSWORD: password


  wordpress:
    image: wordpress:4.9.8
    container_name: wordpress
    restart: always
    volumes:
      - ./:/var/www/html/
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_NAME: wpdb
      WORDPRESS_DB_USER: user
      WORDPRESS_DB_PASSWORD: password
    ports:
      - 8080:80
      - 443:443

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    restart: always
    ports:
      - 3333:80
    environment:
      PMA_HOST: db
      MYSQL_ROOT_PASSWORT: password

В целом все. Нам остается только запустить установщик наших сервисов:

docker-compose up

Заходим на наш http://localhost:8080 и получаем стартовую страницу установки:

Отлично все получилось.

0
 

WordPress, как получить слаг(путь) текущей страницы. (Wp how to get slug/path current page)

751

Предлагаю удобный сниппет. С его помощью можно легко получить текущий URL-адрес страницы на вашем сайте WordPress независимо от отображаемой страницы.

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

Так вернется полностью url. аналог функции get_site_url().

global $wp;
$current_url = home_url( add_query_arg( array(), $wp->request ) );

Так к примеру, если страница http://mysite.com/some-post, то вернется только слаг some-post.

global $wp;
$current_slug = add_query_arg( array(), $wp->request );

0
 

Woocommerce. Как получить данныe товаров (заголовок, описание, картинку, цену и тд).

491

Для этого нам потребуется woocommerce класс WC_Product{}(ссылка на документацию), а точнее его объект с использованием id продукта.

$wc_product = wc_get_product( $post->ID );

А дальше стоит переместиться на страницу документации и ознакомиться с методами. Я приведу пример вывода базовой информации.

Используя объект $wc_product, выводим заголовок (title):

 $title = $wc_product->get_name()

ссылку (get_permalink):

 $permalink = $wc_product->get_permalink()

короткое описание (short_description):

 $short_description = $wc_product->get_short_description()

цена (price):

 $price_html = $wc_product->get_price_html()
+1