вторник, 16 августа 2011 г.

Drupal - Передача аргументов во view типа блок

Views не предусматривает передачу аргументов в блок. Однако, это можно обойти довольно простым способом. Для этого в настройках аргумента выбираем для Action to take if argument is not present значение Provide default argument. И в качестве Default argument type используем например такой PHP Code:

$path = $_GET['q']; // используем это если нам нужен оригинальный путь
//$path = drupal_get_path_alias($_GET['q']); // или это, если нам нужен алиас
$path = explode('/', $path); // распарсим путь
return $path[1];

Сперто отсюда

вторник, 9 августа 2011 г.

Мультисайтинг (многосайтовость) - это просто

Мультисайтинг (многосайтовость) - это просто
Изображение пользователя Макс Кириленко.


Автор: Макс Кириленко, 30.11.2006
Рубрика: Сайтостроение (Drupal, CMS, дизайн,...)


Введение

Студия Razgonka.ru специализируется на мультисайтинге.

Мультисайтинг (многосайтовость) имеет два разных значения. В этой статье я буду говорить в первую очередь об объединении посетительской базы между разными сайтами. Именно оно наиболее интересно с точки зрения наших клиентов.

Необходимость такого объединения очевидна. Любая бабушка знает, что семечками нужно торговать не на углу своего дома, а хотя бы на остановке метро. Еще лучше торговля идет на колхозном рынке. Но там бабушек не видно, другие доходы - другие продавцы.

Мультисайтинг с объединенными посетителями (они же покупатели) это аналог колхозного рынка. Если посетитель не купит у одного торговца, то неизбежно купит у другого. Так или иначе, всякий пришедший на рынок оставляет там больше денег, чем проходя мимо одиноко стоящей бабушки.

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

Мультисайтинг это способ использовать энергию посетителей (покупателей) до конца. На обычных сайтах посетители (покупатели) уходят на другие сайты Интернета. При мультисайтинге у посетителя (покупателя) есть возможность продолжить серфинг на одном из сайтов связки. Учитывая, что все сайты сделаны на одном движке и устроены примерно одинаково, посетитель (покупатель) испытывает больше комфорта при серфинге/шоппинге и ему легче сделать покупку.

Теперь о технической стороне мультисайтинга. Студия Razgonka.ru специализируется на установке сайтов на CMS Друпал, поэтому рассказывать о мультисайтинге буду на его примере.



Теория, виды мультисайтинга

Различают 2 вида мультисайтинга.

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

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

Общий движок, варианты

Если сайтов немного (2-5), то можно завести отдельную папочку, куда кидать эталонную версию версию Друпала и всех модулей.

Мультисайтинг с общим движком на бэкапелке (программа, делающая backup, резервную копию). При выходе очередной версии Друпала или модулей, переносить вручную или бэкапелкой эталонную версию по локальным папкам. Откуда они будут заливаться на сайт при очередном обновлении сайта.

Мультисайтинг с общим движком на FTP-синхронизаторе. Если мы не собираемся отлаживать локально сайты с использованием последней версии Друпала и модулей, то можно мультисайтинг с общим движком еще проще. Берется FTP-синхронизатор, позволяющий сделать профили. С его помощью заливается содержимое эталонной папки напрямую на сайты.

Мультисайтинг с общим движком средствами сервера. Если часть сайтов расположена на одном хостинге (сервере), то появляется возможность перенести папку с эталонным движком на сервер. Физически папка с Друпалом будет одна для всех сайтов. Сервер сам будет "размножать" эту папку для всех сайтов. Помимо правки настроек сервера потребуется некоторое изменение установок Друпала. Об этой технике уже много писалось на Drupal.ru. Воспользуйтесь поиском или советами Акселя на http://drupal.ru/node/763 , http://drupal.ru/node/1453

Общие таблицы, варианты

Вариант 1. Если каждый сайт хранит таблицы в своей независимой базе, то сайты полностью независимы (с точки зрения посетителей).

Комментарий. И что толку? таких независимых сайтов миллионы. Цивилизация рождалась в городах, а не в отдельных хуторах.

Вариант 2. Сайты объединяют свою базу пользователей, но сохраняют независимость в остальном. Здесь таблицы, отвечающие за пользователей, у сайтов общие, а все остальное разное.

