• Как реализовать ajax постраничной навигации, нашел только дозагрузку?

    bootd
    @bootd
    Гугли и ты откроешь врата знаний!
    Ответ написан
    Комментировать
  • Как сделать показ изображения товара в Woocommerce с удалённого сервера (по ссылке) без загрузки файлов на свой хостинг?

    @kazakshent Автор вопроса
    Решил задачу сам. Постараюсь описать как сделал, вдруг у кого то появиться аналогичная потребность.
    Ставим WP All import, затем находим и добавляем бесплатную версию WP All import Woocommerce Add-on, смотрите внимательно, там есть бесплатная версия, которая позволяет реализовывать необходимый нам функционал. В моем csv файле был прописан столбец к каждому товару с url изображений со стороннего сайта, с которого необходимо было подгружать изображения не закачивая их на свой сервер.
    В настройках, при подготовке импорта в WP All Import (подробно о настройке импорта хорошая статья тут: https://www.reactiv.top/import-tovarov-csv-v-wooco... в атрибутах к товару прописываем в столбце Name произвольное имя например (изображение), а в значение копируем шорткод нашего столбца с url изображений (в инструкции по ссылке выше показано как это сделать) и убираем у атрибута видимость(просто убираем галочку). Далее настраиваем как нам надо и импортируем файл.
    После импорта. В файле wp-content/plugins/woocommerce/includes/wc-product-functions.php добавил функцию для вывода значения атрибута pictures(ссылка на изображение) productPicture (). Код функции далее:
    function productPicture (){
    	global $product;
    	$attribute_names = get_the_terms($product->get_id(), 'pa_picture');
    	$attribute_name = "pa_picture";
    	if ($attribute_names){
    		foreach ($attribute_names as $attribute_name):
    		echo $attribute_name->name;
    		endforeach;
    	}
    	}

    Эта функция возвращает нам значение заданного атрибута, в нашем случае это атрибут (pa_picture), на самом деле не важно как вы назовете атрибут, к нему просто добавляется приставка "pa_" впереди.
    Далее, в файле wp-content/plugins/woocommece/templates/single-product/product-image.php в src изображения добавил функцию productPicture (). Таким образом вывел изображения на подробных карточках товаров из внешнего источника. Далее код файла product-image.php :
    <?php
    /**
     * Single Product Image
     *
     * This template can be overridden by copying it to yourtheme/woocommerce/single-product/product-image.php.
     *
     * HOWEVER, on occasion WooCommerce will need to update template files and you
     * (the theme developer) will need to copy the new files to your theme to
     * maintain compatibility. We try to do this as little as possible, but it does
     * happen. When this occurs the version of the template file will be bumped and
     * the readme will list any important changes.
     *
     * @see     https://docs.woocommerce.com/document/template-structure/
     * @package WooCommerce/Templates
     * @version 3.5.1
     */
    
    defined( 'ABSPATH' ) || exit;
    
    // Note: `wc_get_gallery_image_html` was added in WC 3.3.2 and did not exist prior. This check protects against theme overrides being used on older versions of WC.
    if ( ! function_exists( 'wc_get_gallery_image_html' ) ) {
    	return;
    }
    
    global $product;
    
    $columns           = apply_filters( 'woocommerce_product_thumbnails_columns', 4 );
    $post_thumbnail_id = $product->get_image_id();
    $wrapper_classes   = apply_filters( 'woocommerce_single_product_image_gallery_classes', array(
    	'woocommerce-product-gallery',
    	'woocommerce-product-gallery--' . ( $product->get_image_id() ? 'with-images' : 'without-images' ),
    	'woocommerce-product-gallery--columns-' . absint( $columns ),
    	'images',
    ) );
    ?>
    <div class="<?php echo esc_attr( implode( ' ', array_map( 'sanitize_html_class', $wrapper_classes ) ) ); ?>" data-columns="<?php echo esc_attr( $columns ); ?>" style="opacity: 0; transition: opacity .25s ease-in-out;">
    	<figure class="woocommerce-product-gallery__wrapper">
    		<?php
    		if ( $product->get_image_id() ) {	
    			$html = wc_get_gallery_image_html( $post_thumbnail_id, true );
    		} else {
                      //МОИ ИЗМЕНЕНИЯ НАЧАЛО
    		    echo '<div class="woocommerce-product-gallery__image--placeholder">';
    		    echo "<img src='";
    			echo productPicture();
    			echo "' alt='Ваше изображение по умолчанию'>";
    			echo '</div>';
                   //МОИ ИЗМЕНЕНИЯ КОНЕЦ
    		}
    
    		echo apply_filters( 'woocommerce_single_product_image_thumbnail_html', $html, $post_thumbnail_id ); // phpcs:disable WordPress.XSS.EscapeOutput.OutputNotEscaped
    		do_action( 'woocommerce_product_thumbnails' );
    		?>
    	</figure>
    </div>

    Далее нам нужно продублировать эти изображения в нашем каталоге, что бы не только в подробном описании продукта, но и в каталоге на карточках товара выводилось изображение.
    Делаем следующее. В файле wp-content/plugins/woocommerce/includes/wc-product-functions.php изменяем функцию wc_placeholder_img( $size = 'woocommerce_thumbnail' ), реализующую вывод изображений в каталоге товаров, в значение src для img добавил функцию productPicture (). Таким образом вывел изображения товаров в каталоге из внешнего источника. Код функции далее:
    function wc_placeholder_img( $size = 'woocommerce_thumbnail' ) {
    	$dimensions        = wc_get_image_size( $size );
    	$placeholder_image = get_option( 'woocommerce_placeholder_image', 0 );
    
    	if ( wp_attachment_is_image( $placeholder_image ) ) {
    		$image_html = wp_get_attachment_image(
    			$placeholder_image,
    			$size,
    			false,
    			array(
    				'alt'   => __( 'Placeholder', 'woocommerce' ),
    				'class' => 'woocommerce-placeholder wp-post-image',
    			)
    		);
    	} else {
                     //ТУТ МЫ КОММЕНТИРУЕМ СТАНДАРТНЫЕ ЗАПИСИ ФУНКЦИИ КОТОРЫЕ НАМ НЕ НУЖНЫ
    		//$image      = wc_placeholder_img_src( $size );
    		//$image_html = '<img src="' . esc_attr( $image ) . '" alt="' . esc_attr__( 'Placeholder', 'woocommerce' ) . '" width="' . esc_attr( $dimensions['width'] ) . '" class="woocommerce-placeholder wp-post-image" height="' . esc_attr( $dimensions['height'] ) . '" />';
             //МОИ ИЗМЕНЕНИЯ НАЧАЛО
    	    echo '<img src="';
    		echo productPicture();
    		echo '" alt="Заполнитель" width="';
    		echo esc_attr( $dimensions['width'] );
    		echo '" class="woocommerce-placeholder wp-post-image" height="';
    		echo esc_attr( $dimensions['height'] );
    		echo '">';
                   //МОИ ИЗМЕНЕНИЯ КОНЕЦ
    	}
    
    	return apply_filters( 'woocommerce_placeholder_img', $image_html, $size, $dimensions );
    }

    Таким образом мы выводим изображения без скачивания их на сервер, и не захламляем его. Главное не забывайте сделать Бекап, потому что данные изменения пропадут после обновления и нужно будет их снова вносить. Если будут вопросы или советы пишите их в комментариях, постараюсь ответить и буду рад советам!
    Ответ написан
  • Как изменять поля в зависимости от вида заказа?

    wppanda5
    @wppanda5 Куратор тега WordPress
    WordPress Mедведь
    хук woocommerce_checkout_shipping https://github.com/woocommerce/woocommerce/blob/6b...
    или woocommerce_checkout_fields
    https://github.com/woocommerce/woocommerce/blob/60...

    кастомизация формы доставки https://docs.woocommerce.com/document/tutorial-cus...

    вешаться надо сюда woocommerce_shipping_method_chosen
    https://github.com/woocommerce/woocommerce/blob/52...

    Пример кода https://stackoverflow.com/a/37073395
    Ответ написан
    Комментировать
  • Как вынести wp-config.php и wp-content за пределы папки c ядром wordpress?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    https://github.com/ihorvorotnov/sonata

    Давно не обновлял код, многое нужно освежить, но концепция думаю понятна.

    Что важно понять - просто разложить отдельно вообще в разных местах темы и все остальное не получится, разве что симлинками. Ядро будет искать конфиг на 2 уровня вверх, некоторые пути (контент, как вы уже поняли) будут отсчитываться от рута (где конфиг).
    Ответ написан
    2 комментария
  • Wordpress сам дописывает адрес ссылки. Как это изменить?

    cesnokov
    @cesnokov
    <head>&nbsp;</head>
    Это называется "URL Guessing", чтоб его отключить - нужно в functions.php добавить:
    remove_filter( 'template_redirect', 'redirect_canonical' );

    Если Вы не хотите отключать "Canonical URL", то добавить надо:
    function remove_redirect_guess_404_permalink( $redirect_url ) {
       if ( is_404() ) { return false; }
       return $redirect_url;
    }
    add_filter( 'redirect_canonical', 'remove_redirect_guess_404_permalink' );

    А если совсем простой способ нужен то вот плугин:
    https://ru.wordpress.org/plugins/disable-url-autoc...
    Ответ написан
    Комментировать
  • Отсортировать посты по месяцам WP?

    Beeetle
    @Beeetle
    WPKama дает ответ на ваш вопрос
    Ответ написан
    Комментировать
  • Как изменить перечень товаров в уже составленном заказе Woocommerce?

    @weart
    add_filter( 'wc_order_is_editable', '__return_true' );


    5d9221ebc7233236709581.png
    Ответ написан
    Комментировать
  • Как отображать разное меню в Wordpress?

    tuxfighter
    @tuxfighter
    троль
    Комментировать
  • Как оптимизировать магазин на WP под PageSpeed Insights?

    alexandrpavlovv
    @alexandrpavlovv
    Люблю Русь изначальную
    На счет того, что сервис фейковый немного громко звучит, но доля правды есть точно)
    В первую очередь проверьте по указанным сервисам от tuxfighter, а еще можете web.dev посмотреть.

    Но, до этого гляньте как Google смотрит на сайт в GSC, какой процент отказов в Метрике и Аналитике. Есть ли у людей (посетителей) реальные проблемы со скоростью загрузки вашего сайта. Плюс хостинг гляньте - он тоже тормозить может.
    Ответ написан
    Комментировать
  • Как скрыть контент и показывать только после ввода кода?

    V_A_B
    @V_A_B
    ¯\_(ツ)_/¯
    Зачем же сразу плагины? Можно, например, использовать сессию. Не забываем, что сессию и куки объявляем до вывода любой информации:
    <?php session_start();#Template Name: Загрузка файлов из списка на сервер с новым именем
    get_header();
    	if(have_posts()):
    		while(have_posts()):the_post();
    			get_template_part('VAB_template_parts/forms/VAB','FilesLoadServer');
    		endwhile;
    	endif;
    get_sidebar();get_footer();

    Ну и сам собственно код куда-нибудь:
    if(!function_exists('VAB_Authentication()')){function VAB_Authentication(){
    $pass='session_password';//это пароль
    $errorSession='';
    	if(isset($_POST['pass_value'],$_POST['pass_btn'])){
    		if($pass==$_POST['pass_value']){$_SESSION['unique_ProtecT']=true;
    		}else{$_SESSION['ProtecT']=false;$errorSession='<div title="'.__('Неверный пароль!','VAB').'">'.__('Неверный пароль!','VAB').'</div>';}}
    	if(empty($_SESSION['unique_ProtecT'])){?>
    		<div class="contact_message">
    			<div class="ProtecT">
    				<center>
    					<h4><?php echo $errorSession;printf(__('Страница для Администрации','VAB'));?></h4>
    					<form method="POST">
    						<div><?php printf(__('Введите пароль','VAB'));?>:&nbsp;&nbsp;&nbsp;<input type="text" name="pass_value" size="30" />&nbsp;&nbsp;&nbsp;<input type="submit" value="<?php printf(__('Ввод','VAB'));?>" name="pass_btn" />
    						</div>
    					</form>
    					<br><a href="<?php bloginfo('url');?>"><?php printf(__('Отмена','VAB'));?></a>
    				</center>
    			</div>
    		</div>
    <?php }}}
    if(function_exists('VAB_Authentication')):VAB_Authentication();endif;

    Вариант, где пароль устанавливается через кастомайзер или какой-либо раздел по управлению темой. В данном случае через мой раздел по управлению темой...:
    if(VABMoD('VAB_pass_session'))://если в опции есть какое-либо значение, то пароль есть значение опции
         $pass=VABMoD('VAB_pass_session');
    else://иначе пароль по умолчанию
        $pass='session_password';
    endif;

    Мы можем используя данную функцию просто затемнить экран(но вся разметка будет доступна в инженерной панели):
    5d4061ac7d5e0375154361.jpeg
    либо после вызова функции остановить все скрипты:
    if(function_exists('VAB_Authentication')):VAB_Authentication();endif;
    exit();//завершает все скрипты после... в том числе и сайдбары и футер и т.д.

    5d4061e606bfc663618253.jpeg
    или комбинируем оба варианта(оформляем, наводим красоту... баннеры на бакграунд и прочую чех**ню)
    Помимо можно просто обернуть блок, который необходимо скрыть в проверку:
    if(isset($_SESSION['unique_ProtecT'])&&$_SESSION['unique_ProtecT']==true){
    //скрытый контент(включая инженерную панель разумеется)
    }
    Ответ написан
    Комментировать
  • Какие плагины вы считаете стандартными для работы в WordPress?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Как уже написали, универсального набора не существует, ибо задачи разные. Но есть некоторые наметки по этому поводу. Сразу оговорюсь - у меня всех без исключения WP-проекты построены на базе Composer, зависимостями (а плагины ими и являются) управлять просто и удобно, плюс autoload. Это позволяет динамически включать-выключать плагины в зависимости от переменных среды или feature flags. А теперь сами плагины. Разобьем им сразу на 2 категории - development и production. Первые нужны для облегчения разработки и отладки проекта, вторые - всегда.

    Development-only плагины:

    - Query Monitor
    - Transients Manager
    - WP Crontrol
    - Airplane Mode
    - Debug wp_redirect
    - User Switching
    - Rewrite Rules Inspector
    - rarst/wps (обертка для Whoops)
    - rarst/laps (профайлер)
    - Regenerate Thumbnails
    - Парочка кастомных mu-plugins которые облегчают жизнь (обертка для symfony/var-dumper и тд)

    Production:

    - ACF Pro
    - Кеширование - WP Super Cache, Batcache, WP Fastest Cache. Redis/Memcached для объектного кеша (все есть от именитых команд типа 10Up, Humanmade и тд) - какой конкретно зависит от проекта
    - Для форм использую свою наработку, HTML чистый который делает верстальщик, обработчик - своя кухня которая использует внешний transactional email service (SendGrid, Amazon SES и другие - адаптеры пишутся по необходимости) с их темплейтами для писем, использует composer-библиотеки для валидации и тд. Для всех форм также создается custom post type, все сабмишны пишутся туда с логом (сами данные формы, статус отправки транзакционного письма, лог мейлера и тд - удобно для отладки). На первый взгляд звучит сложно, но благодаря ООП-архитектуре по принципу Laravel / Laravel Nova все настраивается буквально за считанные минуты. Но если бы использовал готовый плагин, то скорее всего CF7.
    - Disable Comment - потому что на большинстве сайтов они не нужны
    - Classic Editor - потому что все еще не везде подходит/заходит Gutenberg
    - Duplicate Post - удобно для работы с контентом, активируется по необходимости
    - Enable Media Replace - иногда полезен, активируется по необходимости
    - EWWW Image Optimizer Cloud - удобно, дешево
    - Lazy Load Optimizer - полезная штука для frontend performance
    - Safe SVG - SVG сейчас везде, так что без него никуда
    - Cyr-To-Lat - если сайт кириллический / мультиязычный
    - Для мультиязычных сайтов чаще всего останавливаемся на WPML
    - ElasticPress - для поиска/фильтров
    - WP-Minions или Cavalcade - для асинхронных фоновых задач
    - humanmade/S3-Uploads - для медиа-библиотеки в S3

    Дальше, для разных задач есть свои "фавориты" и/или свои кастомные наработки.

    Ну и, конечно же, WP CLI.
    Ответ написан
    Комментировать
  • Как правильно защитить REST маршрут?

    deniscopro
    @deniscopro Куратор тега WordPress
    WordPress-разработчик, denisco.pro
    В WordPress есть обертка для Ajax-запросов к REST API. Можете подключить её в свою тему
    wp_enqueue_script( 'wp-api-request' );

    Ну и потом использовать аналогично jQuery Ajax
    wp.apiRequest({
    	method: 'post',
    	path: 'my-form/send/',
    	data: data,
    	success: function (response) {
    		console.log(response);
    	}
    });

    WordPress сам сгенерирует и отправит csrf-токен по заголовку X-WP-Nonce.

    Подробнее как устроен враппер можно посмотреть в исходниках.
    Ответ написан
    3 комментария
  • Как перевести русский плагин на остальные языки?

    OtshelnikFm
    @OtshelnikFm Куратор тега WordPress
    Обо мне расскажет yawncato.com
    Ждать пока кто-то переведет - бред. Сами ждали. Потом на фрилансе заказали перевод

    Но минус у такого подхода: это разово. Перевод как правило меняется, добавляется, а следить за этим фрилансер не будет (ну и стремно просить выполнить еще раз работу ради 3-5 новых строк с оплатой в 100р). Или брать его на ставку к себе и назначать его редактором локали - тогда при выходе новой версии он оперативно поправит перевод.

    Вариант второй - уже сейчас у каждого языка в сервисе translate.wordpress.org есть PTE - переписывайтесь с ними в слеке - завербуйте их. Ну в общем с ними можно договориться $

    Вариант 3: сервисы профессиональных переводчиков специализирующиеся на вордпресс.
    Например daytranslations.com
    или список тут https://wpml.org/translation-service/
    Ответ написан
    1 комментарий
  • Как используя VBScript конвертировать xls и xlsx файлы в xml без установленного Excel?

    @domanskiy Автор вопроса
    Разобрался.
    'Читаем данные из XLS файла
    Dim connStr, objConn, getNames, inputFile 
    inputFile  = test.xls
    connStr = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & inputFile & ";Extended Properties=""Excel 12.0 xml;HDR=No;IMEX=2;"";"
    
    Set objConn = CreateObject("ADODB.Connection")
    'Open Connection
    objConn.open connStr
    
    'Define recordset and SQL query
    'тут мы через SQL запрос вытаскиваем данные из ИМЕННЫХ ячеек экселевского файла. Всё это в массив
    Set rs = objConn.execute("SELECT * FROM Job,Customer,Prod")
    
    'присваиваем значения переменным из массива
    DO WHILE NOT rs.EOF
    Job = rs.Fields(0)
    Customer = rs.Fields(1)
    Prod = rs.Fields(2)
    rs.MoveNext
    Loop
    
    'Close connection XLS and release objects
    objConn.Close
    Set rs = Nothing
    Set objConn = Nothing
    
    'формируем XML
    Dim  rootNode, subNode, xmlDoc, commentItem, Fragment
    Set xmlDoc = CreateObject("Msxml2.DOMDocument")
    'Создание объявления XML
    xmlDoc.appendChild(xmlDoc.createProcessingInstruction("xml", "version='1.0' encoding='utf-8'"))
    
    'Создание корневого элемента
    Set rootNode = xmlDoc.CreateElement("JOBS")
    xmlDoc.AppendChild rootNode
    
    Set subNode = rootNode.appendChild(xmlDoc.createElement("Job"))
    subNode.text = Job
    
    Set subNode = rootNode.appendChild(xmlDoc.createElement("Customer"))
    subNode.text = Customer
    
    Set subNode = rootNode.appendChild(xmlDoc.createElement("Prod"))
    subNode.text = Prod
    
    '* -- написание XML-файла с отступом для более легкого использования независимо от того, какая программа использовалась для просмотра или редактирования файла -- *'
    Dim rdr, wrt, oStream
    Set rdr = CreateObject("MSXML2.SAXXMLReader")
    Set wrt = CreateObject("MSXML2.MXXMLWriter")
    
    Set oStream = CreateObject("ADODB.STREAM")
    oStream.Open
    oStream.Charset = "UTF-8"
     
    wrt.Indent = True
    wrt.Encoding = "UTF-8"
    wrt.Output = oStream
    Set rdr.ContentHandler = wrt
    Set rdr.ErrorHandler = wrt
    rdr.Parse xmlDoc
    wrt.Flush
    
    'запись xml файла
    oStream.SaveToFile "Test.xml", 2
    
    Set rdr = Nothing
    Set wrt = Nothing
    Ответ написан
    4 комментария
  • Как менять структуру CSV автоматически?

    akelsey
    @akelsey
    Powershell:
    Import-Csv mysource.csv | select field1,field2,field3 | Export-Csv mydest.csv -Encoding utf8
    Ответ написан
    1 комментарий
  • Как вывести количество дочитываний статьи в Вордпрессе?

    deepblack
    @deepblack
    Внизу каждой статьи разместить элемент (или привязаться к уже существующему), и на JS проверять его нахождение во viewport,
    если элемент входит во viewport, уведомлять об этом сервер, на кастомный роут.
    + можно дабавить проверку того, сколько пользователь находился на странице (для того чтобы отсеять пролистывание вниз сразу после открытия страницы).
    Т.е. если время чтения материала 9 минут (в среднем), убираем 20-30 % (кто-то может и быстрее читать),
    и далее совмещаем с проверкой нахождения во viewport.

    JavaScript: Is element in viewport?
    /*
    No jQuery necessary.
    Thanks to Dan's StackOverflow answer for this:
    http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport
    */
    
    function isElementInViewport(el) {
      var rect = el.getBoundingClientRect();
      return (
        rect.top >= 0 &&
        rect.left >= 0 &&
        rect.bottom <= (window.innerHeight || document. documentElement.clientHeight) &&
        rect.right <= (window.innerWidth || document. documentElement.clientWidth)
      );
    }
    Ответ написан
    Комментировать
  • Бесплатная тема wp?

    nonname
    @nonname
    Всем известно что темы делаются за 5 минут, практически без труда, а разработчики просто из жадности просят за них большие деньги. Думаю нужно найти контакты разработчика и потребовать выдать вам тему бесплатно, ведь она вам понравилась, это неоспоримый аргумент. Если это не поможет, то можно пожаловаться на него в спортлото, я слышал это помогает. Главное не идти у злодеев на поводу и требовать, не платить ни в коем случае!
    Разработчики просто обязаны раздавать результаты своей работы бесплатно, ведь это просто информация, она ничего не стоит и может быть скопирована сколько угодно раз.
    Ответ написан
    2 комментария
  • Как исправить страницы в Google?

    irynashvets
    @irynashvets
    Вы наверное про микроразметку Schema AggregateRating и быстрые ссылки?

    5d5b9f8b6346a009963102.png
    Ответ написан
    Комментировать
  • Плагины или инструменты для мониторинга посещаемости в Wordpress?

    У меня проверка проходит так (код вроде брал из плагина wp-kama, точно не помню):

    global $user_ID;
    $who_count    = 1;	// 0 - считать всех, 1 - только гостей, 2 - только зарегистрированных пользователей
    $exclude_bots = 1;	// 0 - считать всех, 1 - исключить из подсчета ботов
    
    # Проверка пользователя: гость или зарегистрирован
    $should_count = false;
    switch( (int)$who_count ) {
    	case 0: $should_count = true;
    		break;
    	case 1:
    		if( (int)$user_ID == 0 )
    			$should_count = true;
    		break;
    	case 2:
    		if( (int)$user_ID > 0 )
    			$should_count = true;
    		break;
    }
    
    # Проверка на браузер или не бот, иначе false
    if( (int)$exclude_bots == 1 && $should_count ){
    	$useragent = $_SERVER['HTTP_USER_AGENT'];
    	$notbot = "Mozilla|Opera"; //Chrome|Safari|Firefox|Netscape - все равны Mozilla
    	$bot = "Bot/|robot|Slurp/|yahoo"; //Яндекс иногда как Mozilla представляется
    	if ( !preg_match("/$notbot/i", $useragent ) || preg_match( "!$bot!i", $useragent ) )
    		$should_count = false;
    }
    Ответ написан
    Комментировать