PWA is easy. Hello joomla

    We continue to study Progressive Web Applications. After the theoretical first part and a simple practical example of Hello Habr, the second part will be transferred to the PWA website on CMS Joomla.

    The type of server framework is not important. The goal of this article is to show the translation of a regular site in PWA as a concept applicable to arbitrary sites on any frameworks.



    First, download and install Joomla. When installing, we indicate that it is necessary to fill the site with demo data - select the option "Blog". We get this site here - https://tetta.nut.cc/habr/hello-joomla/original/ . Then we copy all the site files into the https://tetta.nut.cc/habr/hello-joomla/ directory - now we have two working instances of the Joomla site on one database. We will leave the first one as it is, and the second will be transferred to the PWA version.

    The source code of the sample of this article can be viewed on GitHub-e

    A little about the structure of Joomla
    В Joomla есть понятие шаблона — это набор веб ресурсов, отвечающих за презентационный уровень. Шаблоны расположены в директории /templates, наш стандартный «из коробки» называется protostar.

    В общем случае после получения браузерного запроса Joomla запускает движок, делает свои дела, а затем передает исполнение запроса в /templates/protostar/index.php, который уже генерит HTML клиенту. Данный файл представляет из себя простой PHP файл, в котором дополнительно возможно использование двух директив:

    <jdoc:includetype="component" /><jdoc:includetype="modules"name="position-id"style="..." />

    Первая вставляет вместо себя основной материал, соответствующий запрошенному URL (компонент), вторая — модули, прописанные администратором для указанной позиции. Любая страница в Joomla состоит из компонента и модулей.

    Если посмотреть на шаблон сайта, то видно блок основного материала в центральной части страницы, и модули вокруг нет. Верхнее меню — position-1, правая колонка с двумя модулями «Older Posts» и «Most Read Posts» — position-7 и так далее.

    image

    У Joomla есть особенность — если в пришедшем GET запросе есть параметр tmpl с каким-нибудь значением somePage, тo Joomla передает исполнение запроса не index.php файлу шаблона, а somePage.php, если он есть. Мы используем это ниже.


    Application shell


    Now we need to isolate from the site the app shell - the shell of the application being created. When developing a PWA site from scratch, there may be different strategies for this, but on the finished site it is convenient to use the division into its static and dynamic parts.

    Static is something that rarely changes and can be part of the app shell. For example, the top menu on our site can be considered static - it is changed only by the administrator, and he can explicitly order an app shell update on client browsers after editing it.

    At the same time, the content itself, as well as the modules in position-7 and the Breadcrumbs module in position-2, showing where the user is currently on the site, are dynamic. On the client browser they should be loaded.

    1. Changes on the server


    Replace all dynamic blocks with placeholders. In the template index.php file, we change the directives:
    <jdoc:includetype="component" />
    на
    <divid="main-content"></div><jdoc:includetype="modules"name="position-id"style="..." />
    на
    <divid="module-id"></div>

    We also include our javascript file hello-joomla.js in index.php in addition to the template scripts.

    Create a file main-content.php with the following contents:
    <jdoc:includetype="component" />

    File module-2.php:
    <jdoc:includetype="modules"name="position-2"style="none" />

    And the module-7.php file:
    <jdoc:includetype="modules"name="position-7"style="well" />


    The meaning of what is done is that when you request https://tetta.nut.cc/habr/hello-joomla/index.php/5-your-modules?tmpl=module-7, we will receive only the code of modules that are in postion- 7 The same with content.

    These are all changes in the "server" part of the site. In other frameworks, these operations (selection of the app shell) will probably be a little more complicated, but here we are lucky.

    2. Client part


    In hello-joomla.js, we need to implement dynamic loading of content and modules. In addition, you need to change the behavior of all <A> tags so that clicking on the link initiates dynamic loading of the page data. The modules of the right column will be loaded once when the site is opened in the browser, and the breadcrumbs and content - each time you click on an internal link.
    This is also easy:

    hello-joomla.js
    // Загружает содержимое url в HTML элемент elfunctionloadData(el, url){
    	url.indexOf("?") >= 0 ? url += "&" : url += "?";
    	url = url + 'mode=nocache&tmpl=' + el;
    	fetch(url)
    	.then(
    	function(response) {
    		if (response.status == 200) {
    			response.text().then(function(data) {
    				document.getElementById(el).innerHTML = data;
    			});
    		}
    	})
    	.catch();	
    	returnfalse;
    }
    // Вешает на все <a> кастомный обработчик кликовfunctionhandleLinks() {
    	var links = document.querySelectorAll('a');
    	for (var i = 0; i < links.length; ++i) {
    		links[i].removeEventListener("click", handleLink);
    		links[i].addEventListener("click", handleLink); 
    	}
    }
    // Обработчик кликовfunctionhandleLink(e) {
    	e.preventDefault();
    	loadData("main-content", this.href);
    	loadData("module-2", this.href);
    	handleLinks();
    	returnfalse;
    }
    // Первоначальная загрузка страницы в браузереfunctionDOMLoaded() {
    	loadData("main-content", location.pathname);
    	loadData("module-2", location.pathname);
    	loadData("module-7", location.pathname);
    	handleLinks();
    }
    document.addEventListener('DOMContentLoaded', DOMLoaded, true);


    At the moment we have converted our site into a full-featured SPA - single page application - application. Grinding is left - the “Back to Top” link, top menu styles, search form, animated preloader, etc.
    A copy of the site in SPA mode is available at https://tetta.nut.cc/habr/hello-joomla/spa/ .

    3. SPA -> PWA


    We connect in index.php the manifesto and sw.js from the last example . To disable the Service Worker from caching dynamic queries, add “mode = nocache” to the url in the loadData function in hello-joomla.js .

    Everything. Can be attached to the home screen.

    findings


    As you can see, in order to turn a web site into a PWA application, no frameworks or toolkits are needed. Everything is done by hand, and the code remains clean and clear.

    In the next article, in the form of useful tips, we will functionally bring the site to the level of production in production. There are standard SPA-shnye improvements - the title of the page in the browser, Google Analitics, checking that nothing has gone wrong for the search engines. Let's make a convenient Service Worker caching control for the prompt update of app shell elements. In addition, editors and commentators of the site want to be able to insert images from the Internet, including the http protocol, into the site materials.

    One of the remarkable properties of the PWA concept is that it brings back to life the MVC paradigm long lost in the numerous server and browser frameworks. “View” now lives on the client, and the browser is accessing the server for data , not for presenting it .

    And, unlike conventional SPA, PWA builds this “View” not with heavy javascript frameworks, but with the good old, fast and understandable html + css.

    Also popular now: