PlaceboCMS — идея, рассуждение на тему того, как можно было бы создать CMS без БД, без PHP, но с поддержкой динамики и разделения контента и оформления.

Этап 0. Создание структуры папок и файлов. Ибо я отказался от PHP, MySQL, и вообще веб-сервера как такового, нужно продумать, как хорошо организовать систему хранения данных. Я сделал вот так:
    public_html — основная папка (ну или www, кому как удобнее)
|> pages = хранит html файлы страниц
|> style = тут стилевое оформление
      |> style.css = основной css файл
      |> img = картинки для CSS
      |> templ = два файла html расширения
            |> web.html — шаблон для WEB (расположение эл-тов)
            |> pda.html — шаблон для мобильных устройств
|> java — хранилище js функций (захотелось назвать java)
      |> my.js — функции JS
|> images — Тут будут картинки какие-нибудь


Этап 1. Создание шаблона.
За основу был взят простой HTML5 шаблон статической страницы. т.к. дизайн я делаю адаптивный (для всех экранов), то надо сделать обработку на JS, поэтому первоначально пишу функциональную примочку для работы с размером экрана. Скажу сразу — IE я не учитываю, как браузер, вообще, так как все мои проекты ориентированы на Linux, где его и в помине нет.
Задал я объект device, параметром width который отдает размер экрана. Тут появилась проблема, в мобильных браузерах есть возможность принудительного масштабирования, что означает, что использовать clientWidth для определения ширины становится бессмысленным. НО! Если человек с компа, то screen.width будет явно шире, чем окно самого браузера, последнее вообще можно растягивать как душе угодно. Пошел на компромис и взял наименьшее из двух. И это помогло! Потому что в мобилках при масштабировании clientWidth возвращается больше, чем screen.width, вот такой вот парадокс Нужно мне это для того, чтобы js выводил нужный шаблон в зависимости от ширины, доступной для размещения контента.

Этап 2. Создание шаблона второго уровня.
Сейчас поясню. Есть шаблон первого уровня — это шаблон определяющий поведение всего сайта в целом, определяет, поддерживает ли браузер AJAX, и обрабатывает ли он js в реальном времени. Пример: Opera Mini обрабатывает js на своем сервере и отдает пользователю отрендеренную страничку, в которой js как такового и нет вовсе. В новых версиях примерно так же. Именно для этого наш js должен уметь работать и с таким браузером тоже. В нашем случае — шаблон второго уровня задает поведение самих страничек (их загрузки в AJAX либо же их открытия посредством обычных URL).

Этап 3. Создание шаблона одной страницы.
Тут не то, чтобы сложно, скорее надо хорошо продумать то, как будет страница выглядеть в браузере и в каком виде ее лучше хранить на сервере. Для начала я взял простой блок текста на HTML и сохранил его как 'index.html'. В этом случае адрес сайта имеет вид: skanersoft.ru/index.html
JS парсит адрес сайта и видит, что грузить надо index.html, что и делает. При этом если браузер не поддерживает динамическую обработку JS или в нем нет AJAX то ссылки имеют обычный вид: <a href=имя_сайта.ру/index.html?page_name>Имя ссылки</a> , если все работает, то ссылке добавляется: onclick = loadPage('page_name');
В самом шаблоне страницы ссылки имеют обычный вид.

Это были этапы планирования. Теперь переходим к реализации.

Этап 1. Рвём на части HTML шаблон!
Создавать с нуля шаблон (оформление) мне не очень улыбается… посему я решил воспользоваться готовым решением. Скачал в интернетах несложный шаблон. Мне сейчас оттуда нужны CSS стили, картинки, чтобы с нуля не рисовать, и каркас. Нашел очень хороший шаблон, вот такой:
image
Сойдет! Идем дальше. Этот шаблон я буду использовать как WEB тему для сайта, значит его нужно запихать в файл style/templ/web.html и убрать из него все лишнее.
Я убрал из шаблона все лишнее, оставив только то, что было между ..., Но потерялись стили CSS! Решение пришло простое: динамически подгружать стили, когда потребуется. Придем к этому потом. Теперь нужно отделить меню от контента. Я подумал, что лучше хранить меню в js файле в виде строки, хотя был вариант использовать AJAX для загрузки, а CSS для позиционирования, либо же iframe, но решил оставить в js.
В итоге от шаблона осталось только следующее:
<div class="content"> 
  <div id="header"> 
    <div class="title"> 
      <h1 id="mySite">Заголовок</h1> 
      <h2 id="mySlogan">Слоган</h2> 
    </div> 
  </div> 
  
  <div id="main"> 
    <div class="right_side" id="myData"> 
     Текст страницы 
    </div> 
    <div class="left_side"> 
      <div class="nav"> 
        <ul id="myMenu"> 
          
        </ul> 
      </div> 
      <br /> 
    </div> 
  </div> 
  <div id="footer"> 
    <div class="padding"> 
     (C) 2015 - SkanerSoft 
    </div> 
  </div> 
