SlideShare a Scribd company logo
Drupal 7 и History.js
или
как AJAX-ифицировать сайт.
Малай Вадим
Drupal developer
vadim.malai@wearepropeople.com
Зачем ?
• Иметь статичную зону контента.
• Иметь возможность навигации Back
или Forward в истории browser-a
• Избежать несоответствий при
использовании родного
window.History
Составляющие
1. Ajaxify Pages
2. History.js
3. Libraries
History.js (Введение)
• Придерживается HTML5 History API
насколько это возможно;
• Кросбраузерность для всех HTML5
браузеров;
• Поддержка HTML4 браузеров;
• Адаптация link-ов в зависимости от
HTML5 или HTML4;
• Поддержка javaScript framerork-ов как
"jQuery", "MooTools", "Prototype", "Zepto".
History.js (Где это работает ?)
HTML5 Browsers
HTML4 Browsers
HTML5 Browsers
Firefox 4+ Safari 5.0+
Chrome 8+ Safari iOS 4.3+
Opera 11.5
IE 6, 7, 8, 9 Safari 4
Firefox 3 Safari iOS 4.2, 4.1,
4.0, 3.2
Opera 10, 11.0
History.js (Как это работает ?)
(function(window,undefined){
var History = window.History;
// Bind to StateChange Event
History.Adapter.bind(window,'statechange',function(){ // Note: We are using statechange instead of popstate
var State = History.getState(); // Note: We are using History.getState() instead of event.state
History.log(State.data, State.title, State.url);
});
// Change our States
History.pushState({state:1}, "State 1", "?state=1"); // logs {state:1}, "State 1", "?state=1"
History.pushState({state:2}, "State 2", "?state=2"); // logs {state:2}, "State 2", "?state=2"
History.replaceState({state:3}, "State 3", "?state=3"); // logs {state:3}, "State 3", "?state=3"
History.pushState(null, null, "?state=4"); // logs {}, '', "?state=4"
History.back(); // logs {state:3}, "State 3", "?state=3"
History.back(); // logs {state:1}, "State 1", "?state=1"
History.back(); // logs {}, "Home Page", "?"
History.go(2); // logs {state:3}, "State 3", "?state=3"
})(window);
History.js (Разбор полётов)
History.Adapter.bind(window,'statechange',function(){}); - Привязка к событию
(Срабатывает, когда состояние страницы изменилось).
History.getState() - Получает текущее состояние браузера, возвращает
объект с data, title и url.
History.pushState({state:1}, "State 1", "?state=1") - Вталкивает новое
"состояния" в браузер; data может быть нулевыми или объектом, title
может быть нулевым или строкой, URL должен быть строкой.
History.js (Разбор полётов)
History.replaceState({state:3}, "State 3", "?state=3") - Заменяет существующее
"состояние" новым; (В случае замены, будет утеряно "состояние"
предшествующее нынешнему)
History.back() - Назад в историю на 1 шаг;
History.go(2) - Вперед в историю на 2 шага;
History.log(...) - Вывод сообщения в консоли;
History.js (Что еще?)
События :
1. 'statechange' - Срабатывает, когда состояние страницы изменилось;
2. 'onanchrorchange' - Срабатывает, когда "якорь" страницы изменился;
History.replaceState(data,title,url) - Заменяет текущее состояние страницы
новым.
History.getHash() - Возвращает значение URL после # (hash); (HTML 4)
History.Adapter.trigger(element,event) - Триггер события;
History.Adapter.onDomLoad(callback) - onDomLoad связующее;
History.forward() - шаг впреред в историю браузера;
History.debug(...) - тоже что и History.log(...), но работает только если
History.debug.enable === true
History.js в Drupal-e
History.js и Drupal
(Привязка к URL)
1. Drupal.behaviors.ajaxify_pages = {};
2. Drupal.behaviors.ajaxify_pages.attach = function(context, settings) {
3. $(Drupal.settings.ajaxify_pages.links_selector, context).each(function() {
4. var to_avoid = Drupal.settings.ajaxify_pages.links_to_avoid;
5. var links = $(this).attr("href");
6. var links_obj = $(this);
7. if (typeof links !== 'undefined') {
8. $.each(to_avoid, function(index, value) {
9. if (links.indexOf(value) < 0 && links !== '/') {
10. var href = links_obj.addClass('ajaxify-pages-processed');
11. href = decodeURIComponent(href);
12. if (href.indexOf("<script>") > 0) {
13. return false;
14. }
15. if (typeof href !== 'undefined') {
16. $(this).click(function() {
17. History.pushState(null, null, href);
18. return false;
19. }); }} }); } });
History.js и Drupal
(Привязка к URL)
1. if (typeof Drupal.settings.ajaxify_pages.processed !== 'undefined') {
2. return false;
3. }
4. Drupal.settings.ajaxify_pages.processed = 'processed';
5. Drupal.ajaxify_pages = {cache: {}};
6. History.Adapter.bind(window, 'statechange', function() {
7. loadPage(History.getState().url);
8. });
9. Drupal.ajaxify_pages.cache[History.getState().url] = {
10. title: $('title').html(),
11. content: $(Drupal.settings.ajaxify_pages.content_selector)
12. };
13. };
History.js и Drupal
(Привязка к URL) Разбор полётов
Что, и зачем мы сделали ?
1. Указываем в админке части URL, при нахождении которых, мы
игнорируем URL. (Избегаем внешних ссылок, картинок и т.д);
2. Заменяем каждую escape-последовательность в закодированном URI
символом, который она представляет;
3. Вталкивает новое "состояния" в браузер;
4. Привязываемся к событию смены состояния страницы, и вызываемся
функцию, которая будет получать новый контент;
5. Сохраняем новые значения; (При возврате на URI, на котором мы уже
были, можно вытащить уже сохранённые значения, что бы не делать
лишний AJAX запрос)
History.js и Drupal
Получаем новый контент
Для получения контента, делаем обычный AJAX запрос, НО ! :
1. Drupal, генерирует BODY классы в зависимости от страницы, так что не
забываем их заменять на "новой" странице;
2. Разные страницы могут иметь разные CSS файлы, их тоже нужно
добавить;
3. Разные страницы могут иметь разные JS файлы, и их :) ;
4. Меняем title страницы;
5. Не забываем про Trobber, потому как AJAX запрос может быть разной
продолжительности;
History.js и Drupal
Получаем новый контент (немного кода)
1. Drupal.ajaxify_pages.cache[url] = {
2. title: new_page.title,
3. content: new_page.content,
4. scripts: new_page.new_script,
5. css: new_page.new_css,
6. body_class: new_page.body_class,
7. admin_menu: new_page.admin_menu
8. };
9. processPage(Drupal.ajaxify_pages.cache[url], url);
Не забываем сохранить страницу в "кэш", что бы мы в следующий раз,
при возвращении Back в браузере, ну или новым кликом на ссылку
этой страницы, не делали новый AJAX запрос, а использовали
существующие данные.
History.js и Drupal
Заменяем контент
1. $('head script').each(function() {
2. if ($(this)[0].src.length > 0) {
3. to_replace.page_script.push($(this)[0].src.match(/([^<]+)(.js)/)[0]);
4. }
5. if ($(this).text().length > 0) {
6. $(this).remove();
7. }
8. });
9.
10. if (typeof to_replace.new_script !== 'undefined') {
11. $.grep(to_replace.new_script, function(el) {
12. if ($.inArray(el, to_replace.page_script) === -1)
13. to_replace.diff_script.push(el);
14. i++;
15. });
16. }
History.js и Drupal
Заменяем контент
•Нет нужды заменять все JS файлы, потому что при этом, будут
перезапущены все скрипты.
•Не стоит пугаться что JS или CSS файл не появился в вашем DOM-e.
•Мы только добавляем новые файлы.
•В определённый момент, у нас соберутся в кучу все JS и CSS файлы
сайты, но на мой взгляд, это не смертельно.
•Так же, не стоит забывать, что Drupal делает агрегацию файлов, то есть
добавляет символы в конец имени файла. Это надо учесть при получении
и сравнении новых файлов.
History.js и Drupal
Views, как быть ?
1. Drupal.settings.views = {
2. ajaxViews: {},
3. ajax_path: "/views/ajax"
4. };
5. $("[class^=view]").ready(function() {
6. $(".view").each(function() {
7. if ($("[class*=view-]").length > 0 && $("[class*=view-dom-id]").length
> 0 && $("[class*=view-display-id]").length > 0) {
8. var view_classes_array = $("[class*=view-]").attr('class').split(' '),
9. view_name = view_classes_array[1].replace(/view-/g, ""),
10. view_display_id = view_classes_array[3].replace(/view-display-
id-/g, ""),
11. view_dom_id = view_classes_array[4].replace(/view-dom-id-/g,
""),
12. view_path = '';
13. view_path = location.pathname.substring(1,
location.pathname.length);
14. view_name = view_name.replace("-", "_");
History.js и Drupal
Views, как быть ?
1. Drupal.settings.views.ajaxViews['views_dom_id:'+view_display_id] = {
2. pager_element: "0",
3. view_args: "",
4. view_base_path: null,
5. view_display_id: view_display_id,
6. view_dom_id: view_dom_id,
7. view_name: view_name,
8. view_path: view_path
9. };
10. }
11. });
12. });
History.js и Drupal
Views, как быть? (Разбор полётов)
Так как мы получаем контент по AJAX, все JS обьекты, мы строим рукчами :(
pager_element - Элемент страничной навигации;
view_args - Аргумент передаваеммый во Views;
view_base_path - Родной адресс Views;
view_display_id - ID "отображения" Views;
view_dom_id - Рандомный хэш, который присваивается как класс контейнеру
Views;
view_name - Машинное имя Views;
view_path - URL на котором вызывается Views. При совпадении с
view_base_path, можно указывать только view_path, а view_base_path оставить
как NULL.
• Drupal.settings.views = {
• ajaxViews: {},
• ajax_path: "/views/ajax"
• };
Views обьект в которов будет список
всех Views на странице.
Каждая Views идентифицируется с
помощью ключа
"'views_dom_id:'+view_display_id"
History.js и Drupal
Views, как быть? (Разбор полётов)
Приведенный пример, должен использоваться не только по отношению ко
Views, но также и в случае AJAX форм, Ctools modals, Omega layouts ... в
общем ко всему что могло бы быть динамично добавлено при генерации
страницы.
Спасибо за Внимание !
Drupal 7 and History.js

More Related Content

What's hot

XML Native Database на примере SednaXML
XML Native Database на примере SednaXMLXML Native Database на примере SednaXML
XML Native Database на примере SednaXML
Slach
 
Web осень 2013 лекция 3
Web осень 2013 лекция 3Web осень 2013 лекция 3
Web осень 2013 лекция 3
Technopark
 
Школа-студия разработки для iOS. Лекция 4. Работа с данными
Школа-студия разработки для iOS. Лекция 4. Работа с даннымиШкола-студия разработки для iOS. Лекция 4. Работа с данными
Школа-студия разработки для iOS. Лекция 4. Работа с данными
Глеб Тарасов
 
basis.js - почему я не бросил разрабатывать свой фреймворк
basis.js - почему я не бросил разрабатывать свой фреймворкbasis.js - почему я не бросил разрабатывать свой фреймворк
basis.js - почему я не бросил разрабатывать свой фреймворк
Roman Dvornov
 
2013 09 19 кеширование на клиенте и сервере
2013 09 19 кеширование на клиенте и сервере2013 09 19 кеширование на клиенте и сервере
2013 09 19 кеширование на клиенте и сервере
Yandex
 
Web осень 2013 лекция 1
Web осень 2013 лекция 1Web осень 2013 лекция 1
Web осень 2013 лекция 1
Technopark
 
Александр Шуменко - Varnish for authenticated users
Александр Шуменко - Varnish for authenticated usersАлександр Шуменко - Varnish for authenticated users
Александр Шуменко - Varnish for authenticated users
LEDC 2016
 

What's hot (20)

XML Native Database на примере SednaXML
XML Native Database на примере SednaXMLXML Native Database на примере SednaXML
XML Native Database на примере SednaXML
 
Web осень 2013 лекция 3
Web осень 2013 лекция 3Web осень 2013 лекция 3
Web осень 2013 лекция 3
 
Школа-студия разработки для iOS. Лекция 4. Работа с данными
Школа-студия разработки для iOS. Лекция 4. Работа с даннымиШкола-студия разработки для iOS. Лекция 4. Работа с данными
Школа-студия разработки для iOS. Лекция 4. Работа с данными
 
basis.js - почему я не бросил разрабатывать свой фреймворк
basis.js - почему я не бросил разрабатывать свой фреймворкbasis.js - почему я не бросил разрабатывать свой фреймворк
basis.js - почему я не бросил разрабатывать свой фреймворк
 
Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)
Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)
Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)
 
JDBC
JDBCJDBC
JDBC
 
2013 09 19 кеширование на клиенте и сервере
2013 09 19 кеширование на клиенте и сервере2013 09 19 кеширование на клиенте и сервере
2013 09 19 кеширование на клиенте и сервере
 
JavaScript-библиотека
JavaScript-библиотекаJavaScript-библиотека
JavaScript-библиотека
 
YiiConf: Миграции и инсталляции
YiiConf: Миграции и инсталляцииYiiConf: Миграции и инсталляции
YiiConf: Миграции и инсталляции
 
Web осень 2013 лекция 1
Web осень 2013 лекция 1Web осень 2013 лекция 1
Web осень 2013 лекция 1
 
Страх и ненависть в Event Bus
Страх и ненависть в Event BusСтрах и ненависть в Event Bus
Страх и ненависть в Event Bus
 
Олег Годовых «Страх и ненависть в Event Bus»
Олег Годовых «Страх и ненависть в Event Bus»Олег Годовых «Страх и ненависть в Event Bus»
Олег Годовых «Страх и ненависть в Event Bus»
 
хранение данных
хранение данныххранение данных
хранение данных
 
Cookies, session и другое в JSP
Cookies, session и другое в JSPCookies, session и другое в JSP
Cookies, session и другое в JSP
 
