«правильный» файл robots.txt

<FilesMatch «\.md5$»>
Deny from all

DirectoryIndex index.php
Options -Indexes
# Comment the following line, if option Multiviews not allowed here
Options -MultiViews

AddDefaultCharset utf-8
RewriteEngine On
# Uncomment the following line, if you are having trouble
#RewriteBase /

RewriteCond %{REQUEST_URI} !\.(js|css|jpg|jpeg|gif|png|svg|ttf|eot|otf|woff|woff2)$ [or]
RewriteCond %{REQUEST_URI} apple-touch-icon\.png$ [or]
RewriteCond %{REQUEST_METHOD} ^(POST|PUT|COPY|MOVE|DELETE|PROPFIND|OPTIONS|MKCOL)$ [or]
RewriteCond %{HTTP:Translate} ^.+$ [or]
RewriteCond %{HTTP_USER_AGENT} ^(DavClnt|litmus|gvfs|davfs|wdfs|WebDAV|cadaver|Cyberduck)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^(.*)$ index.php [L,QSA]
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} !robots.txt
RewriteCond %{HTTP:X_FORWARDED_PROTO} !^https$
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
<FilesMatch «\.(jpg|jpeg|png|gif|js|css|svg|ttf|eot|otf|woff|woff2)$»>
Header set Cache-Control «max-age=3153600, public»

Плагины для WooCommerce

Наименование/Ссылка Краткое описание

Advanced Orders Export For WooCommerce — Экпорт в Excel/CSV/XML/Json file.
Booster for WooCommerce — Универсальный плагин со множеством возможностей, твиков и настроек.
Flat Rate per State/Country/Region for WooCommerce — Установка единых тарифов на доставку по странам и регионам.
Instant Search + for WooCommerce Search — Быстрый поиск для товаров.
Instock Email Alert for Woocommerce — Уведомления на почту о поступлении товара в продажу.
Product Enquiry for WooCommerce — Задать вопрос со страницы товара.
Product Import Export for WooCommerce — Импорт/Экспорт продуктов.
Saphali Woocommerce Russian — Универсальный плагин с доп. корректировками по славянским языкам и валютам.
Smart Manager for WooCommerce & WPeC — Таблица с товарами и быстрое редактирование их свойств.
Testimonials by WooThemes — Отзывы покупателей.
VKMarket for WooCommerce — Синхронизация с магазином в соц. сети VK.
WooCommerce — Store Toolkit — Инструмент для разработчиков плагинов для WC.
WooCommerce — Table Rates — Добавление таблиц с рассчетной стомостью доставки.
WooCommerce — Webmoney Payment Gateway — Оплата через Вебмани.
Woocommerce Abandoned Cart Lite — Плагин помогающий вам вернуть клиентов которые заполнили корзины, но не стали ничего покупать.
WooCommerce Advanced Free Shipping — Дополнительные условия для бесплатной доставки
WooCommerce Advanced Product Quantities — Правила для ограничений при покупке товаров
Woocommerce Ajax add to cart for variable products — Добавление в корзину через AJAX для вариативных товаров
WooCommerce and 1C:Enterprise/1С:Предприятие Data Exchange — Обмен данными с 1С
WooCommerce Bulk Discount — Система скидок для корзины
Woocommerce Catalog — Включение режима «Каталог» в магазине
WooCommerce Currency Switcher — Переключатель различных валют
WooCommerce Customizer — Кастомизатор для некоторых стандартных параметров и текстов в магазине
WooCommerce Expand Tabs — Дополнительный табы на странице продукта
WooCommerce Extended Coupon Features — Расширение функционала для скидочных купонов
WooCommerce Grid / List toggle — Переключатель вывода товаров сеткой ли списком
WooCommerce Menu Cart — Отображение корзины в основном меню навигации
WooCommerce More Sorting — Дополнительные сортировки для товаров
WooCommerce PDF Invoices — Счета фактуры печать и отправка
WooCommerce PDF Invoices & Packing Slips — Счета фактуры печать и отправка
WooCommerce Product Archive Customiser — Настройщик вывода архивов с товарами
WooCommerce Product SKU Generator — Генератор артикулов
WooCommerce Product Slider — Слайдер продуктов
WooCommerce Products Carousel all in one — Слайдер-карусель товаров
WooCommerce Products Filter — Фильтр, сортировка для товаров
Woocommerce Products Slider — Слайдер для продуктов
Woocommerce Quick Buy — Быстрая покупка с редиректом сразу на страницу оформления заказа
Woocommerce Role Based Price — Цена на товары в зависимости от ролей пользователей
WooCommerce Table Rate Shipping by Mangohour — Рассчитать стоимость доставки в зависимости от пункта назначения, веса и/или корзина товаров.
WooDiscuz — WooCommerce Comments — Продвинутые комментарии/дискуссия к товарам
WooSidebars — Дополнительный сайдбары на сайте
WooCommerce Wholesale Prices — Цены для оптовых покупателей
XO10 — WooCommerce Categories widget — Настройка виджета для категорий с картинками
YIKES Custom Product Tabs for WooCommerce — Дополнительный таб на странице товара
YITH WooCommerce Cart Messages — Сообщения в корзине покупателя
YITH WooCommerce Compare — Сравнение различных товаров для покупателя
YITH WooCommerce Custom Order Status — Добавление и редактирование статусов заказов
YITH WooCommerce Multi-step Checkout — Пошаговый помощник при оформлении заказа
YITH WooCommerce Quick View — Быстрый просмотр товара в окне без перехода на его страницу
YITH WooCommerce Wishlist — Создание списка желаний покупателя из отобранных товаров
YITH WooCommerce Zoom Magnifier — Эффект увеличения (лупы) при наведении на карточку товара
YITH Essential Kit for WooCommerce #1 — Подборка в админке всех плагинов от YITH для быстрой установки
===============