</div>



Это и есть весь шаблон WEB версии сайта.
Так же подправил CSS стили, убрав оттуда все лишние элементы оставив только самые нужные.
Теперь немного о структуре (не HTML) шаблона. Все данные я буду присваивать посредством изменения innerHTML объекта, отсюда я присвоил следующие id:
mySite — заголовк сайта
mySlogan — слоган сайта
myData — основной текст страницы, в который будет грузиться шаблон.
Пока всё. Остальное решу потом.

Этап 2. Создаем основной шаблон.
Так как я не использую PHP, то тут надо хорошо подумать над тем, как удет выглядеть сайт извне. Я не ориентировался на поисковики, проект внутренний, поэтому сделаю простейший шаблон html:
<!DOCTYPE html> 
<html> 
 <head> 
  <meta http-equiv="Cache-Control" content="no-cache"> 
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
  <link id="myCss" type="text/css" rel="stylesheet" href=""> 
  <script id="myScript" type="text/javascript" src="java/my.js"></script> 
  <title id="myTitle"></title> 
 </head> 
 <body id="myBody" onload="placebo_start();"></body> 
</html>



И опять же:
myCss — файл стиля для подключения
myScript — скрипт для подключения функций
myTitle — тот заголовок, что видно в окне браузера
myBody — то хорошее место, куда будем грузить наш шаблон
Файл получился более, чем миниатюрный, однако от этого не менее функциональный!

Этап 3. my.js
Вот это самая сложная часть, с точки зрения времязатратности. Я на написание этого файла потратил почти 4 часа!
Список функций, которые я написал для дальнейшей работы:
$() — получение DOM объекта по id
$$() — получение DOM объекта по name
hScreen() — высота экрана юзера
wScreen() — ширина
whMonitor() — ширина/высота экрана (не браузера)
showhide() — скрывает/открывает объект
hide() – скрывает объект
show() — открывает
startajax() вернет объект для работы с AJAX потоком
setCookie() — устанавливает cookie запись в браузер
getCookie() — соответственно, вернет их
i() — аналог parseInt
bottomObj() — располагает объект под объектом, принимает id объектов и две переменные смещения вверх/влево
fDown() — прижмет объект в низ экрана (position: fixed;)
fRight() — прижмет к правому краю
Обе функции не чувствительны к скроллингу
goURLA() — переходит по ссылке в асинхронном режиме
reLoad() — переходит по ссылке в асинхронном режиме, только если пользователь нажмет на навигационные кнопки (назад/вперед)
loadTempl() — функция загрузки шаблона
getPageName() — возвращает название файла страницы из URL адреса
pdaAd() — позиционирует объекты, в случае, если экран слишком узкий (меньше 800px)
allLinkToClick() — функция пробегает по всем ссылкам и делает асинхронными, если поддерживает браузер, иначе не пробегает.
placebo_start() — та самая функция в onload тела документа (объект «body»). Она подгружает шаблон, стили, и пробегает по ссылкам при возможности.

Вот и все. Расписывать сами функции не буду, при желании можно заглянуть в исходник.

Работает в Chrome и Opera и Mozilla новых версий, на старых не тестировал, и тем более не тестировал на IE, ибо на него вообще пофигу. Будет у кого желание, проверьте! Ссылка на демо в конце статьи.

Теперь про переменные, которые я описал в JS:
showhide_arr — массив состояний для объектов (функции show/hide/showhide)
page — массив данных о текущей странице,
site — массив данных с инфой о сайте
menu — массив нашего меню, который рендерится юзеру при загрузке шаблона
device — хранит высоту / ширину клиента