Александр Шуменко - Varnish for authenticated users
Александр Шуменко - Varnish for authenticated usersАлександр Шуменко - Varnish for authenticated users
Александр Шуменко - Varnish for authenticated users
 
C# Web. Занятие 12.
C# Web. Занятие 12.C# Web. Занятие 12.
C# Web. Занятие 12.
 
Database (Lecture 14 – database)
Database (Lecture 14 – database)Database (Lecture 14 – database)
Database (Lecture 14 – database)
 
Примеры быстрой разработки API на масштабируемом сервере приложений Impress д...
Примеры быстрой разработки API на масштабируемом сервере приложений Impress д...Примеры быстрой разработки API на масштабируемом сервере приложений Impress д...
Примеры быстрой разработки API на масштабируемом сервере приложений Impress д...
 
JSP
JSPJSP
JSP
 
Кратко о MongoDB
Кратко о MongoDBКратко о MongoDB
Кратко о MongoDB
 

Similar to Drupal 7 and History.js

Web весна 2012 лекция 9
Web весна 2012 лекция 9Web весна 2012 лекция 9
Web весна 2012 лекция 9
Technopark
 
Практическое применение HTML5 в Я.Почте
Практическое применение HTML5 в Я.ПочтеПрактическое применение HTML5 в Я.Почте
Практическое применение HTML5 в Я.Почте
Alexey Androsov
 
Web весна 2013 лекция 3
Web весна 2013 лекция 3Web весна 2013 лекция 3
Web весна 2013 лекция 3
Technopark
 
библиотека Google closure java script
библиотека Google closure java scriptбиблиотека Google closure java script
библиотека Google closure java script
Yova Stoika
 

Similar to Drupal 7 and History.js (20)

Web весна 2012 лекция 9
Web весна 2012 лекция 9Web весна 2012 лекция 9
Web весна 2012 лекция 9
 
Webuibasics - Lesson 3 - Nginx, SSI (in russian)
Webuibasics - Lesson 3 - Nginx, SSI (in russian)Webuibasics - Lesson 3 - Nginx, SSI (in russian)
Webuibasics - Lesson 3 - Nginx, SSI (in russian)
 
FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиен...
FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиен...FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиен...
FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиен...
 
Документирование исходных текстов (javadoc)
Документирование исходных текстов (javadoc)Документирование исходных текстов (javadoc)
Документирование исходных текстов (javadoc)
 
JavaScript Базовый. Занятие 08.
JavaScript Базовый. Занятие 08.JavaScript Базовый. Занятие 08.
JavaScript Базовый. Занятие 08.
 
Кеширование. Api. http 1.1 (rfc 2616)
Кеширование. Api. http 1.1 (rfc 2616)Кеширование. Api. http 1.1 (rfc 2616)
Кеширование. Api. http 1.1 (rfc 2616)
 
