Установка Drupal 7.x на сервер через SSH
Способ 1
Простой и быстрый способ установки Drupal - через командную строку. Для этого необходимо выполнить следующий набор команд:
Простой и быстрый способ установки Drupal - через командную строку. Для этого необходимо выполнить следующий набор команд:
Статистика по запросам:
grep "20/Nov" /var/log/nginx/access.log | cut -d \" -f 2 | cut -d ' ' -f 2 | sort | uniq -c | sort -n | tail -n 30
Статистика по доменам:
grep "20/Nov" /var/log/nginx/access.log | cut -d ' ' -f 1 | sort | uniq -c | sort -n | tail -n 30
Количество запросов по часам:
grep "20/Nov" /var/log/nginx/access.log | cut -d [ -f 2 | cut -d ] -f 1 | cut -d : -f 1,2 | uniq -c
Часто в логах заносятся следующие PHP ошибки:
Warning: array_filter() expects parameter 1 to be array, string given в функции field_collection_item_is_empty() (строка 591 в файле /var/www/.../sites/all/modules/field_collection/field_collection.module).
Связано это с ошибкой в модуле Field Collection, которая исправляется патчем, прикрепленным к данной статье.
Это перевод оригинальной статьи «How to expose a Semantic Configuration for a Bundle» (Как влиять на семантические настройки бандла). В статье описаны способы конфигурации вашего бандла и его сервисов.
Для большего удобства, можно настроить сайт на сервере так, чтобы он автоматически обновлялся после каждого вашего пуша в основной Git репозиторий, например BitBucket. Для этого в самом репозитории настраиваем web-hook, который будет автоматически отправлять POST запрос по адресу http://site.ru/deploy.php
Содержимое файла deploy.php:
При необходимости можно добавить свои команды в массив $commands.
Имеется 3 мобильных шаблона PSD:
И 1 десктопный шаблон PSD:
Брейкпойнты для CSS:
Для изменения надписи "удалить" для кнопки удаления изображения в форме редактирования:
function hook_image_widget($vars) { $vars['element']['remove_button']['#value'] = "Удалить изображение"; return theme_image_widget($vars); }
Для изменения надписи "удалить" для элемента коллекции полей в форме редактирования:
Drupal 7 отображает в head страницы несколько мета-тегов, в том числе:
Рассмотрим, как настроить на сервере связку nginx (фронтенд) + apache (бекенд) для корректной работы Symfony 2 с её функциональностью ассетов и пр. Основная идея в том, чтобы статика отдавалась через nginx, а php код через apache. Однако если статика не находится с помощью nginx (что бывает из-за генерации Assets), в этом случае надо вместо 404 ошибки - пробовать направлять запрос в Apache.
В виртуальном хосте nginx прописываем:
server {
Существует несколько способов темизации страниц ошибок.
Самый простой способ - создать в папке /app/Resources/TwigBundle/views/Exception/ файлы с именем error404.html.twig, error403.html.twig, error.html.twig и т.п. Теперь наши шаблоны будут срабатывать при вызове в контроллере:
throw $this->createNotFoundException('Page not found');
Подробнее тут.
Сперва скачиваем библиотеку QueryPath в корневую папку сайта. Далее создаём файл parser.php и подключаем в нём ядро Друпала и библиотеку QueryPath:
CСуществует множество способов как упростить жизнь простым модераторам, работающим с сайтом на Drupal и не владеющими всеми его тонкостями. Вот несколько из них:
1) Simplify - https://www.drupal.org/project/simplify
Позволяет скрывать ненужные поля с форм добавления/редактирования материалов, таксономии и т.п.
Существует множество разных способов загрузки изображений внутрь текста с использованием визуального редактора (CkEditor и не только).
1) Самый неудобный способ - это загружать изображения на сторонний сайт хранилище-изображений и прикреплять картинку в CkEditor по ссылке.
2) Гораздо более правильный способ - это добавления поля "images" и установка модуля Insert, Который позволяет вставлять загруженные изображения в CkEditor одним нажатием, без необходимости копировать их URL.
Данная ошибка может появляться после обновления jQuery до версии 1.8.x.
Для её исправления необходимо внедрить следующий JS код:
(function($) { $.curCSS = $.css; })(jQuery);
Отбпасываем все подключения на указанных портах (FTP, SSH).
-A INPUT -p tcp -m multiport --dports 21,22 -j DROP
И выше этого правила указываем ip-адреса, которым разрешен доступ:
-A INPUT -s x.x.x.x/32 -j ACCEPT
-A INPUT -s x.x.x.x/32 -j ACCEPT
Для того,чтоб добавить новый ip-адрес в список доверенных необходимо выполнить следующую команду:
iptables -I INPUT -s ip-address -j ACCEPT
Для того, чтоб удалить необходимо выполнить:
iptables -D INPUT -s ip-address -j ACCEPT
В Twig имеется множество расширений, которые удобно использовать в шаблонах. Однако может возникнуть ситуация, когда будет необходимо написать собственное расширение. Например мы хотим отображать даты в формате: 2 дня назад, 3 месяца назад и т.п.
Пусть это расширение используется следующим образом:
{{ comment.created|created_ago }}
1. Сперва создадим файл для Twig расширения по адресу src/Acme/TestBundle/Twig/Extensions/AcmeTestExtension.php со следующим содержимым:
Для переноса контента с удаленного компьютера на локальный (или наоборот) очень помогут команды drush sql-sync и drush rsync, соответственно.
1) Устанавливаем модуль CKeditor и в пути к библиотеки указываем - //cdn.ckeditor.com/4.4.0/full-all
2) Устанавливаем модуль Syntax Highlighter и включаем его.
2) Скачиваем плагин Syntaxhighlighter Interface и копируем в папку /sites/all/modules/ckeditor/plugins/syntaxhighlight. Так, чтобы в данной директории оказался файл plugin.js.
1) Прописать локальный домен в файле hosts:
sudo nano /etc/hosts
2) Добавить конфигурацию сайта в Apache/nginx через Ajenti или вручную.
Проверить работу сайта на этом этапе.
3) Подлкючаемся по SSH к удаленному сайту:
ssh <username>@<host>
jQuery.browser = {}; (function () { jQuery.browser.msie = false; jQuery.browser.version = 0; if (navigator.userAgent.match(/MSIE ([0-9]+)\./)) { jQuery.browser.msie = true; jQuery.browser.version = RegExp.$1; } })();
Для того, чтобы тестовый домен для разработки не попал в индекс поисковых систем необходимо прописать запрет на индексацию в файле robots.txt. Однако основной домен должен остаться в индексе. Для этого создаём отдельный файл test_robots.txt для тестового домена с содержимым:
User-agent: * Disallow: /
А в файле .htaccess прописываем:
RewriteCond %{HTTP_HOST} ^test.DOMAINNAME.ru$ [NC] RewriteRule ^robots.txt$ test_robots.txt [L]
mappedBy - указывается на обратной стороне (OneToMany)
inversedBy - указывается на владеющей стороне (ManyToOne)
Часто возникает проблема, когда после сливания ветки в master, а затем выполнения push мастера в репозиторий - в удаленный репозиторий не передаётся информация о том, что было слияние веток. И в дереве изменений коммиты отображаются прямо внутри мастера. Это происходит из-за того, что Git может выполнять слияние веток двумя способами:
Для операций с изображениями потребуется пакет imagemagick. Командой данного пакета является - convert.
Изменить размер изображения:
convert -resize 1400x1400 image.jpg image.resized.jpg
Размер можно задавать следующими способами:
Консольная программа для анализа свободного места NCDU
ncdu /
Просмотр всех директорий, отсортированных по размеру:
du -mh --max-depth 1 | sort -rn
Просмотр 10 самых больших директорий:
du -mh --max-depth 1 | sort -rn | head -11
Для определения версии операционной системы семейства Linux существует несколько команд:
cat /etc/*-release
lsb_release -a
uname -a
cat /proc/version
На сервере должен быть установлен сервис memcached, а также одно из двух PHP расширений: memcache
Блок представления:
$block = module_invoke('views', 'block_view', 'catalog-block_2'); print render($block['content']);
Или так:
$block = block_load('block', 1); $arr = _block_get_renderable_array(_block_render_blocks(array($block))); $block = drupal_render($arr); print $block;
Своя функция в template.php:
1) Открываем Tools > Tasks & Context > Configure Servers
Server URL: http://youtrack.[domain-name].ru
Username: *****
Passwird: *****
Search: Assignee: me sort by: updated #Unresolved
Commit Message: Ставим галочку "Add commit message".
Функция для получения терминов таксономии в виде иерархии:
В большинстве случаев для множественного вывода материалов на сайте, построенном на Drupal, достаточно прибегнуть к услугам модуля Views. Данный модуль имеет массу возможностей и доп. модулей. Однако иногда встаёт задача нестандартного вывода нод на странице, когда "ковыряние" во Views окажется более сложным и нудным делом, нежели написание своего модуля. Рассмотрим упорядоченный вывод нод в таблице с постраничной навигацией, сортировкой по любой колонке, фильтрами и всё это через Ajax!
Drupal 7 «из коробки» поддерживает сразу несколько хранилищ, а именно: MySQL, PostgreSQL, SQLite. Это значит, что уровень абстракции существующий в API Drupal`а, гарантирует, что одни и те же модули (и сайты в целом) будут с одинаковым успехом работать на любой из этих баз данных.
Для перехода с MySQL на SQLite необходим установить модуль DBTNG Migrator. После чего надо внести изменения в файле settings.php, добавив в него базу данных SQLite под другим индексом. Например так:
Создаем директорию "/sites/all/modules/my_module". В которой добавляем 2 файла:
1) Файл с описанием модуля - my_module.info
2) Файл с самим содержимым модуля - my_module.module
Далее очищаем кеш и включаем модуль в админ панели. И переходим по адресу /custom_page
1) Установка пакетного менеджера rvm:
open vim
\curl -sSL https://get.rvm.io | bash -s stable
reopen a vim
rvm -v
2) Установка ruby:
sudo apt-get purge ruby (this will remove old ruby that is not installed by rvm)
rvm list known (this will show available ruby versions)
rvm install 2.2.0 (it's quite smart, will do a lot check, might take a while)
Для лучшей защиты сайта было бы полезным скрыть всю информацию о том, что сайт сделан на друпале. Итак, пройдёмся по пунктам:
$ tar -xvf foo.tar
$ tar -xvzf foo.tar.gz
$ tar -xvjf foo.tar.bz2
Опции | Описание |
---|---|
-x | извлечь файлы из архива |
Иногда одна единственная идея способна изменить все представление о программировании. Для меня одной из такой идей была идея сервис-контейнера. Это как золотой грааль). Вообще-то, идея не сугубо Symfony framework, это просто один из удачных паттернов проектирования приложений, часто используемый в Symfony.
RobotsTxt - модуль удобен для мультисайтинга на Drupal. Он позволяет прописывать свой robots.txt для каждого домена прямо из админ панели. Однако, у него был обнаружен баг при включенной опции производительности CMS Drupal 7 - "Сжатие кэшированных страниц" на странице /admin/config/development/performance.
При возникновении ошибок в журнале типа:
Notice: Undefined property: FieldCollectionItemEntity::$type в функции yamaps_field_formatter_view() (строка 437 в файле /var/www/nasosdon/data/www/nasosdon.ru/sites/all/modules/yamaps/inc/yamaps.formatter.inc).
Необходимо внести изменения в модуль yamaps в файле /sites/all/modules/yamaps/inc/yamaps.fromatter.inc. Перед строкой
$id = drupal_html_id(implode('-', array(
Добавить строчку:
Настроим доступ с локальном компьютера на удаленный через SSH без ввода пароля - с помощью пары ключей:
В файле /core/model/modx/modresource.class.php необходимо произвести 2 изменения:
Development:
SEO:
Ubercart Webform Checkout Pane
Для устранения ошибки Call to undefined function webform_client_form_includes()
Нужно добавить в webform.module
У Symfony framework интересная системанаследования бандлов (bundle). Интересная она тем, что действует как ООП наследование с точностью до наоборот. При наследовании бандла модификации задевают родительский.
Если у нас имеется только один материал, принадлежащий данному термину, то будет логично переходить сразу на карточку данного товара, а не на страницу термина (на которой будет всего 1 ссылка на данный товар). Если мы выводим карту сайта для людей с помощью модуля Sitemap, то необходимо в файле /sites/all/modules/site_map/site_map.module перед строкой elseif ($term->count) { вставить следующий код:
Вывод сообщений
$output->writeln('Message'); $output->writeln('<error>This error</error> ');
Ввод данных
$dialog = $this->getHelper('dialog'); $validator = function ($value) { // Проверка $value return $value; }; $ask = $dialog->askAndValidate($output, 'Enter your name: ', $validator); // Обработка ответа на вопрос $ask
:after{
content: '.';
display: block;
height: 0;
clear: both;
visibility: hidden;
}
В файле template.php необходимо прописать:
function TEMPLATENAME_html_head_alter(&$head_elements) { $remove_meta = array('canonical','shortlink','generator'); foreach ($head_elements as $key => $element) { if (isset($element['#name']) && in_array($element['#name'],$remove_meta)) { unset($head_elements[$key]); } } }
Устанавливаем и включаем модуль Taxonomy field menu
chown user:user <dir-name>
chown -R user:user <dir-name>
find <dir-name> -type d -exec chown user:user {} \;
Создаем модуль или используем готовый. В нем прописываем функцию:
<?php function MODULE_NAME_entity_info_alter(&$entity_info) { $entity_info['node']['view modes']['teaser_custom'] = array( 'label' => t('Teaser custom'), 'custom settings' => TRUE, ); }
Далее включаем модуль и переходим в "Типы материалов" -> нужный тип ноды -> "Управление отображением", включаем нужные поля.
На каждом сайте существует множество блоков (меню, погода, новости...), чтобы не использовать SonataBlockBundle, не подключать контроллеры в каждом шаблоне - создаем ядро контроллеров
Создадим бандл AcmeDemoBundle, теперь добавим ядро контроллеров (Acme/DemoBundle/Controller/CoreController.php)
stylesheets[all][] = css/style.css
scripts[] = js/script.js
regions[region] = Region
Использование параметров
Параметры задаются в отдельном файле app/config/parameters.yml (также можно и в app/config/config.yml), назначим параметр site_name:
parameters: site_name: "Название сайта"
Далее выведем его в контроллере:
echo $this->container->getParameter('site_name');
Использование конфигураций
(function ($, Drupal, window, document, undefined) { Drupal.behaviors.my_custom_behavior = { attach: function(context, settings) { // Place your code here. }}; })(jQuery, Drupal, this, this.document)
.tabledrag-processed { width:100%; } #block-admin-configure .vertical-tabs, #edit-visibility-title, #edit-regions, .tabledrag-toggle-weight-wrapper, .ckeditor_links, .filter-wrapper.form-wrapper { display:none !important; }
Если большой батон one click upload:
.cke_top .ocupload-processed{position:relative;} .cke_top .ocupload-processed object {width:20px;height:20px;margin: 0;padding: 0; position: absolute;top: 1px;left: 2px;cursor: pointer;opacity: 0;}
Как только загрузил картинку в CkEditor, при двойном клике по ней - открываются "Свойства ссылки", вместо того, чтобы открыть "Свойства изображения". После сохранения материала и его повторного редактирования - всё становится нормально и теперь при двойном клике открываются именно "Свойства изображения", а также появляется возможность изменять размер изображения. Чтобы избежать этого - необходимо в файле /sites/all/modules/ocupload/static/plugin.js после строчки:
httperf --hog --server vk.com --num-conn 100 --ra 10 --timeout 5
Пример кода JavaScript:
$('a[href*=#]').bind("click", function(e){ var anchor = $(this); $('html, body').stop().animate({ scrollTop: $(anchor.attr('href')).offset().top }, 1000); e.preventDefault(); });
При работе по системе GIT+Features возникает проблема с невозможностью создания шаблонов типа node--[nid].tpl.php, так как один и тот же материал может иметь разные nid на сервере и на локальной машине. Для решения данной проблемы применяется следующий подход.
Заменяем в файле модуля "fancybox.admin.inc" 32 строку
$settings = _fancybox_array_replace_recursive(variable_get('fancybox_settings'), _fancybox_defaults());
на
$settings = variable_get('fancybox_settings');
Вариант 1 (более короткий):
$view = views_get_view('taxonomy_term'); // get your view from database $view->set_display('page'); // set the display of your view $view->init_handlers(); // initialise the handlers $exposed_form = $view->display_handler->get_plugin('exposed_form'); print $exposed_form->render_exposed_form(true);
Вариант 2 (более подробный):
find . -printf '%C@ %p\n' | sort -n | tail -5
Для того что бы у нас правильно отображались наши события, нужно получить их с базы данных.
foreach ($result_services as $val):
$result[$key]['title'] = $val->title;
$result[$key]['publish'] = $val->field_publish_value;
$result[$key]['day'] = $val->field_day_value;
$result[$key]['day_month'] = $val->field_num_month_value;
$result[$key]['datepicker'] = $val->field_datepicker_value;
Недостаток использования визуальных редакторов - возможное различие между стилями страницы просмотра и правки материала. В результате чего результат форматирования текста в CkEditor может отличаться в связи с тем, что к тексту применяются еще стили, которые проявляются только на странице просмотра материала.
Чтобы избежать данную проблему - воспользуемся прекрасным модулем Edit.
Пошаговая инструкция по установке модуля Edit:
Часто бывает необходимо перенаправлять авторизованного посетителя сайта сразу после ввода логина и пароля, например, на главную страницу. Так как страница /user/* не содержит никакой полезной информации и только вводит в заблуждение.
Одно из решений - прописать в файле .htaccess следующее правило:
RewriteRule ^users/(\w) / [L,R=301] RewriteRule ^user/(\d+) / [L,R=301]
Для просмотра списка всех процессов, отсортированных по занимаемой оперативной памяти в МБ:
ps -eo size,pid,user,command --sort -size | awk '{ hr=$1/1024 ; printf("%13.2f Mb ",hr) } { for ( x=4 ; x<=NF ; x++ ) { printf("%s ",$x) } print "" }'
Для просмотра общей статистики по оперативной памяти:
free -h
В файле Index.html помещаем div:
<!-- header --> <div class="included" data-url="parts/header.html"></div> <!-- /header -->
В javascript прописываем подключение файлов внутрь дивов:
Создать пользователя с id = 0
INSERT INTO `users` VALUES (0, '', '', '', 0, 0, 0, '', '', 0, 0, 0, 0, NULL, '', '', '', NULL); update `users` set uid=0 where name='';