Этап 4. Обработка ссылок. (ёп-ёп-ёп)
Это отдельный этап работы. Я ведь полностью отказался от серверной части работы, значит все делаем через JS. Функция для перехода по ссылке:
function goURLA(pageName, func) 
{ 
 var ajax= startajax(); // создаем объект для работы с AJAX
 ajax.open('GET', site.domain+'pages/'+pageName+'.html');  // посылаем запрос бедному серверу, который даже не в курсе, что творится
 ajax.onreadystatechange = function ()   
 {  
  if(ajax.readyState == 4)   // если загрузка окончена
  {  
   if (ajax.status != 404) // и если это не 404 ответ от сервера
   { 
    $('myData').innerHTML= ajax.responseText; // рисуем юзеру страницу
    $('myTitle').innerHTML= $('myH2').innerHTML; // рисуем браузера зуголовок
    window.history.pushState(null, null, site.domain+'index.html?' +pageName); // добавляем запись в историю браузера, что мы перешли на новую страницу и заодно меняем строку адреса
   } else { $('myData').innerHTML= '<div id="myError">Ошибка загрузки! Код ошибки: 404</div>'; } // на тот случай, если сервер не нашел страницу, которую нам надо
   if (func) func(); // если была функция, выполняем ее
  }  
  else { $('myData').innerHTML= '<div id="myError">Ошибка загрузки! Код ошибки: 500</div'; } //  на тот случай, если сервер нас обломил
 }  
 ajax.send(null); / посылаем запрос
}



Этап 5. Нелокальный Chrome от Google.
Тут чисто о том, что я заметил. Chrome, а точнее его Linux воплощение — Chromium, не умеет работать в асинхроне с локальными файлами. Это на будущее, для тех, кто соберется отлаживать AJAX без сервера. Тут либо использовать Mozilla, который с этим прекрасно справляется, либо завести сервер. Я завел сервер LAMP, чтобы убить сразу двух зайцев — потестить в Chrome и Mozilla, а заодно обкатать разработку на Apache в режиме эмулирования разных девайсов. И мой вердикт — замечательно! Конечно, работы еще много, но результат уже есть!

Этап 6. Файлы страниц.
Тут все до одури просто:
<h2 id="myH2">Заголовок страницы</h2> 
<p id="myHTML"> 
Основной текст страницы! 
</p> 
<p id="myFooter"> 
Какая-нибудь подпись под текстом
</p>

Это файл страницы. Все просто и смешно!

Этап 7. Внешний вид
WEB
image
PDA
image
Вот так выглядит сайт в режиме отладки в Chrome. Никаких ошибок и ничего прочего! Все прекрасно работает! Странички грузятся, адрес сайта меняется, наполняй сайт страницами и радуйся!

Этап 7. Допиливание.
Теперь пришло время доделать все до нормального состояния и опубликовать на хостинге, дабы протестировать и ввести в эксплуатацию. Так как у меня все настройки и функции находятся в одном JS файле, я решил разбить их на три файла:
java/my.js — функции и обработчики
java/settings.js — переменные и объекты для работы. Настройки сайта.
pages/menu.js — переменные хранящие меню сайта.

Файл menu.js я перенес в папку «pages» для того, чтобы было легко обновлять материалы на сайте — закинул на сервер одну папки с заменой совпадений — и дело сделано, сайт обновлен!

Осталось только изменить «index.html», чтобы он принимал эти файлы, поэтому я его видоизменил до следующего вида:
<!DOCTYPE html>
<html> 
 <head>
  <meta http-equiv="Cache-Control" content="no-cache">
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <link id="myCss" type="text/css" rel="stylesheet" href="">
  <script id="mySettings" type="text/javascript" src="java/settings.js"></script>
  <script id="myMenuConf" type="text/javascript" src="pages/menu.js"></script>
  <script id="myScript" type="text/javascript" src="java/my.js"></script>
  <title id="myTitle"></title>
 </head>
 <body id="myBody" onload="placebo_start();"></body>
</html>



Однако… а если я захочу на сайте разместить какой-нибудь счетчик? Посредством моих обработчиков страницы не могут содержать скрипты…
Еще немного модфифцирую страницу:
<!DOCTYPE html> 
<html> 
 <head> 
  <meta http-equiv="Cache-Control" content="no-cache"> 
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
  <link id="myCss" type="text/css" rel="stylesheet" href=""> 
  <script id="mySettings" type="text/javascript" src="java/settings.js"></script> 
  <script id="myMenuConf" type="text/javascript" src="pages/menu.js"></script> 
  <script id="myScript" type="text/javascript" src="java/my.js"></script> 
  <title id="myTitle"></title> 
 </head> 
 <body onload="placebo_start();"> 
  <div id="myBody" ></div> 
 </body> 
</html>



Итак, я вынес блок «myBody» в отдельный блок. Теперь он будет являться хранителем всего содержимого сайта при динамической подгрузке, остальной код можно смело списывать как до него так и после. И даже JS, который мне может потребоваться. Вердикт — Идеально! Конечно, на текущее время, что будет потом не знает никто.