Практическое применение HTML5 в Я.Почте
Практическое применение HTML5 в Я.ПочтеПрактическое применение HTML5 в Я.Почте
Практическое применение HTML5 в Я.Почте
 
Module 4
Module 4Module 4
Module 4
 
Web весна 2013 лекция 3
Web весна 2013 лекция 3Web весна 2013 лекция 3
Web весна 2013 лекция 3
 
Node.js введение в технологию, КПИ #ITmeetingKPI
Node.js введение в технологию, КПИ  #ITmeetingKPINode.js введение в технологию, КПИ  #ITmeetingKPI
Node.js введение в технологию, КПИ #ITmeetingKPI
 
Библиотеки для передачи данных (Lecture 13 – multithreading, network (libs))
Библиотеки для передачи данных (Lecture 13 – multithreading, network (libs))Библиотеки для передачи данных (Lecture 13 – multithreading, network (libs))
Библиотеки для передачи данных (Lecture 13 – multithreading, network (libs))
 
#6 "Изоморфный фреймворк Catberry.js" Денис Речкунов
#6 "Изоморфный фреймворк Catberry.js" Денис Речкунов#6 "Изоморфный фреймворк Catberry.js" Денис Речкунов
#6 "Изоморфный фреймворк Catberry.js" Денис Речкунов
 
Jsfwdays 2013-2
Jsfwdays 2013-2Jsfwdays 2013-2
Jsfwdays 2013-2
 
Backbone js
Backbone jsBackbone js
Backbone js
 
JSSDK: Начало
JSSDK: НачалоJSSDK: Начало
JSSDK: Начало
 
The Old New ASP.NET
The Old New ASP.NETThe Old New ASP.NET
The Old New ASP.NET
 
C# Web. Занятие 16.
C# Web. Занятие 16.C# Web. Занятие 16.
C# Web. Занятие 16.
 
библиотека Google closure java script
библиотека Google closure java scriptбиблиотека Google closure java script
библиотека Google closure java script
 
03 templates kachalova
03 templates kachalova03 templates kachalova
03 templates kachalova
 
Алексей Андросов "HTML5 в Я.Почте"
Алексей Андросов "HTML5 в Я.Почте"Алексей Андросов "HTML5 в Я.Почте"
Алексей Андросов "HTML5 в Я.Почте"
 

