Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. CMS
Code

Створюємо CMS: nodePress

by
Difficulty:IntermediateLength:LongLanguages:

Ukrainian (українська мова) translation by AlexBioJS (you can also view the original English article)

Ви вже вдало створили CMS (* content management system – система керування контентом; використовують для організації автоматизованого збирання, керування та публікації інформації; ПЗ для фільтрації, публікації, обслуговування і відновлення контенту веб-сайтів і порталів), що працює на основі плоскої файлової системи (* система організації файлів, при якій вони не можуть мати однакових імен, якщо навіть знаходяться у різних каталогах), за допомогою Go. Наступний крок – реалізувати те саме за допомогою Node.js. Я покажу вам, як завантажити бібліотеки, створити та запустити сервер.

У цій CMS ми будемо використовувати ту структуру даних сайту, яку було показано у першому посібнику, «Building a CMS: Structure and Styling». Тому завантажте та витягніть архів з цією базовою структурою до порожньої папки.

Встановлюємо Node та бібліотеки для неї:

Найпростіший спосіб встановити Node.js на Mac – за допомогою Homebrew (* найпопулярніший пакетний менеджер для Mac). Якщо Homebrew у вас ще не встановлено, то можете подивитися, як це зробити, у посібнику «Homebrew Demystified: OS X’s Ultimate Package Manager».

Для встановлення Node.js за допомогою Homebrew виконайте наступну команду у командному рядку:

Після її виконання на вашому Mac стануть доступні всі команди з node та npm. Для встановлення Node.js на решту платформ дотримуйтесь інструкцій, які наведено на веб-сайті Node.js.

Будьте обережні: багато пакетних менеджерів зараз встановлюють Node.js версії 0.10. У цьому посібнику припускається, що ви використовуєте версію 5.3 або новішу. Ви можете перевірити, яку версію ви використовуєте за допомогою:

За допомогою команди з node запускається інтерпретатор JavaScript. За допомогою команди з с npm до справи береться пакетний менеджер Node.js для встановлення бібліотек, створення нових проектів та запуску скриптів для проекту. На Envato Tuts+ є велика кількість чудових посібників та курсів з Node.js та npm.

Для встановлення бібліотек для сервера вам потрібно виконати наступні команди у програмі Terminal.app або iTerm.app:

