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

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

html<!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>

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

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

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

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

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

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

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

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

html<!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/. Toгда тайтл этой страницы будет лежать в файле /page/dir/name/title.html, а контент - в файле /page/dir/name/content.html.

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

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

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

javascripthttp.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);
Задание 1

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

Задание 2

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

Задание 3

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

Задание 4

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

Задание 5

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