Белок старлайн

Запись нового брелка:
1.При выкл.зажигании нажать сервисную кнопку Valet 7 раз.
2.Включить зажигание. Последуют 7 сигналов сирены и 7 вспышек светодиода, подтверждающих вход в режим программирования брелков.
3.Не позже 10 сек. нажмите на брелке одновременно кнопки 1 и 2 и дождитесь подтверждения записи одиночным сигналом сирены.
4.Пропишите все брелки, которые используете, повторив п.3

10 правил питча

10 правил питча

1. У вашего продукта не может не быть конкурентов. Забудьте слова «уникальный» и «не имеющий аналогов».

2. Если у людей есть такая потребность, то они ее уже как-то удовлетворяют. Теми же способами, которые предлагаете и вы – прямые конкуренты. Или другими способами, но ту же потребность – непрямые конкуренты.

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

4. Если нет прямых конкурентов, то высока вероятность того, что они были, но умерли, потому что экономика такой бизнес-модели не сходится. Не знаете их конкретно – не беда. Предположите, что они были и подумайте, почему их экономика не сошлась. Расскажите, чем ваша бизнес-модель будет отличаться.

5. Начинайте рассказ о своем продукте с рассказа о чужих продуктах. Кто ваши основные конкуренты? По какому параметру ваш продукт лучше с точки зрения потребителя?
Это первый переломный момент. Если вы не рассказали про конкурентов и не объяснили, чем вы лучше их, то дальше слушать неинтересно – либо потребности нет, либо вы не понимаете ничего про потребности и конкуренцию, либо не умеете гуглить.

6. Вы можете быть лучше, чем конкуренты, только за счет того, что вы что-то делаете по-другому или у вас есть нечестное конкурентное преимущество. Нельзя быть лучше, потому что вы что-то делаете лучше.
Это второй переломный момент. Если у вас нет «чего-то другого» или «нечестного преимущества» – то разговаривать дальше не о чем, в продукте нет внутренней ценности, вы просто планируете построить свой маленький свечной заводик на чужие деньги.

7. Где деньги? Опираться на юнит-анализ. Средний чек, стоимость привлечения, экономика одного заказа. Если есть заказы от друзей, знакомых – не катит. Если бизнес хочет и может расширяться, то способы привлечения клиентов могут быть только платными. Фраза «мы не потратили на маркетинг ни копейки» является стоп-словом.
Это третий переломный момент. Если вы не знаете, где будете искать клиентов, если вы не понимаете, во сколько вам один покупатель будет обходиться, то, вероятнее всего, вы будете терять деньги на каждом заказе. Вкладываться в планово убыточный проект – неинтересно. Ждать волшебного момента «когда о нас узнают все» – денег не хватит.

8. Что вы сделали для того, чтобы проверить вашу гипотезу о том, что ваше «по-другому» действительно «лучше» для потребителя? Ссылки на американские аналоги не катят. Интересует только то, что сделали лично вы с командой. Опросы друзей и знакомых не катят. «Предварительные разговоры с клиентами» не катят. Minimum viable product – это о продажах, а не о разговорах.

9. Если вы не смогли сделать minimum viable product для проверки гипотезы своими силами и своими ресурсами, то у вас неполноценная команда. Либо вы не умеете придумать минимальный продукт, а значит вы будете постоянно требовать и прожирать деньги на постройку космолета. Либо у команды нет полного набора ключевых компетенций.
Это четвертый и последний переломный момент. Инвестируют не в идею, а в команду. Если команда неполноценная, то инвестировать не во что.

10. Все остальное – только после этой черты. Показывать продукт – здесь. Детали того, как устроен ваш проект – здесь. Что вы хотите – денег, опыта, связей – тоже только здесь.
—-
Антистартап в это воскресенье: http://antistartup.darkside.vc
—-
Взято отсюда https://www.facebook.com/amoreynis/posts/10153797156941511

Проблема WordPress WP-ADMIN You do not have sufficient permissions to access this page.

Сегодня встала незадача, после переноса перестала открываться панель администратора. Оказывается в вордпрессе не достаточно поменять в файле wp-config.php префикс таблиц. Необходимо так же изменить и некоторые записи.

UPDATE `{%TABLE_PREFIX%}usermeta` SET `meta_key` = replace(`meta_key`, '{%OLD_TABLE_PREFIX%}', '{%NEW_TABLE_PREFIX%}');
UPDATE `{%TABLE_PREFIX%}options` SET `option_name` = replace(`option_name`, '{%OLD_TABLE_PREFIX%}', '{%NEW_TABLE_PREFIX%}');

Больше деталей по ссылке  You do not have sufficient permissions to access this page without any change