Это самый рабочий вариант. О нем ниже будет подробнее.

Вариант 3. Сайты объединяют пользователей и часть содержимого. Например, у разных сайтов общие пользователи и общий форум. Статьи разные на каждом сайте.

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

Посетителям тоже неудобно иметь дело с частичным зеркалированием сайта. Ссылки на зеркальное содержимое показываются в его браузере еще не просмотренными. Посетитель идет по ним и у него начинается дежа вю. Когда он наконец понимает, что он это уже точно читал, у посетителя сразу падает доверие к цвету посещенных/непосещенных ссылок. И он обзывает любителя зеркалирования разными словами за свое потерянное время. Весь дальнейший просмотр сайтов из мультисайтовой связки проходит под давлением - "Читал это уже или еще не читал?".

Вариант 4. Сайты объединяются полностью. Получаются "зеркала".

Когда-то в прошлом тысячелетии зеркала были распространены как способ борьбы с плохим хостингом. Если не было видно сайта на одном месте, то посетитель мог найти его на другом. Сейчас зеркала выжили только для файловых архивов, да и то в основном на бесплатных хранилищах. В коммерческих сайтах на скачиваемый файл дается одна ссылка и это забота хозяина сайта, найти хороший хостинг и обеспечить круглосуточную доступность файлов.

Коммерческий сайт не должен зеркалироваться. Даже варианты с www и без говорят о неуважении хозяина сайта к посетителю. Поисковики могут показывать одни ссылки на такой сайт и www, а другие без. Посетитель зайдет по ссылке с www, просмотрит сайт и увидит на форуме ссылку без www . Ее дал тот, кто зашел по адресу без www. Но браузер может показать ее как еще не посещенную. И посетителю пойдет второй раз смотреть ту же самую страницу.


Идеальный вариант разделения таблиц

Итак, если проводить границу объединения таблиц, то самое оптимальное объединить зарегистрированных пользователей, но не замахиваться на объединение содержимого,т.е. вариант 2. Сайты сохраняют независимое содержимое с точки зрения поисковиков и посетителей. Но при этом посетители свободно переходят с одного сайта на другой с сохранением своего "лица" и покупательской "истории".



Техника подачи мультисайтинга на сайтах

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

Если сайты в мультисайтовой связке работают независимо, то в таком объединении нет смысла. Пользователи и не знают, что где-то в мире есть другие сайты, на которых можно воспользоваться тем же логином/паролем. Надо в блоке логина на каждом сайте из мультисайтовой связки повесить объявление: "Подходит логин/пароль с любого из следующий сайтов". И дать список сайтов из связки. При наведении мышки на ссылку всплывает надпись, чем занимается соответствующий сайт. Если посетитель уже зарегистрирован на каком-то из сайтов связки, то это побуждает его использовать имеющийся логин/пароль, чтобы обрести лицо при использовании нового сайта. Все остальные с интересом могут пройти по ссылкам, чтобы посмотреть, что там интересного есть.

Кроме объединения пользовательских логинов/паролей можно объединить между сайтами и базу покупателей. Если пользователь сделал покупку на одном из сайтов, то на другом сайте из связки он может сделать покупку в упрощенном варианте. Все его адреса и координаты подставятся из анкеты, которую он заполнял при своей первой покупке на другом сайте.

Объединение другой информации

Часто бывает и информация вне Друпаловских таблиц, которая одинакова для всех сайтов. Например, можно объединить 100-Мбайтную базу почтовых индексов, чтобы все сайты из связки могли работать с одной базой, а не держать ее копии у себя в таблице.


Техника мультисайтинга с общими таблицами

Есть два варианта.

Вариант 1. Объединение на разных префиксах. Здесь держат в одной базе несколько разных версий друпаловских таблиц для разных сайтов. Уникальные таблицы идут с префиксом сайта, общие таблицы идут вообще без префикса.

Этот вариант применим только если хостер дешевый и берет отдельную плату за каждую дополнительную базу MySQL. Если у вас в связке будет болтаться хотя бы с десяток сайтов, то таблиц в базе будет 600, многовато. Также если один из сайтов некорректно проработал с одной из таблиц, то это может подвесить работу со всей базой и вся десятка сайтов замрет.