Express – фреймворк для розробки веб-застосунків. Він подібний бібліотеці goWeb у Go. Handlebars – шаблонізатор (* ПЗ для комбінування шаблонів з моделлю даних для отримання кінцевих документів) для створення сторінок. Moment – бібліотека для роботи з датами. Marked – відмінний конвертер Markdown до HTML для JavaScript. Jade – рівень абстракції HTML для простішого створення HTML-сторінок. Morgan – бібліотека ПЗ проміжного шару для Express, за допомогою якої генеруються лог-файли (* запис у журналі реєстрації подій, що фіксує дію та подію, що відбулася у комп'ютерній системі) стандарту Apache (* Common Log Format – загальноприйнятий формат лог-файлів).

Альтернативний варіант встановлення необхідних бібліотек – завантажити початкові файли для цього посібника. Після завантаження архіву та його витягнення виконайте наступну команду у головній папці проекту:

Завдяки цьому буде встановлено все, що необхідно для створення розглядуваного тут проекту.

nodePress.js

Тепер ми можемо взятися за створення сервера. У кореневій папці проекту створіть файл під назвою nodePress.js, відкрийте його у своєму улюбленому редакторі та починайте додавати туди наступний код: Я буду пояснювати код по мірі його додавання до файлу.

Код починається з підключення всіх потрібних для реалізації сервера бібліотек. Бібліотеки, для яких не вказано коментарі з веб-адресами, постачаються у складі самої платформи Node.js.

Потім я задаю значення всіх глобальних змінних та налаштування бібліотеки. Підхід з використанням глобальних змінних не належить до усталеної практики (* загальноприйнята практика, що не є правилом) створення додатків, але працює та прискорює процес розробки.

Змінна parts – хеш (* колекція пар ключ-значення, причому ключом є рядок), що містить всі частини веб-сторінки. Її контент використовується при створенні кожної сторінки. Контент цієї змінної починається з вмісту файлу server.json, що знаходиться у кореневій папці сервера.

Потім я використовую інформацію з файлу server.json для створення повних шляхів до папок styles та layouts, що використовуються для нашого сайту.

Далі у якості значень трьох змінних (siteCSS, siteScripts та  mainPage) задається null. У цих глобальних змінних буде міститися контент всіх файлів CSS, JavaScript та головної сторінки. Ці три елементи запитуються найчастіше на всіх серверах. Тому завдяки розміщенню їх у пам'яті ми прискорюємо роботу сайту. Якщо значенням властивості Cache у файлі server.json є false, то ці елементи зчитуються заново при кожному запиті.

У цьому коді налаштовується бібліотека Marked для отримання HTML з Markdown. Головним чином, тут я активую підтримку таблиць та «розумних» списків (* smartList; список з підтримкою фільтрів).

Потім до змінної parts додається контент папок styles та layouts. Контент кожного файлу папки parts, що розташовується у папці site також завантажується до глобальної змінної parts. Ім'я файлу без розширення – ім'я, що використовується для збереження контенту файлу. Ці імена замінюються набором інструкцій у макросах (* (від грец. makros - великий, довгий) послідовність команд і/або натискань клавіш, записана макрорегістратором під унікальним ім'ям; блок команд, асоційований із певним унікальним ім'ям) Handlebars.

У наступній частині коду йде визначення хелперів Handlebars, що будемо використовувати у веб-сервері: save, date та cdate. У хелпері save передбачається створення змінних на сторінці. Ця версія хелпера підтримує версію CMS goPress, в якій у параметрі одночасно присутні ім'я та значення разом, розділені за допомогою “|”. Також можна задати використовувані у хелпері значення за допомогою двох параметрів. Наприклад:

В обох випадках отримуємо однаковий результат. Мені більше подобається другий підхід, проте у бібліотеці Handlebars, що використовується для Go не передбачається передача більше одного параметра.

За допомогою хелперів date та cdate форматується поточне значення дати (date) або вказане (cdate) згідно з правилами форматування, що вказані в бібліотеці moment.js. При використанні хелпера cdate передбачається, що дату, яку потрібно відформатувати, буде передано у якості першого параметра у форматі ISO 8601 (* міжнародний стандарт, що описує обмін інформацією про дати та час, а також деякими іншими даними, що пов'язані з часом; створений в International Organization for Standardization (ISO) та вперше опублікований в 1988).

Далі в коді створюється зразок Express для налаштування власне сервера. За допомогою функції nodePress.use() відбувається налаштування ПЗ проміжного шару. ПЗ проміжного шару – будь-який код, що виконується при кожному запиті до серверу. Тут я налаштовую бібліотеку Morgan.js для отримання потрібного формату записів у журналі реєстрації подій.

У цьому розділі коду визначаються всі потрібні для реалізації сервера маршрути. У всіх маршрутах виконується функція setBasicHeader() для встановлення потрібних значень заголовків. У результаті будь-яких запитів на отримання сторінок буде викликано функцію page(), у той час як в результаті будь-яких запитів на отримання постів буде викликано функцію post().

Значенням за налаштуванням для заголовка Content-Type – HTML. Тому при відправленні CSS, JavaScript та зображень ми спеціально задаємо для Content-Type відповідне значення.

Також ви можете визначати маршрути за допомогою методів REST (* Representational State Transfer – передача репрезентативного стану; підхід до архітектури мережевих протоколів, які забезпечують доступ до інформаційних ресурсів) put, delete та post. У цьому невеликому сервері використовується тільки метод get.

Нам залишилось тепер, перед визначенням різних використовуваних у коді функцій, тільки запустити сервер. У файлі server.json міститься DNS-ім'я (у нас localhost) та порт для сервера. Після парсингу (* розбиття рядка тексту на складові частини) у функції listen() використовується номер порту для запуску сервера. Після відкриття порту сервера завдяки скрипту до консолі виводиться адреса та порт сервера.

Перша функція, яку будемо визначати, – setBasicHeader(). За допомогою цієї функції встановлюється значення спеціального заголовку відповіді для повідомлення браузерові про потребу гешування сторінки на один місяць. Також завдяки ній браузеру повідомляється, що сервер – це сервер nodePress. Якщо би ви хотіли додати ще якісь стандартні заголовки, то додали би їх за допомогою функції response.append() .

У функції page() шаблон розмітки сторінки та адреса сторінки на сервері передаються до функції processPage().

Функція post() подібна функції page(), за винятком того, що при створенні поста використовується більше інформації. У створюваних у цій серії посібників серверах пост містить тип, категорію та власне пост. Типом поста є або blogs, або news. Категорія  – flatcms. Оскільки ними є імена директорій, то ви можете давати їх будь-які імена. Просто підберіть ім'я таким чином, щоб воно співпадало з тим, що використовується у вашій файловій системі.

Функція processPage() приймає макет та шлях до потрібного для відображення контенту сторінки. Код функції починається зі створення локальної копії глобальної змінної parts та додавання ключа, використовуваного для розміщення  “контенту”, значенням якого є результат виконання функції figurePage(). Далі у якості значення PageName задається ім'я сторінки.

Далі відбувається компіляція контенту сторінки у шаблон з розміткою за допомогою Handlebars. Потім завдяки функції processShortCodes() весь скорочений код на сторінці буде перетворено у повний. Після цього шаблонізатор Handlebars проганяє код через себе ще раз. І потім браузер отримує результат.

Функція processShortCodes() приймає контент веб-сторінки у якості рядка та здійснює пошук усіх частин коду у скороченому вигляді. Скорочений код – це блок коду, подібний тегам HTML. Прикладом міг би стати:

У цьому коді є скорочений код для box навколо параграфа HTML. Там, де в HTML використовується < и >, у скороченому коді використовується -[ и ]-. Після імені може при потребі додаватися рядок з аргументами для скороченого коду.

У функції processShortCodes() відбувається пошук скороченого коду, отримання його імені та аргументів, знаходження його кінці для отримання контенту, оброблення цього контенту, виконання скороченого коду з урахуванням аргументів та контенту, додавання результат до фінальної сторінки та пошук решти частин скороченого коду на сторінці. Уведення циклу здійснюється завдяки рекурсивному виклику функції.

У цій частині йде json-структура скороченого коду, у якій визначаються імена скороченого коду зі зв'язаними з ними функціями. Всі функції для скороченого коду приймають два параметри: args та inside. аrgs – все, що йде після імені та пробілу до кінця тегу. inside – все, що розташовується між відкриваючим та закриваючим тегами скороченого коду. Це базові функції, проте ви можете створити скорочений код для виконання будь-чого на JavaScript, що  спадає вам на думку.

Функція figurePage() отримує повний шлях на сторінку на сервері. Потім у цій функції перевіряється формат сторінки (HTML, Markdown або Jade) на основі розширення. Я як і раніше використовую .amber для коду на Jade, оскільки я використовував бібліотеку Аmber при створенні сервера goPress. Весь контент на Markdown та Jade транлюється в HTML перед його передачею рутинній функції (* return()). Оскільки процесор Markdown перетворює всі лапки у &quot;, то я перетворю їх назад перед поверненням результату.

Функція fileExists() – заміна для функції fs.exists(), що буда частиною бібліотеки fs Node.js (* до версії 1.0.0). У ній використовується функція fs.statSync(), щоб спробувати отримати статус файлу. У разі помилки функція повертає false. Інакше – true.

Переходимо до останньої функції – MergeRecursive(). У ній відбувається копіювання другого переданого об'єкта до першого. Я її використовую для копіювання вмісту головної змінної parts до локальної копії перед додаванням частин, властивим різним сторінкам.

Запускаємо сервер локально:

Після зберігання файлу ви можете запустити сервер за допомогою:

У якості альтернативного варіанта ви можете використати вказаний у файлі package.json скрипт, що запускається за допомогою команди npm. Запуск скриптів за допомогою npm виконується наступним чином:

За допомогою цієї команди буде виконано скрипт start, який вказано у файлі package.json.

nodePress Server Main Page
головна сторінка сервера nodePress

Перейдіть у вашому браузері за http://localhost:8080 і ви побачите сторінку, показану вище. Ви, напевно, помітили, що я додав додатковий код для тестування сайту на головну сторінку. Зі внесеними на сторінки змінами ви можете ознайомитися у приєднаних файлах. Це, головним чином, просто деякі невеликі поправки, внесені для повнішого тестування функціональних можливостей та підгонки коду під вимоги різних бібліотек. Найзначніша різниця полягає в тому, що в бібліотеці Jade на використовується $ при найменування змінних, а в Amber використовується.

Завершення

Тепер ми маємо ідентичні CMS, що працюють на основі плоскої файлової системи, реалізовані за допомогою Gо та Node.js. Ми скористалися тільки базовими можливостями цієї платформи. Поекспериментуйте та спробуйте щось нове. Це саме цікаве при створенні власного сервера.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.