Вывод.
Сей проект я затеял для публикации небольших статей и демо-проектов от имени своего канала на YouTube, потому что прикладывать исходник к видео хорошо, а иметь живой пример — еще лучше! Кроме всего прочего, сайт на этой системе никак не грузит сервер, вся работа ложится на клиент-браузер.
Заморачиваться с установкой каких-либо CMS мне тоже не очень хотелось, как и искать нормальный хостинг, где эти CMS бы запускались и не глючили, а там еще и настройка БД, дампы, ну их всех.
Создавать сайт при помощи html редактора и создания каждой страницы в отдельности тоже не для меня, а вдруг я захочу сменить дизайн? Править каждый раз все файлы? А если их будет больше 100? А если больше 1000?
Именно для этого и была создана такая вот небольшая псевдо CMS.
Никоим образом не призываю делать так же, просто делюсь опытом, на тот случай, если кто-то захочет сделать что-либо подобное.
Время разработки от идеи до внедрения: ~7 часов =)

Итог сей басни есмь таков:
Плюсы:
+ не грузит сервер никак
+ работает очень быстро, ибо нет никаких БД
+ невозможно взломать
+ невозможно получить доступ к админке, так как ее нет =)
+ возможность смены дизайна
+ легкий перенос на любой сервер
+ не требует MySQL и PHP, вообще ничего не требует
+ маленький вес! Ну совсем маленький, 5kb всего.
+ расширяется в любую сторону, куда фантазия глянет

Минусы:
— Плохая индексируемость поисковиками, если не нулевая
— Необходимость лезть в файлы, чтобы что-то поправить
— Требуются минимальные знания HTML


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

PS: Ссылку на пример только в ЛС, ибо в прошлый раз за ссылку на ДЕМО получил бан на неделю. Ну его рисковать…

Комментарии (14)


  1. impwx
    04.07.2015 13:24
    +1

    Идея любопытная, но по сути это не cms, что подразумевало бы управление контентом, а просто собираемый на клиенте статический сайт.


    1. Skaner Автор
      04.07.2015 13:30
      -1

      Об этом тоже знаю, но не придумал лучшего названия а CMS более привычно. Это скорее просто система доступа к данным, и все. Я пробовал на виртуальной машине заходить с IE, работает, собака, с глюками и сообщениями об ошибках, но работает!


      1. lair
        04.07.2015 13:54

        А зачем вам это как-то называть? Сайт — он и есть сайт.


  1. ateraefectus
    04.07.2015 13:49

    Неплохая задумка, но

    работает очень быстро, ибо нет никаких БД

    — одна сторона медали. Переложение всего на клиента может привести к гораздо большей потере скорости, чем она могла бы быть с серверными БД.


    1. Skaner Автор
      04.07.2015 13:53

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


      1. ateraefectus
        04.07.2015 14:01

        Единственно, если страница будет содержать в себе несколько МБ текста, то возникнет «залипание» на какое-то время

        Об этом-то я и говорю.


  1. lair
    04.07.2015 13:57
    +2

    невозможно взломать

    Возможно. Достаточно получить доступ к месту хранения файлов.


    1. Skaner Автор
      04.07.2015 14:00
      -1

      Сервер не поддерживает PHP, что можно в этом случае сделать? Интересны ваши мысли для совершенствования работы.


      1. lair
        04.07.2015 14:02

        Вы же как-то туда файлы заливаете? Вот этим каналом и воспользоваться. Ну и плюс в сервере свои уязвимости встречаются.


        1. Skaner Автор
          04.07.2015 14:04

          Через FTP заливаю. Но таким способ взламывается уже все что угодно, тот де VK, на него ведь тоже файлы как-то заливают… Но тут спорить не могу, ибо защититься от уязвимостей самого сервера / хостинга непосредственно пользователю сложно.


          1. lair
            04.07.2015 14:05

            Про это и речь: взламывается что угодно.

            (а FTP, кстати, весьма несекьюрный протокол)


            1. Skaner Автор
              04.07.2015 14:08
              -1

              Увы, я пока осваиваю только всё это. Раньше занимался разработкой игр, и подобные вещи были, мягко говоря, далеки от меня. Однако, область довольно интересная для освоения. Думаю что делать дальше. Но спасибо за отзыв! Про взлом самого FTP я даже как-то и не подумал…


  1. anyxem
    04.07.2015 14:22
    +1

    Как всё сложно. GitHub + TravisCI, с ними вообще можно из чего угодно собирать html (напрмер шаблоны в Jade или Hammer, стили в Stylus, контент в Markdown и структурой катологов) и заливать куда требуется, а может и вообще оставить в hg-pages и смаппить домен на него


  1. m1el
    04.07.2015 14:28
    +1

    |> java — хранилище js функций (захотелось назвать java)

    ?_?

    Если уже использовать статику, то почему бы не использовать статику по полной? Например, jekyll.
    Нет смысла использовать жс, где он попросту не нужен — переход по ссылкам.