Вариант 2. Выделение общих таблиц в отдельную базу. Уникальные таблицы каждый сайт держит в своей личной базе (без префиксов). Общие таблицы выделены в отдельную базу.

Здесь вероятность поломки базы с общими таблицами резко снижена, потому что общих таблиц всего 4-6 и они довольно компактные, без кэша, поиска и прочих объемных таблиц.. А уникальных таблиц у каждого сайта остается 50 штук, хранятся они в отдельной базе и если с ней что-то случится, то повиснет только сайт-виновник. Общую базу нужно почаще бэкапить.

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


Объединение новых и старых сайтов

Самое простое объединить несколько новых сайтов. Чуть сложнее присоединить в мультисайтинге новый сайт к старому. Присоединять старый сайт к старому можно, но сложно. Потребуется перенести в присоединяемом сайте информацию о пользователях на область свободных UserID. И корректно переименовать многие таблиц, завязанных на UserID.

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


Пусть у нас есть старый сайт site1.ru и новый сайт site2.ru. И есть 3 базы:

base: site1 здесь пока хранятся все таблицы для старого сайта
user: firstuser
password: pasfirstuser

base: site2 здесь будут хранится уникальные таблицы для нового сайта
user: firstuser
password: pasfirstuser

base: common здесь будут хранится общие таблицы для всех сайтов
user: firstuser
password: pasfirstuser


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


Разделение таблиц

Начинаем с того, что разделяем базу site1 на две части. Общие таблицы в мультисайтовой связке перенесем в базу common. А уникальные таблицы для Site1.ru оставим в родной базе site1. После чего старый сайт будет работать на двух базах.

По шагам

Шаг 1. Заходим на Site1.ru как суперюзер.

http://www.site1.ru/admin/settings

Переводим сайт в режим офф-лайн. В качестве объяснения пишем:

"Сайт Site1.ru закрыт на профилактическое обслуживание сегодня, такого-то числа, в субботу в 1:00 по Московскому времени. Через два часа, в 3:00, он откроется снова. Пожалуйста, зайдите позже. Благодарим за терпение."

Шаг 2. Делаем бэкапы базы site1.

Для бэкапа используйте Sypex Dumper Lite http://sypex.net/ . Укажите в скрипте в 38-ой строчке кодировку utf-8 :
define('CHARSET', 'utf-8'); // define('CHARSET', 'cp1251');

При бэкапе можно указать фильтр, отбрасывающий нужные и отбрасывающий ненужные таблицы


Вся база site1 разбивается на 3 части:

а) общие файлы (authmap, profile_fields, profile_values, sequences, sessions, users)

б) ненужные таблицы ^locales*, ^cache, ^search*, которые можно восстановить и без бэкапа

в) остальные таблицы, они уникальны для site1 и не используются в site2

Кладем скрипт dumper.php в директорию tmp, назначаем на нее права 777. Запускаем в браузере

http://www.site1.ru/tmp/dumper.php

Вводим логин/пароль:

user: firstuser
password: pasfirstuser

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

Делаем общий бэкап, в фильтре указываем

^locales*, ^cache, ^search*

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

Скачиваем файл с бэкапом. Смотрим, можем ли мы распаковать его и все ли нормально с кодировкой.

Если все нормально, то делаем бэкап общих таблиц, указав фильтр:

authmap, profile_fields, profile_values, sequences, sessions, users

Скачиваем файл и опять проверяем его.

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

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

Если все нормально, то продолжаем подготовку к разделению Site1.ru для работы на двух базах, общей и уникальной.

Шаг 3. Меняем в локальной версии Site1.ru файл /sites/default/settings.php :

//$db_url = 'mysql://username:password@localhost/databasename';

$db_url = 'mysql://firstuser:pasfirstuser@localhost/site1';

// $db_prefix = '';

$db_prefix = array(
"default" => "site1.", // эта строчка разная у каждого сайта в мультисайтовой связке
"users" => "common.",
"sessions" => "common.",
"authmap" => "common.",
"sequences" => "common.",
"profile_fields" => "common.",
"profile_values" => "common.",
);

Такая конструкция означает, что Друпал на Site1.ru будет брать по умолчанию таблицы из базы site1, а 6 общих таблиц - из базы common.

