# Движок сайта на NodeJS

Давайте рассмотрим структуру типичного сайта:

`<!DOCTYPE html> <html> <head> <title>page title</title> </head> <body> <div id="wrapper"> <header> common header <nav> common menu </nav> </header> <main> page content </main> <aside> common sidebar </aside> <footer> common footer </footer> </div> </body> </html>`

Как вы видите, у страницы сайта как правило есть хедер, футер, сайдбары и контент.

При этом на многостраничном сайте все страницы сайта отличаются лишь контентом и тайтлом, а хедер, футер и сайдбары остаются одинаковым.

Это создает определенные неудобства в поддержке сайта: если у вас на сайте сто страниц, то у них будет сто одинаковых хедеров, раскиданных по ста файлам. Если вам что-то нужно будет поменять в хедере сайта - вам придется сделать это сто раз! Это, конечно же, не удобно.

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

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

Когда браузер запрашивает страницу сайта, то сервер по запрошенному URL получает файл с тайтлом и контентом, затем берет файл шаблона и подставляет тайл и контент в специально обозначенные места шаблона.

В результате получается готовая HTML страница со всеми частями, которая и отправляется в браузер.

Места для вставки изменяющихся частей в шаблоне обозначаются с помощью придуманных нами команд. Например, я могу сказать, что место вставки тайтла обозначим как `{% get title %}`, а место вставки контента как `{% get content %}`. С такими командами файл шаблона может иметь следующий вид:

`<!DOCTYPE html> <html> <head> <title>{% get title %}</title> </head> <body> <div id="wrapper"> <header> common header </header> <main> {% get content %} </main> <aside> common sidebar </aside> <footer> common footer </footer> </div> </body> </html>`

## Реализация

Итак, давайте реализуем описанное. Для начала продумаем файловую структуру. Пусть в папке `page` лежат изменяющиеся части, причем тайтл и контент одной страницы в разных файлах в одной папке. Адрес их папки пусть соответствует URL страницы.

Пусть, к примеру, запрошен адрес `/dir/name/`. Тогда тайтл этой страницы будет лежать в файле `/page/dir/name/title.html`, а контент - в файле `/page/dir/name/content.html`.

В папке `root` разместим ресурсы сайта (для простоты их пока проигнорируем), а шаблон сайта - в файле `layout.html`.

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

Реализуем описанное:

`http.createServer(async (request, response) => { let lpath = 'layout.html'; let cpath = 'page' + request.url + 'content.html'; let tpath = 'page' + request.url + 'title.html'; let layout = await fs.promises.readFile(lpath, 'utf8'); let content = await fs.promises.readFile(cpath, 'utf8'); let title = await fs.promises.readFile(tpath, 'utf8'); layout = layout.replace(/\{% get content %\}/, content); layout = layout.replace(/\{% get title %\}/, title); response.writeHead(200, {'Content-Type': 'text/html'}); response.write(layout); response.end(); }).listen(3000);`

Возьмите приведенный код и потестируйте его работу.

Реализуйте показ `404` страницы в случае, если URL не соответствует файлу. Пусть `404` страница хранится в файле `page/404/title.html` и `page/404/content.html`.

Добавьте к вашему коду работу с ресурсами.

Кроме тайтла и контента на страницах сайта может также изменяться мета-описание (погуглите). Реализуйте возможность добавлять его к страницам сайта.

Возьмите созданный вами в предыдущем уроке сайт из `6`-ти страниц. Переделайте его в соответствии с данным уроком.

← →
↑