Полная инструкция по SEO оптимизации интернет-магазина (перепечатано)

http://forum.opencart-russia.ru/threads/polnaja-seo-optimizacija-onlajn-magazina-na-opencart-2-0.551/

 

1. После установки обязательно включите SEO (система- Настройка- Сервер — Тип ЧПУ – Включаем)
01.png

2. .Htaccess

RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\ HTTP/
RewriteRule ^index\.html$ / [R=301,L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\ HTTP/
RewriteRule ^index\.php$ / [R=301,L]
RewriteCond %{QUERY_STRING} ^route=common/home$
RewriteCond %{REQUEST_METHOD} !^POST$
RewriteRule ^index\.php$ http://%{HTTP_HOST}? [R=301,L]
3. Ставим дополнительный модуль для SEO. Это может быть SEOPro или любой другой. Я советую Complete SEO 55$

Настройки Complete SEO

3.2 Если сайт мультиязычный делаем так, если обычный не отрогаем

03-2.png

3.3. Если сайт мультиязычный включаем, если нет не трогаем
03-3.png

3.4 Заполняем данные для главной страницы (title, Meta Description, Meta Keywords). Если несколько языков, заполняем и их.
03-4.png

3.5 Настройки хлебных крошек
03-5.png

3.6 Для Вашего удобства есть (SEO редактор) — таблица где вы можете прописать URL, Title, Meta Description, Meta Keywords и другие значения). Заполните все по максимуму и исключите дубли. Аналогично делаем для Категорий, товаров, Статей, Производителей. Проверить результат можна на (http://audit.megaindex.ru или http://saitreport.ru за $)
03-6.png

3.7 Создаем короткие URL в разделе SEO редактор — Стандартные страницы.
‘route=account/account’ => ‘my-account’,
‘route=account/address’ => ‘address-book’,
‘route=account/edit’ => ‘edit-account’,
‘route=account/forgotten’ => ‘forgot-password’,
‘route=account/login’ => ‘login’,
‘route=account/logout’ => ‘logout’,
‘route=account/newsletter’ => ‘newsletter’,
‘route=account/order’ => ‘order-history’,
‘route=account/password’ => ‘change-password’,
‘route=account/register’ => ‘create-account’,
‘route=account/return’ => ‘returns’,
‘route=account/return/insert’ => ‘request-return’,
‘route=account/reward’ => ‘reward-points’,
‘route=account/transaction’ => ‘transactions’,
‘route=account/wishlist’ => ‘wishlist’,
‘route=checkout/cart’ => ‘shopping-cart’,
‘route=checkout/checkout’ => ‘checkout’,
‘route=checkout/simplecheckout’ => ‘cart’,
‘route=checkout/voucher’ => ‘gift-vouchers’,
‘route=common/home’ => ‘/’,
‘route=information/sitemap’ => ‘sitemap’,
‘route=product/compare’ => ‘compare-products’,
‘route=product/manufacturer’ => ‘brands’,
‘route=product/search’ => ‘search’,
4.Задаем шаблон для title. У меня title повторяется, меняется только название и артикул товара. Открывает файл
vqmod\xml\seo_package.xml
, находим
$this->document->setTitle(!empty($product_info[‘meta_title’])
и делаем все что угодно. у меня строчка выглядит так:

$this->document->setTitle(!empty($product_info[‘meta_title’]) ? $this->language->get(‘title01′) .’ ‘. $product_info[‘meta_title’].’, ‘.$this->language->get(‘title02′).’ ‘. $product_info[‘model’] .’ — ‘. $this->language->get(‘title03′) .’ ‘. mb_substr($product_info[‘price’], 0, -5) : $product_info[‘name’]);
4.1.
$this->language->get(‘title01’)
— Прописанная фраза в
/catalog/controller/product/product.php
$data[‘title01’] = $this->language->get(‘title01’);
и
catalog/language/russian/product/product.php
$_[‘title01’] = ‘Купить’;
Если у Вас сайт на 1 языке можете смело писать в коде

4.2.
.’ ‘.
— Пробел

4.3
$product_info[‘model’]
— Модель товара (артикул)

4.4
mb_substr($product_info[‘price’], 0, -5)
— Обрезаная цена товара
В итоге у меня получается
«Купить Товар, модель 113920 — Цена 3800»
Нажмите, чтобы раскрыть…
Вы так же можете добавить рубль или другую валюту ручками.
У меня вопрос к экспертам, как добавить сюда Валюту (переменную title т.е. Рубль или US dollar) Буду благодарен.

5. Добавляем сайт в webmaster google, webmaster yandex, webmaster bing, webmaster mail.ru.

6. Карта сайта. Можно пользоваться стандартной, если мультиязычный сайт советую «SEO Package Sitemap». Добавляем карту сайта во все поисковые системы.

7. Ищем или покупаем модуль (Яндекс.YML) для yandex маркета, добавляем сайт в Маркет, это улучшить сниппет.

8. Добавляем счетчики yandex метрики и google analitics.

9. Добавляем микроразметку сайта (https://www.google.com/webmasters/markup-helper/?hl=ru). Делаем. Проверяем в (https://developers.google.com/structured-data/testing-tool/) или (https://webmaster.yandex.ru/microtest.xml?utm_source=wm)
09.png

10. Избавляемся от внешних ссылок
Добавляем JS код
<script>
+function ($){
$(document).ready (function (){
$(‘.netsilok’).replaceWith (function (){return'<a onclick=»return !window.open (this.href)» href=»‘+$(this).data (‘link’)+'» title=»‘+$(this).text ()+'»>’+$(this).html ()+'</a>’;});
});
}(jQuery);
</script>
Теперь все внешние ссылки нужно привести к виду
<span class=»netsilok» data-link=»http://nonprice.ru/» rel=»tag»>Скидка и акции в Красноярске</span>
В итоге вместо ссылок делаем Span и добавляем class=»netsilok»

Реализовываем и радуемся. Проверить внешние ссылки можно на (http://audit.megaindex.ru или http://saitreport.ru за $)

11. Проверяем орфографию. Проверить можно на http://saitreport.ru за $

12. Скорость сайта.
12.1 Проверяем https://developers.google.com/speed/pagespeed/insights/ (устраняем, ужимаем) Проблема с кешем решается добавлением в .htaccess (если не работает решайте с Хостингом)

php_value session.cookie_domain .ВАШ-ДОМЕН.ru
php_value max_input_vars 4000
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg «access 1 year»
ExpiresByType image/jpeg «access 1 year»
ExpiresByType image/gif «access 1 year»
ExpiresByType image/png «access 1 year»
ExpiresByType text/css «access 1 month»
ExpiresByType text/html «access 1 month»
ExpiresByType application/pdf «access 1 month»
ExpiresByType text/x-javascript «access 1 month»
ExpiresByType application/x-shockwave-flash «access 1 month»
ExpiresByType image/x-icon «access 1 year»
ExpiresDefault «access 1 month»
</IfModule>
12.2 Проверяем сайт http://gtmetrix.com. Показатель сайта должен быть минимум 80. Ужимаем, можно с сайта брать готовые CSS, JS (не забывайте делать резервную копию оригинальных файлов) и картинки

2015-06-07 23-58-38 Скриншот экрана.png

12.3 Проверяем сайт http://tools.pingdom.com

13. Подаем заявки в yandex каталог, DMOZ

14. Добавляем сайт в yandex Адреса и организации(https://webmaster.yandex.ru/site/addresses.xml) и google мой бизнес.(https://www.google.com/business/). От google ждем бумажное письмо.

15. Оптимизируем страницы под запросы. http://audit.megaindex.ru/audit/relevant_page/ Пишем запрос и страницу. Оптимизируем и закупаем ссылки.

16. Ищем и устраняем ошибки верстки http://validator.w3.org

17. Хлебные крошки.
Удаляем ссылку на самого себя. для этого:
Меняем

<ul class=»breadcrumb»>
<?php foreach ($breadcrumbs as $breadcrumb) { ?>
<li><a href=»<?php echo $breadcrumb[‘href’]; ?>»><?php echo $breadcrumb[‘text’]; ?></a></li>
<?php } ?>
</ul>
на

<ul class=»breadcrumb»>
<?php
$breadcount =count($breadcrumbs)-1;
foreach ($breadcrumbs as $iterator => $breadcrumb) {
if ($iterator != $breadcount) {
echo ‘<li><a href=»‘.$breadcrumb[‘href’].'»>’.$breadcrumb[‘text’].'</a></li>’;

} else {
echo ‘<li class=»end»>’.$breadcrumb[‘text’].'</li>’;
}
} ?>
</ul>
В во всех файлах темы
catalog\view\theme\default\template
или вашей темы

18. Решение ошибки пагинации.
Как известно есть косяк в opencart, что страница http://ваш сайт.рф/category/
и http://ваш сайт.рф/category/?page=1 это одна страница.
Решение данной проблемы установка бесплатного модуля
SEO-Pagination 1.0
разработчик ceskf

У меня еще есть несколько нерешенных проблем.
1. Для страниц ?page=2 и далее есть текст и дублируется title и другие теги, пока решил тегом rel=»canonical», но хотелось иметь в title к примеру фразу «страница 2″ и текст (Описание) исчезал

Если у Вас есть, что дополнить пишите пополню список.

В среднем на проект уходит от 5-60 дней (Все зависит от кол-во материала)

Вложения:
12.png
12.png
Размер файла:50,8 КБ
Просмотров:159
Последнее редактирование: 5 авг 2015
Slait, 28 май 2015
#1
grey0207, olegianni, RoS и 4 другим нравится это.
DeCeRt
DeCeRt Новичок
Сообщения:16
Симпатии:6
Slait сказал(а): ↑
У меня еще есть несколько нерешенных проблем.
1. Для страниц ?page=2 и далее есть текст и дублируется title и другие теги, пока решил тегом rel=»canonical», но хотелось иметь в title к примеру фразу «страница 2″ и текст (Описание) исчезал
Нажмите, чтобы раскрыть…
На самом деле этот момент решается очень просто. Менять тайтл и убирать текст совсем не обязательно. Я делаю следующим образом:

а) На первой странице пагинации (по адресу корня разделе /):
<meta name=»robots» content=»index, follow»/> (страница будет полностью индексируема)
<link rel=»canonical» href=»http://адрес раздела или подраздела»/> (думаю, понятно)
<rel=»next» href=»http://страница №2″/> (указатель на то, что есть постраничка и куда идти дальше)
б) На второй странице пагинации:
<meta name=»robots» content=»noindex, follow»/> (не индексируем контент, так как текст не убран, но полностью индексируем ссылки, чтобы грамотно распределить веса страниц)
<link rel=»canonical» href=»http://адрес страницы №2″/>
<rel=»next» href=»http://страница №3″/>
<rel=»prev» href=»http://адрес корня раздела или подраздела»/>
в) На третьей и последующих страницах пагинации (N):
<meta name=»robots» content=»noindex, follow»/>
<link rel=»canonical» href=»http://адрес страницы N»/>
<rel=»next» href=»http://страница N+1″/>
<rel=»prev» href=»http://страница N-1″/>
г) Последняя страница пагинации:
<meta name=»robots» content=»noindex, follow»/>
<link rel=»canonical» href=»http://адрес последней страницы»/>
<rel=»prev» href=»http://предыдущая страница пагинации»/>

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

Варианты вызова модуля в шаблонах

По мотивам — Различные условия в шаблонах

Варианты вызова модуля в шаблонах компонента Jshop

как вызвать модуль, например, в шаблоне категории или товара, 3 способа
1. Вывод конкретного модуля, на примере модуля меток

Код
<?php echo JHTML::_('content.prepare', '{loadmodule mod_jshopping_label_products}'); ?>

2. Вывод любого (всех) модулей, опубликованных в конкретной позиции — bottom

Код
<?php echo JHTML::_('content.prepare', '{loadposition bottom}'); ?>

3. Еще вариант вызова модулей по позиции

Код
<?php  $modules = JModuleHelper::getModules('Указать позицию модулей');
if ($modules && is_array($modules)) {
	foreach ($modules as $module) {
		//заголовок 
		echo $module->title;
		//контент
		echo JModuleHelper::renderModule($module);
	};
} ?>

Различные условия в шаблоне Joomla (templates/ВАШ_Шаблон/index.php)

1. Получаем необходимые параметры

Перед составлением условий, рекомендую — отключить SEF, тогда будет видно в URL какие у вас параметры

Код
$input = JFactory::getApplication()->input;
$option = $input->getCmd('option', '');
$controller = $input->getCmd('controller', '');

$option определяет компонент, в нашем случае $option это ‘com_jshopping’
$controller работает уже внутри компонента — это может быть ‘category’, ‘product’, ‘cart’ и другое; все это можете узнать отключив SEF в настройках и посмотрев чему равен $controller (в адресной строке) на интересующих вас страницах.

Логические операторы
(для совсем новичков, чтоб вы сами могли составлять условия)

логические операторы

Примеры для шаблона Joomla (templates/ВАШ_Шаблон/index.php)

1. Компонент Jshop установлен как главный пункт меню (для красивых ссылок, допустим), но не хотим выводить его на главной

Код
<?php if (JURI::current()!= JURI::base()):?> //само условие
<jdoc:include type="component" /> //непосредственно вывод компонента
<?php endif;?>

2. Позицию модуля не показывать в корзине и при оформлении заказа

Код
<?php if ( $option == 'com_jshopping' && $controller != 'cart' && $controller != 'checkout' ) : ?>
<jdoc:include type="modules" name="left" />
<?php endif; ?>

3. Показать модуль только в категории, у которой ID=5

Код
<?php if ( $option == 'com_jshopping' && $controller == 'category' && $category_id == '5') : ?>
<jdoc:include type="modules" name="left" />
<?php endif; ?>

тут новая переменная — $category_id, поэтому в самом начале ее тоже нужно определить

Код:
$category_id = $input->getCmd('category_id', '');

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

Различные условия в шаблонах компонента Joomshopping

Первым делом переопределяем шаблоны —  всю папку /components/com_jshopping/templates/default/ копируем, переименовываем в com_jshopping и загружаем по адресу /templates/ваш_шаблон/html/*

1. Выводить описание категории только на первой странице (на второй и последующих — описания не будет)
/templates/ваш_шаблон/html/com_jshopping/category/category_default.php

Код
<?php 
        $input = JFactory::getApplication()->input;
	$start = $input->getCmd('limitstart', 0);
	$option = $input->getCmd('option', '');
	If (!$start && $option == 'com_jshopping'){ ?>
	<?php print $this->category->description?> //описание категории товаров
<?php } ?>

2. Выводить что угодно в магазине только для авторизованных пользователей

Код
<?php
$user = JFactory::getUser();
if ($user->get('guest') == '1') { } else { ?>
//тут что-то выводим (например цена для оптовиков)
<?php } ?>

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

Добавление поста череp ajax на WordPress

Добавление поста произвольного типа с фронтэнда на ajax’е в WP

ajax-spray-uniwersalny-750-mlВсем йоханга!
Сегодня будем решать не простую задачу добавления поста с лицевой части сайта на WordPress, да еще и с помощью ajax, и не просто поста, а поста произвольного типа. В одной из прошлых статей мы разобралиськак быстро создать таксономии, посты произвольного типа, запилить к ним шаблоны и форму добавления, но этот случай добавления очень простой, работает на API плагина PODS и не освещает кучу подводных камней и сейчас мы это исправим и заодно разберемся как правильно юзать аякс в WordPress.

Итак, задача:

  • Сделать возможность добавления поста произвольного типа с фронт-энда, минуя админку.
  • Все должно работать без перезагрузки страницы, т.е. на аяксе.
  • Посты, помимо стандартных полей, имеют дополнительные поля, а также поле множественной загрузки картинок.
  • При добавлении, посты должны привязываться к терминам(элементам) таксономии, тоже произвольной.
  • Использовать можно только нативные механизмы WP.

У нас есть произвольный тип постов с полями:

  • заголовок(стандартное поле — post_title),
  • текст(стандартное — post_content),
  • миниатюра(стандартное поле типа файл, потом будем получать id загруженного файла — _thumbnail_id),
  • обычная строка(произвольное поле типа строка — string_field),
  • форматированный текст(произвольное, текстарея — text_field),
  • поле множественной загрузки файлов(произвольное типа файл, дополнительные поля добавляются с помощью jQuery — multifile_field).

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

  • простая таксономия без вложенности, как тэги — custom_tax_like_tag,
  • таксономия с иерархией/вложенностью как у категорий — custom_tax_like_cat.

Причем если пост принадлежит к дочернему термину — он должен принадлежать и к родителю.
Жирным выделено название полей и слаги таксономий.

Решение: сделаем обычную форму со всеми полями, обработаем её отправку с помощью jQuery и плагинаjQuery-forms, примем полученные данные по всем правилам работы ajax в WordPress, все проверим, добавим пост с полями и медиафайлами, привяжем к таксономиям и вернем ответ.

Начнем.

0. Подготовим WP для использования аякса:
В WP существует свой механизм работы с аяксом и раз мы используем только стандартное API, то будем делать все по правилам.
Суем это в functions.php нашей темы:

add_action('wp_print_scripts','include_scripts'); // действие в котором прикрепим необходимые js скрипты и передадим данные 
function include_scripts(){
        wp_enqueue_script('jquery'); // добавим основную библиотеку jQuery
        wp_enqueue_script('jquery-form'); // добавим плагин jQuery forms, встроен в WP
        wp_enqueue_script('jquery-chained', '//www.appelsiini.net/projects/chained/jquery.chained.min.js'); // добавим плагин для связанных селект листов

        wp_localize_script( 'jquery', 'ajaxdata', // функция для передачи глобальных js переменных на страницу, первый аргумент означет перед каким скриптом вставить переменные, второй это название глобального js объекта в котором эти переменные будут храниться, последний аргумент это массив с самими переменными
			array( 
   				'url' => admin_url('admin-ajax.php'), // передадим путь до нативного обработчика аякс запросов в wp, в js можно будет обратиться к ней так: ajaxdata.url
   				'nonce' => wp_create_nonce('add_object') // передадим уникальную строку для механизма проверки аякс запроса, ajaxdata.nonce
			)
		);
}

Теперь у нас подключены нужные плагины и определены глобальные js переменные для граммотной работы с аяксом.

1. Запиливаем форму добавления:
Так как у нас есть вложенная таксономия, для удобства воспользуемся плагином jQuery chained, это для того, чтобы после выбора родительского термина, в следующий селектлист нам добавились только дочерние термины к выбранному. Еще сделаем ссылку, которая будет добавлять нам поля типа файл, для мультизагрузки картинок.
Пусть поля тайтл, постконтент и выборы терминов таксономий будут обязательны.

Ахтунг! Нельзя чтобы атрибут name у контроллов выбора терминов таксономии был таким же как слаг таксономии — вордпресс может пытаться отфильтровать контент по этой таксономии вместо того, что мы хотим.

Код формы:

<?php
// подготовим актуальные данные таксономий
$cats = get_terms('custom_tax_like_cat', 'orderby=name&hide_empty=0&parent=0'); // получим все термины(элементы) таксономии с иерархией
foreach ($cats as $cat) { // пробежим по каждому полученному термину
    $parents.="<option value='$cat->term_id' />$cat->name</option>"; // суем id и название термина в строку для вывода внутри тэга select
    $childs_array = get_terms('custom_tax_like_cat', 'orderby=name&hide_empty=0&parent='.$cat->term_id); // возьмем все дочерние термины к текущему
	foreach ($childs_array as $child){
		$childs.="<option value='$child->term_id' class='$cat->term_id' />$child->name</option>"; // делаем то же самое, класс должен быть равным id родительского термина чтобы плагин chained работал
	}
}
$tags_array = get_terms('custom_tax_like_tag', 'orderby=none&hide_empty=0&parent=0'); // получим все термины таксономии без вложенности
foreach ($tags_array as $tag) { // пробежим по каждому
  $tags .= '<label><input type="radio" name="tag" value="'.$tag->term_id.'">'.$tag->name.'</label>'; // суем все в radio баттоны
}
?>
<?php // Выводим форму ?>
<form method="post" enctype="multipart/form-data" id="add_object">
	<label>Кастом категории-родители:
		<select id="parent_cats" name="parent_cats" required>
			<option value="">Не выбрано</option>
			<?php echo $parents; // выводим все родительские термины ?>
		</select>
	</label>

	<label>Кастом категории-дети:
		<select id="child_cats" name="child_cats" required>
			<option value="">Не выбрано</option>
			<?php echo $childs; // выводим все дочерние термины, плагин chained сам покажет только нужные элементы в зависимости от выбранного родительского термина ?>
		</select>
	</label>

	Кастом тэги
  	<?php echo $tags; // выводим термины таксономии без иерархии в radio ?>

	<label>Тайтл(стандартное) <input type="text" name="post_title" required/></label>
	<label>Пост контент(стандартное) <textarea name="post_content" required/></textarea></label>
	<label>Поле типа строка(произвольное) <input type="text" name="string_field"/></label>
	<label>Пост типа текст(произвольное) <textarea name="text_field"/></textarea></label>
	<label>Миниатюра(стандартное): <input type="file" name="img"/></label>
	<label id="first_img" class='imgs'>Дополнительные фото(произвольное): <input type='file' name='imgs[]'/></label>
	<a href="#" id="add_img">Загрузить еще фото</a>
	<input type="submit" name="button" value="Отправить" id="sub"/>
	<div id="output"></div> <?php // сюда будем выводить ответ ?>

2. Перехват отправки формы и подготовка данных:
Суньте это куда удобнее: прямо на страницу или в специальный js файл для кастом скриптов =)

function ajax_go(data, jqForm, options) { //ф-я перед отправкой запроса
  	jQuery('#output').html('Отправляем...'); // в див для ответа напишем "отправляем.."
  	jQuery('#sub').attr("disabled", "disabled"); // кнопку выключим
}
function response_go(out)  { // ф-я обработки ответа от wp, в out будет элемент success(bool), который зависит от ф-и вывода которую мы использовали в обработке(wp_send_json_error() или wp_send_json_success()), и элемент data в котором будет все что мы передали аргументом к ф-и wp_send_json_success() или wp_send_json_error()
	console.log(out); // для дебага
	jQuery('#sub').prop("disabled", false); // кнопку включим
	jQuery('#output').html(out.data); // выведем результат
}
jQuery(document).ready(function(){ // после загрузки страницы
	jQuery("#child_cats").chained("#parent_cats");  // подключаем плагин для связи селект листов с терминами вложенной таксономии
  	add_form = jQuery('#add_object'); // запишем форму в переменную
  	var options = { // опции для отправки формы с помощью jquery form
  		data: { // дополнительные параметры для отправки вместе с данными формы
  			action : 'add_object_ajax', // этот параметр будет указывать wp какой экшн запустить, у нас это wp_ajax_nopriv_add_object_ajax
        	nonce: ajaxdata.nonce // строка для проверки, что форма отправлена откуда надо
    	},
      	dataType:  'json', // ответ ждем в json формате
      	beforeSubmit: ajax_go, // перед отправкой вызовем функцию ajax_go()
      	success: response_go, // после получении ответа вызовем response_go()
      	error: function(request, status, error) { // в случае ошибки
        	console.log(arguments); // напишем все в консоль
      	},
      	url: ajaxdata.url // куда слать форму, переменную с url мы определили вывели в нулевом шаге     
  }; 
  add_form.ajaxForm(options); // подрубаем плагин jquery form с опциями на нашу форму 

  jQuery('#add_img').click(function(e){ // по клику на ссылку "Добавить еще фото"
    e.preventDefault(); // выключим стандартное поведение ссылки
    jQuery(this).before("<label class='imgs'>Дополнительные фото(произвольное) <input type='file' name='imgs[]'/></label>"); // добавим перед ссылкой еще один инпут типа файл с таким же нэймом
  });  
});

3. Обработка данных и добавление поста:
Это тоже в functions.php

add_action( 'wp_ajax_nopriv_add_object_ajax', 'add_object' ); // крепим на событие wp_ajax_nopriv_add_object_ajax, где add_object_ajax это параметр action, который мы добавили в перехвате отправки формы, add_object - ф-я которую надо запустить
add_action('wp_ajax_add_object_ajax', 'add_object'); // если нужно чтобы вся бадяга работала для админов
function add_object() {
	$errors = ''; // сначала ошибок нет

	$nonce = $_POST['nonce']; // берем переданную формой строку проверки
	if (!wp_verify_nonce($nonce, 'add_object')) { // проверяем nonce код, второй параметр это аргумент из wp_create_nonce
		$errors .= 'Данные отправлены с левой страницы '; // пишим ошибку
	}

	// запишем все поля
	$parent_cat = (int)$_POST['parent_cats']; // переданный id термина таксономии с вложенностью (родитель)
	$child_cat = (int)$_POST['child_cats']; // id термина таксономии с вложенностью (его дочка)
	$tag = (int)$_POST['tag']; // id обычной таксономии
	$title = strip_tags($_POST['post_title']); // запишем название поста
	$content = wp_kses_post($_POST['post_content']); // контент
	$string_field = strip_tags($_POST['string_field']); // произвольное поле типа строка
	$text_field = wp_kses_post($_POST['text_field']); // произвольное поле типа текстарея

	// проверим заполненность, если пусто добавим в $errors строку
	if (!$parent_cat) $errors .= 'Не выбрано "Кастом категория-родитель"';
    if (!$child_cat) $errors .= 'Не выбрано "Кастом категория-ребенок xD"';				    
    if (!$tag) $errors .= 'Не выбрано "Кастом тэг"';
    if (!$title) $errors .= 'Не заполнено поле "Тайтл"';
    if (!$content) $errors .= 'Не заполнено поле "Пост контент"';

    // далее проверим все ли нормально с картинками которые нам отправили
    if ($_FILES['img']) { // если была передана миниатюра
   		if ($_FILES['img']['error']) $errors .= "Ошибка загрузки: " . $_FILES['img']['error'].". (".$_FILES['img']['name'].") "; // серверная ошибка загрузки
    	$type = $_FILES['img']['type']; 
		if (($type != "image/jpg") && ($type != "image/jpeg") && ($type != "image/png")) $errors .= "Формат файла может быть только jpg или png. (".$_FILES['img']['name'].")"; // неверный формат
	}

	if ($_FILES['imgs']) { // если были переданны дополнительные картинки, пробежимся по ним в цикле и проверим тоже самое
		foreach ($_FILES['imgs']['name'] as $key => $array) {
			if ($_FILES['imgs']['error'][$key]) $errors .= "Ошибка загрузки: " . $_FILES['imgs']['error'][$key].". (".$key.$_FILES['imgs']['name'][$key].") ";
    		$type = $_FILES['imgs']['type'][$key]; 
			if (($type != "image/jpg") && ($type != "image/jpeg") && ($type != "image/png")) $errors .= "Формат файла может быть только jpg или png. (".$_FILES['imgs']['name'][$key].")"; 
		}
	}  

	if (!$errors) { // если с полями все ок, значит можем добавлять пост
		$fields = array( // подготовим массив с полями поста, ключ это название поля, значение - его значение
			'post_type' => 'my_custom_post_type', // нужно указать какой тип постов добавляем, у нас это my_custom_post_type
	    	'post_title'   => $title, // заголовок поста
	        'post_content' => $content, // контент
	    );
	    $post_id = wp_insert_post($fields); // добавляем пост в базу и получаем его id

	    update_post_meta($post_id, 'string_field', $string_field); // заполняем произвольное поле типа строка
	    update_post_meta($post_id, 'text_field', $text_field); // заполняем произвольное поле типа текстарея

	    wp_set_object_terms($post_id, $parent_cat, 'custom_tax_like_cat', true); // привязываем к пост к таксономиям, третий параметр это слаг таксономии
	    wp_set_object_terms($post_id, $child_cat, 'custom_tax_like_cat', true);
	    wp_set_object_terms($post_id, $tag, 'custom_tax_like_tag', true);

	    if ($_FILES['img']) { // если основное фото было загружено
   			$attach_id_img = media_handle_upload( 'img', $post_id ); // добавляем картинку в медиабиблиотеку и получаем её id
   			update_post_meta($post_id,'_thumbnail_id',$attach_id_img); // привязываем миниатюру к посту
		}

		if ($_FILES['imgs']) { // если дополнительные фото были загружены
			$imgs = array(); // из-за того, что дефолтный массив с загруженными файлами в пхп выглядит не так как нужно, а именно вся инфа о файлах лежит в разных массивах но с одинаковыми ключами, нам нужно создать свой массив с блэкджеком, где у каждого файла будет свой массив со всеми данными
			foreach ($_FILES['imgs']['name'] as $key => $array) { // пробежим по массиву с именами загруженных файлов
				$file = array( // пишем новый массив
					'name' => $_FILES['imgs']['name'][$key],
					'type' => $_FILES['imgs']['type'][$key], 
					'tmp_name' => $_FILES['imgs']['tmp_name'][$key], 
					'error' => $_FILES['imgs']['error'][$key],
					'size' => $_FILES['imgs']['size'][$key]
				);
				$_FILES['imgs'.$key] = $file; // записываем новый массив с данными в глобальный массив с файлами
				$imgs[] = media_handle_upload( 'imgs'.$key, $post_id ); // добавляем текущий файл в медиабиблиотека, а id картинки суем в другой массив
			}
			update_post_meta($post_id,'multifile_field',$imgs); // привязываем все картинки к посту
		}  
	}

	if ($errors) wp_send_json_error($errors); // если были ошибки, выводим ответ в формате json с success = false и умираем
	else wp_send_json_success('Все прошло отлично! Добавлено ID:'.$post_id); // если все ок, выводим ответ в формате json с success = true и умираем
	
	die(); // умрем еще раз на всяк случ
}

После того как форму отправят, по переданному параметру action вордпресс поймет какой экшн запустить, а именно wp_ajax_add_object_ajax и выполнит нашу функцию add_object(), а дальше все просто.

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

4. Примечания:

  • Я специально усложнил все насколько смог, чтобы были примеры на все случаи жизни. Очевидно, что для добавления простого поста все проще, но по аналогии.
  • Все таксономии и произвольный тип постов были созданы с помощью плагина Pods Framework за 5 минут. Как работать с этим плагином и какие кнопки нажимать читайте здесь. Если обязательные поля нужны, то для добавления используйте api плагина pods.
  • Очень полезно будет прочитать про ajax в wordpress у Камы.

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

Шарьте статью, плюсуйте, спрашивайте, всем мир, развлекайтесь)