Точка на конце будет отделять имя базы от имени таблицы. Повторюсь, для базы site1 и common юзер и его пароль должны быть одинаковыми, иначе не будут видны те таблицы, у которых база не допускает до себя юзера firstuser с паролем pasfirstuser .



Теперь у нас все готово для того, чтобы Site1.ru заработал на двух базах.

Шаг 4. Заливаем файл /sites/default/settings.php на Site1.ru

Шаг 5. Удаляем в базе уникальных таблиц site1 ставшие ненужными общие таблицы
authmap, profile_fields, profile_values, sequences, sessions, users

Шаг 6. Ходим по Site1 как суперюзер и проверяем, все ли в порядке.

Шаг 7. Идем в таблицу sequences (счетчики)

В ней 10 записей:

files_fid
view_view_vid
access_aid
comments_cid
menu_mid
node_nid
node_revisions_vid
term_data_tid
vocabulary_vid

и

users_uid

При добавлении новых нод, меню, комментариев, файлов,... Друпал, бегающий на Site1.ru будет создавать в таблице sequences новые записи, добавляя в качестве префикса дефолтную для него базу site1:

site1.access_aid
site1.comments_cid
site1.files_fid
site1.menu_mid
site1.node_nid
site1.node_revisions_vid
site1.term_data_tid
site1.view_view_vid
site1.vocabulary_vid

И только при создании нового юзера он добавит префикс common к users_uid:

common.users_uid

Если бы Site1.ru поднимался с нуля, то в этом не было бы ничего страшного, каждый бы новый счетчик начал бы работать с 1. Но у нас Site1.ru уже имеет много мастерила и юзеров. Поэтому при попытке создания нового материала, комментария, добавления файла,... и добавления нового юзера Друпал проверит, есть ли в наличии запись с соответствующим счетчиком (site1.node_nid, site1.comments_cid,... и common.users_uid). Если такой счетчик Drupal не обнаружит, то он создаст соответствующую запись, присвоит ей значение 1 и начнет создавать материал (ноду, комментарий,... или юзера) с номером 1. Но при попытке сохранить материал или юзера под номером 1 Друпал обнаружит, что в базе уже есть материал или юзер под таким номером. И тогда он пожалуется на этот факт и откажется добавлять материал или юзера.

Нужно вручную создать в базе common записи:

site1.access_aid
site1.comments_cid
site1.files_fid
site1.menu_mid
site1.node_nid
site1.node_revisions_vid
site1.term_data_tid
site1.view_view_vid
site1.vocabulary_vid
и
common.users_uid

И перенести из них значения старых счетчиков

access_aid
comments_cid
files_fid
menu_mid
node_nid
node_revisions_vid
term_data_tid
view_view_vid
vocabulary_vid
и
users_uid

После чего записи счетчиков со старыми именами (без префиксов) можно удалить.

При определенной сноровке можно эту операцию сделать путем правки файла с бэкапом общих таблиц. Нужно в таблице sequences добавить к записи users_uid префикс к 9-ти записям префикс "common.", а к остальным 9-ти записям префикс site1. Снова сжать файл и восстановить его пустую базу common.

После такой операции станет возможным добавлять на Site1 новых юзеров и материалы (меню, комментарии,...) и они будут начинаться с правильных номеров.

Шаг 8. Заводим нового пользователя. Проверяем:

а) получилось ли завести нового пользователя
б) в базе common в таблице users должна появится новая запись
в) в таблице sequences запись common.users_uid должна увеличится на 1.

Если все в порядке, то заходите на http://www.site1.ru/admin/settings и переводите сайт в режим он-лайн.

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



Присоединение нового сайта к мультисайтовой связке

Шаг 1. Заводим базу для уникальных таблиц второго сайта

base: site2
user: firstuser
password: pasfirstuser

Шаг 2. Бэкапим базу common и site1

Шаг 3. Меняем в локальной версии Site2.ru файл /sites/default/settings.php следующим образом:

//$db_url = 'mysql://username:password@localhost/databasename';

$db_url = 'mysql://firstuser:pasfirstuser@localhost/site2';

// $db_prefix = '';

$db_prefix = array(
"default" => "site2.", // эта строчка разная у каждого сайта в мультисайтовой связке
"users" => "common.",
"sessions" => "common.",
"authmap" => "common.",
"sequences" => "common.",
"profile_fields" => "common.",
"profile_values" => "common.",
);