Drupal 7 and History.js

  • 1. Drupal 7 и History.js или как AJAX-ифицировать сайт. Малай Вадим Drupal developer vadim.malai@wearepropeople.com
  • 2. Зачем ? • Иметь статичную зону контента. • Иметь возможность навигации Back или Forward в истории browser-a • Избежать несоответствий при использовании родного window.History
  • 4. History.js (Введение) • Придерживается HTML5 History API насколько это возможно; • Кросбраузерность для всех HTML5 браузеров; • Поддержка HTML4 браузеров; • Адаптация link-ов в зависимости от HTML5 или HTML4; • Поддержка javaScript framerork-ов как "jQuery", "MooTools", "Prototype", "Zepto".
  • 5. History.js (Где это работает ?) HTML5 Browsers HTML4 Browsers HTML5 Browsers Firefox 4+ Safari 5.0+ Chrome 8+ Safari iOS 4.3+ Opera 11.5 IE 6, 7, 8, 9 Safari 4 Firefox 3 Safari iOS 4.2, 4.1, 4.0, 3.2 Opera 10, 11.0
  • 6.
  • 7. History.js (Как это работает ?) (function(window,undefined){ var History = window.History; // Bind to StateChange Event History.Adapter.bind(window,'statechange',function(){ // Note: We are using statechange instead of popstate var State = History.getState(); // Note: We are using History.getState() instead of event.state History.log(State.data, State.title, State.url); }); // Change our States History.pushState({state:1}, "State 1", "?state=1"); // logs {state:1}, "State 1", "?state=1" History.pushState({state:2}, "State 2", "?state=2"); // logs {state:2}, "State 2", "?state=2" History.replaceState({state:3}, "State 3", "?state=3"); // logs {state:3}, "State 3", "?state=3" History.pushState(null, null, "?state=4"); // logs {}, '', "?state=4" History.back(); // logs {state:3}, "State 3", "?state=3" History.back(); // logs {state:1}, "State 1", "?state=1" History.back(); // logs {}, "Home Page", "?" History.go(2); // logs {state:3}, "State 3", "?state=3" })(window);
  • 8.
  • 9. History.js (Разбор полётов) History.Adapter.bind(window,'statechange',function(){}); - Привязка к событию (Срабатывает, когда состояние страницы изменилось). History.getState() - Получает текущее состояние браузера, возвращает объект с data, title и url. History.pushState({state:1}, "State 1", "?state=1") - Вталкивает новое "состояния" в браузер; data может быть нулевыми или объектом, title может быть нулевым или строкой, URL должен быть строкой.
  • 10. History.js (Разбор полётов) History.replaceState({state:3}, "State 3", "?state=3") - Заменяет существующее "состояние" новым; (В случае замены, будет утеряно "состояние" предшествующее нынешнему) History.back() - Назад в историю на 1 шаг; History.go(2) - Вперед в историю на 2 шага; History.log(...) - Вывод сообщения в консоли;
  • 11. History.js (Что еще?) События : 1. 'statechange' - Срабатывает, когда состояние страницы изменилось; 2. 'onanchrorchange' - Срабатывает, когда "якорь" страницы изменился; History.replaceState(data,title,url) - Заменяет текущее состояние страницы новым. History.getHash() - Возвращает значение URL после # (hash); (HTML 4) History.Adapter.trigger(element,event) - Триггер события; History.Adapter.onDomLoad(callback) - onDomLoad связующее; History.forward() - шаг впреред в историю браузера; History.debug(...) - тоже что и History.log(...), но работает только если History.debug.enable === true
  • 13. History.js и Drupal (Привязка к URL) 1. Drupal.behaviors.ajaxify_pages = {}; 2. Drupal.behaviors.ajaxify_pages.attach = function(context, settings) { 3. $(Drupal.settings.ajaxify_pages.links_selector, context).each(function() { 4. var to_avoid = Drupal.settings.ajaxify_pages.links_to_avoid; 5. var links = $(this).attr("href"); 6. var links_obj = $(this); 7. if (typeof links !== 'undefined') { 8. $.each(to_avoid, function(index, value) { 9. if (links.indexOf(value) < 0 && links !== '/') { 10. var href = links_obj.addClass('ajaxify-pages-processed'); 11. href = decodeURIComponent(href); 12. if (href.indexOf("<script>") > 0) { 13. return false; 14. } 15. if (typeof href !== 'undefined') { 16. $(this).click(function() { 17. History.pushState(null, null, href); 18. return false; 19. }); }} }); } });
  • 14. History.js и Drupal (Привязка к URL) 1. if (typeof Drupal.settings.ajaxify_pages.processed !== 'undefined') { 2. return false; 3. } 4. Drupal.settings.ajaxify_pages.processed = 'processed'; 5. Drupal.ajaxify_pages = {cache: {}}; 6. History.Adapter.bind(window, 'statechange', function() { 7. loadPage(History.getState().url); 8. }); 9. Drupal.ajaxify_pages.cache[History.getState().url] = { 10. title: $('title').html(), 11. content: $(Drupal.settings.ajaxify_pages.content_selector) 12. }; 13. };
  • 15.
  • 16. History.js и Drupal (Привязка к URL) Разбор полётов Что, и зачем мы сделали ? 1. Указываем в админке части URL, при нахождении которых, мы игнорируем URL. (Избегаем внешних ссылок, картинок и т.д); 2. Заменяем каждую escape-последовательность в закодированном URI символом, который она представляет; 3. Вталкивает новое "состояния" в браузер; 4. Привязываемся к событию смены состояния страницы, и вызываемся функцию, которая будет получать новый контент; 5. Сохраняем новые значения; (При возврате на URI, на котором мы уже были, можно вытащить уже сохранённые значения, что бы не делать лишний AJAX запрос)
  • 17. History.js и Drupal Получаем новый контент Для получения контента, делаем обычный AJAX запрос, НО ! : 1. Drupal, генерирует BODY классы в зависимости от страницы, так что не забываем их заменять на "новой" странице; 2. Разные страницы могут иметь разные CSS файлы, их тоже нужно добавить; 3. Разные страницы могут иметь разные JS файлы, и их :) ; 4. Меняем title страницы; 5. Не забываем про Trobber, потому как AJAX запрос может быть разной продолжительности;
  • 18. History.js и Drupal Получаем новый контент (немного кода) 1. Drupal.ajaxify_pages.cache[url] = { 2. title: new_page.title, 3. content: new_page.content, 4. scripts: new_page.new_script, 5. css: new_page.new_css, 6. body_class: new_page.body_class, 7. admin_menu: new_page.admin_menu 8. }; 9. processPage(Drupal.ajaxify_pages.cache[url], url); Не забываем сохранить страницу в "кэш", что бы мы в следующий раз, при возвращении Back в браузере, ну или новым кликом на ссылку этой страницы, не делали новый AJAX запрос, а использовали существующие данные.
  • 19. History.js и Drupal Заменяем контент 1. $('head script').each(function() { 2. if ($(this)[0].src.length > 0) { 3. to_replace.page_script.push($(this)[0].src.match(/([^<]+)(.js)/)[0]); 4. } 5. if ($(this).text().length > 0) { 6. $(this).remove(); 7. } 8. }); 9. 10. if (typeof to_replace.new_script !== 'undefined') { 11. $.grep(to_replace.new_script, function(el) { 12. if ($.inArray(el, to_replace.page_script) === -1) 13. to_replace.diff_script.push(el); 14. i++; 15. }); 16. }
  • 20. History.js и Drupal Заменяем контент •Нет нужды заменять все JS файлы, потому что при этом, будут перезапущены все скрипты. •Не стоит пугаться что JS или CSS файл не появился в вашем DOM-e. •Мы только добавляем новые файлы. •В определённый момент, у нас соберутся в кучу все JS и CSS файлы сайты, но на мой взгляд, это не смертельно. •Так же, не стоит забывать, что Drupal делает агрегацию файлов, то есть добавляет символы в конец имени файла. Это надо учесть при получении и сравнении новых файлов.
  • 21. History.js и Drupal Views, как быть ? 1. Drupal.settings.views = { 2. ajaxViews: {}, 3. ajax_path: "/views/ajax" 4. }; 5. $("[class^=view]").ready(function() { 6. $(".view").each(function() { 7. if ($("[class*=view-]").length > 0 && $("[class*=view-dom-id]").length > 0 && $("[class*=view-display-id]").length > 0) { 8. var view_classes_array = $("[class*=view-]").attr('class').split(' '), 9. view_name = view_classes_array[1].replace(/view-/g, ""), 10. view_display_id = view_classes_array[3].replace(/view-display- id-/g, ""), 11. view_dom_id = view_classes_array[4].replace(/view-dom-id-/g, ""), 12. view_path = ''; 13. view_path = location.pathname.substring(1, location.pathname.length); 14. view_name = view_name.replace("-", "_");
  • 22. History.js и Drupal Views, как быть ? 1. Drupal.settings.views.ajaxViews['views_dom_id:'+view_display_id] = { 2. pager_element: "0", 3. view_args: "", 4. view_base_path: null, 5. view_display_id: view_display_id, 6. view_dom_id: view_dom_id, 7. view_name: view_name, 8. view_path: view_path 9. }; 10. } 11. }); 12. });
  • 23. History.js и Drupal Views, как быть? (Разбор полётов) Так как мы получаем контент по AJAX, все JS обьекты, мы строим рукчами :( pager_element - Элемент страничной навигации; view_args - Аргумент передаваеммый во Views; view_base_path - Родной адресс Views; view_display_id - ID "отображения" Views; view_dom_id - Рандомный хэш, который присваивается как класс контейнеру Views; view_name - Машинное имя Views; view_path - URL на котором вызывается Views. При совпадении с view_base_path, можно указывать только view_path, а view_base_path оставить как NULL. • Drupal.settings.views = { • ajaxViews: {}, • ajax_path: "/views/ajax" • }; Views обьект в которов будет список всех Views на странице. Каждая Views идентифицируется с помощью ключа "'views_dom_id:'+view_display_id"
  • 24. History.js и Drupal Views, как быть? (Разбор полётов) Приведенный пример, должен использоваться не только по отношению ко Views, но также и в случае AJAX форм, Ctools modals, Omega layouts ... в общем ко всему что могло бы быть динамично добавлено при генерации страницы.