Шаг 3. Устанавливаем Drupal на Site2.ru как обычно. При запуске скрипта создания таблиц уникальные таблицы будут без префиксов заведены в базе site1, а общие 6 таблиц заводится в базе common не будут, потому что они уже существуют.

Править таблицу sequences нет нужды. По мере работы Site2.ru сайт будет добавлять свои собственные записи:

site2.access_aid
site2.comments_cid
site2.files_fid
site2.menu_mid
site2.node_nid
site2.node_revisions_vid
site2.term_data_tid
site2.view_view_vid
site2.vocabulary_vid

А если придется создавать на Site2.ru нового юзера, то Друпал увеличит на 1 общий счетчик юзеров common.users_uid в котором хранится общее число пользователей в Site1.ru.



Вот, собственно, и все добавление нового сайта к готовой связке.

Следующие новые сайты добавляются по такой же схеме.


Замечания

1. Раз база пользователей общая, то попытка во время установки Site2.ru добавить суперюзера окончится ничем. Если на сайте Site1.ru уже было 2000 юзеров, то будет добавлен всего-навсего юзер 2001. Когда после установки Site2.ru видите страницу с приглашением добавить юзера, не поддавайтесь на провокацию. Лучше идите в блок Логин/Пароль и вводите туда данные суперюзера №1 с Site1.ru. Если Site2.ru признал такой логин-пароль как суперюзерский, то значит мультисайтинг начал работать.

2. Если ставите на сайт Друпал, то не назначайте себя суперюзером. Рано или поздно вы уйдете с сайта, придет другой человек, который будет админить и он поменяет ваше имя как суперюзера. Следом поменяются имена у всех написанных вами статей.

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

3. Как видим, добавление нового сайта к готовой мультисайтовой связке очень простое. Нужно только поменять несколько строчек в /sites/default/settings.php. Если ставите сайт и есть планы цеплять к нему другие на мультисайтинг, то имеет смысл даже первый сайт в связке с самого начала готовить к мультисайтовой работе. Это потребует создания общей базы common и добавления нескольких строчек в /sites/default/settings.php.

4. Добавление старого сайта к старому требует много дополнительной работы. Поэтому с самого начала стройте все свои сайты как единую мультисайтовую связку. Это намного проще, чем развивать сайты порознь, а потом объединять их.



Мое мнение

Мультисайтинг на общих таблицах в отдельной базе делается на Друпале очень просто.

Первый сайт на мультисайтинг я перевел за 1,5 часа неспешного разбирания и протоколирования своих действий для статьи. Не успел даже выпить все приготовленное пиво. Улыбка У вас же это наверняка получится быстрее.

Новый сайт присоединил к связке за 10 минут.

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

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



Модули, полезные при мультисайтинге

Shared Sign-Ons. Позволяет пользователям ограничиться залогиниванием на одном лишь сайте сайте. При переходе внутри мультисайтовой связки другие сайты будут узнавать такого пользователя без дополнительной аутентификации. В марте 2007 г. у этого модуля были проблемы из-за которых он работал устойчиво только при отключенном кэширования сайта.
Fierce SSO. Альтернатива Single Sign-On. Позволяет узнавать пользователей, залогинившихся даже с сайтов не на Друпале.
Registration role. Этот модуль позволяет назначать пользователям при регистрации заранее заданные роли. Можно на каждом сайте из связки завести отдельную роль, названную по имени сайта и присваивать зарегистрировавшимся пользователям роль, названную именем сайта. Такая информация служит для разделения пользователей по месту их исходной регистрации. Эта информация может быть полезна при выплате коммиссионных за приведенных покупателей. Или когда настанет время "выделить" сайт из связки вместе с пользователями, которые зарегистрировались на этом сайте
Multisite Manager. Модуль позволяет плодить сайты на основе центрального сайта
Multiple Domains. Позовляет создавать частичные клоны основного сайта. Например, можно вынести работу E-commerce или работу с пользовательскими аккаунтами на отдельный протокол https. Требует модуль single sign-on.
Robotstxt позволяет создать отдельный robots.txt для каждого сайта в связке.

Оригинал статьи: http://www.razgonka.ru/multisiting