Как создать сайт с помощью Node.js и Express

Как создать сайт с помощью Node.js и Express

Веб-приложение Node.js

В этом примере создается веб-сайт с использованием Node.js для обеспечения логичного поведения веб-сайта. Использование Express.js рамки, сайт реализован как веб приложение, с логической маршрутизацией в другие разделы сайта.

HTML и CSS основаны на наших адаптивный дизайн веб-сайтов с использованием CSS Grid и Flexbox. HTML — это реорганизованный как шаблон, поэтому код макета можно повторно использовать при добавлении новых страниц.

Установить узел

Node.js, также называемый Узел, это среда выполнения для написания серверных приложений на JavaScript.

Примечание

Если Node уже установлен на вашем компьютере, вы можете пропустить этот раздел и перейти к сделать новое приложение Express.

Загрузите установщик Node из официальный сайт загрузок Node.js. Выберите версию LTS (долгосрочная поддержка) для вашей операционной системы.

Windows и macOS

Откройте и запустите установщик узла (.msi в Windows, .упак. на macOS).

В Windows на экране установки, помеченном Инструменты для собственных модулей, поставить галочку Автоматически установить необходимые инструменты.

Linux

В системах Linux вы можете установить Node с помощью диспетчера пакетов, установить скомпилированные двоичные файлы вручную или собрать Node из исходного кода. Для получения подробной информации см. официальная вики по установке Node.js.

Все операционные системы

По завершении установки откройте окно терминала или командной строки. Выполните следующую команду, чтобы обновить npm, менеджер пакетов Node. В -грамм (глобальный) переключатель указывает, что программное обеспечение установлено в масштабе всей системы, а не только в текущем приложении Node..

Окна

npm install -g npm

Linux и macOS

sudo npm install -g npm

Наконец, используйте npm для глобальной установки экспресс-генератор заявление.

Окна

npm install -g экспресс-генератор

Linux и macOS

sudo npm install -g экспресс-генератор

Создайте новое приложение Express

В окне терминала или командной строки сгенерируйте новое приложение Express.js. В нашем примере имя приложения myapp, и механизм просмотра указан как мопс.

выразить myapp —view ="мопс"

Измените каталог на новое приложение Express.

cd myapp

В каталоге приложения Express используйте npm install для загрузки и установки необходимых зависимостей, как указано в файле package.json.

npm install

Если для установленных зависимостей доступны какие-либо обновления безопасности, отображается уведомление..

обнаружил 1 уязвимость низкой степени серьезности, запустите `npm audit fix`, чтобы исправить их, или` npm audit`, чтобы узнать подробности

Если да, примените обновления безопасности..

исправление аудита npm

Установить nodemon

В каталоге приложения Express установите nodemon. Опция —save-dev указывает, что nodemon является зависимостью разработки. Он не используется в самом приложении, но является инструментом, используемым во время разработки..

npm install —save-dev nodemon

Добавить сценарий запуска разработки

А сценарий запуска разработки предоставляет способ запустить ваше веб-приложение с опциями, которые помогут вам разработать приложение, например, с подробными сообщениями об ошибках..

В текстовом редакторе откройте файл package.json в каталоге приложения. Этот файл JSON определяет зависимости, используемые вашим приложением Node. Кроме того, он содержит именованные сценарии запуска которые запускают приложение разными способами.

В package.json найдите "скрипты" Вход. По умолчанию он содержит только один скрипт («старт»)..

"скрипты": { "Начните": "узел ./bin/www" },

Добавьте новую строку, определяющую скрипт devstart следующее.

Linux и macOS

"скрипты": { "Начните": "узел ./bin/www", "devstart": "ОТЛАДКА = myapp: * nodemon ./bin/www"
},

Окна

"скрипты": { "Начните": "узел ./bin/www", "devstart": "УСТАНОВИТЬ ОТЛАДКУ = myapp: * & nodemon ./bin/www"
},

Эти скрипты ("Начните" и "devstart") можно выполнить, запустив команду npm run имя сценария.

Команда npm запустить devstart запускает приложение с двумя включенными дополнительными функциями разработки.

  • В ОТЛАЖИВАТЬ установлена ​​переменная среды, указывающая, что журнал консоли и страницы ошибок, такие как HTTP 404, отображают дополнительную информацию, например трассировку стека..
  • Кроме того, nodemon отслеживает определенные важные файлы веб-сайта. Если вы измените эти файлы, например, измените дизайн страницы или измените статическое содержимое, nodemon автоматически перезапустит сервер, чтобы отразить изменения..

Запустить веб-сервер в режиме разработки.

npm запустить devstart
Кончик

Если брандмауэр Windows блокирует приложение веб-сервера, щелкните Разрешить доступ.

Предварительный просмотр веб-приложения

Когда приложение запущено, ваш компьютер действует как веб-сервер, обслуживая HTTP на порт 3000.

Для предварительного просмотра веб-сайта откройте веб-браузер по адресу локальный: 3000.

Приложение Express.js по умолчанию

Любое устройство, подключенное к вашей локальной сети, может просматривать приложение по адресу айпи адрес: 3000, куда айпи адрес местный айпи адрес компьютера, на котором запущено приложение.

Кончик

Если вы не знаете, какой у компьютера локальный IP-адрес, см.: Как узнать мой IP-адрес.

Чтобы просмотреть веб-сайт на мобильном устройстве, подключите его Wi-Fi к локальной сети и откройте адрес в браузере..

Express.js на мобильном телефоне

HTML-шаблоны

В нашем примере используется CSS, JavaScript и HTML из статьи о том, как создать адаптивный веб-сайт с помощью CSS Grid и Flexbox.. CSS и JavaScript используются дословно. HTML — это реорганизованный к язык шаблонов.

При использовании языка шаблонов код макета пишется только один раз и наследуется другими страницами..

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

Express.js поддерживает несколько механизмов просмотра, включая Мопс.

Обзор мопса

Язык мопсов описывает HTML-документы, обеспечивающие преимущества и дополнительные функции. Файлы Pug преобразуются в HTML, когда пользователь запрашивает их..

Синтаксис языка Pug устраняет необходимость в теги следует закрыть или заключить в квадратные скобки. Он также поддерживает унаследованные шаблоны, итерация, условные, и оценка JavaScript.

Пример преобразования HTML в Pug

Это первые несколько строк HTML из статьи о том, как создать адаптивный веб-сайт с помощью CSS Grid и Flexbox.

<!DOCTYPE html> <html lang ="en"> <голова> <мета-имя ="область просмотра" содержание ="width = ширина устройства, начальный масштаб = 1"> <мета-кодировка ="utf-8"> <заглавие>Заголовок</заглавие> <ссылка rel ="таблица стилей" href ="index.css"> <скрипт src ="index.js"></ скрипт> </голова> <тело> <div id ="меню"> <раздел id ="Пункты меню"> <div class ="кнопка меню"> <h1 onclick ="menuToggle (‘скрыть’)" class ="кнопка меню">&# 9776;</ ч1>

В Pug тот же HTML можно написать так:.

doctype html html head meta (name ="область просмотра" содержание ="width = ширина устройства, начальный масштаб = 1") мета (кодировка ="utf-8") title Ссылка на заголовок (rel ="таблица стилей", href ="index.css") скрипт (src ="index.js") body # раздел меню # элементы меню .menubutton h1.menubutton (onclick ="menuToggle (‘скрыть’)") &# 9776;

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

В "я бы" и "учебный класс" Селекторы CSS можно записать как элемент # id, element.class, element # id.class, и т. д. Если элемент не указан, предполагается, что это div. Например, <div class ="фу"> в HTML можно записать как .фу в мопсе.

После имени элемента и его селекторов атрибуты могут быть указаны в круглых скобках в виде списка, разделенного запятыми. Например:

HTML

<div class ="кнопка" onmouseover ="светиться()" onclick ="Начните()">

Мопс

.кнопка (onmouseover ="светиться()", onclick ="Начните()")

Перечисление нескольких элементов в одной строке

Если за элементом следует двоеточие (:), за ним может следовать дочерний элемент в той же строке. Следующие два раздела Pug производят одинаковый вывод HTML..

а (href ="/дома") p Домой
a (href = «/ home»): p На главную

Оба из вышеперечисленных отображаются в следующем HTML.

<a href = «/ дом»><п>Дома</п></ а>

Оценка JavaScript

Если за элементом следует знак равенства (знак равно) все, что следует за этой строкой, интерпретируется как буферизованный код. Код оценивается как JavaScript, а вывод "буферизованный" (входит в состав содержимого элемента). В простейшей форме буферизованный код может быть именем переменной, переданной приложением..

Например, маршрутизатор приложений для домашней страницы, index.js, передает переменную заглавие со значением "Наш фермерский стенд" к методу express.Router (), который передает его Мопсу. Когда Мопс рендерит layout.pug, следующая строка:

title = pagetitle

…интерпретируется как:

title Наша ферма

…который отображается как следующий HTML:

<заглавие>Наша ферма</заглавие>

Наследование шаблона

Документы Pug могут наследовать другие документы Pug, используя ключевые слова расширяет и блокировать.

Например, вы можете создать базовый макет сайта., layout.pug, который содержит общие элементы страницы.

doctype html html заголовок заголовка Заголовок страницы body p Содержимое блокировать фу

В блокировать фу в заявлении говорится "вставьте сюда блок содержимого с именем фу, указан в другом документе Pug, который наследует этот шаблон."

Документы, наследующие layout.pug, должны начинаться с утверждения расширяет макет, и содержать блокировать фу оператор на верхнем уровне отступа (в начале новой строки). Дети этого "блокировать фу" инструкции вставляются в шаблон в месте расположения соответствующего блока.

Документ Pug может наследовать layout.pug как следующее.

расширяет блок макета foo p Это домашняя страница.

Когда документ визуализируется, движок Pug загружает файл layout.pug. Линия блокировать фу в layout.pug заменяется на p Это домашняя страница.

Обзор приложения Express по умолчанию

Здесь указана стандартная структура приложения Express с описанием каждого файла и каталога..

myapp / (Содержит все приложение Express) ├─ app.js Основная логика приложения Express. ├─ bin / (содержит исполняемые скрипты приложения) │ └─ www Обертка, запускающая app.js. ├─ node_modules / (содержит зависимости, установленные npm) ├─ пакет-lock.json Манифест установленных зависимостей в формате JSON. ├─ package.json JSON зависимостей и конфигурации, специфичные для вашего приложения. ├─ public / (Файлы, загруженные веб-браузером пользователя) │ ├─ images / (содержит файлы изображений, доступные для клиента) │ ├─ javascripts / (содержит файлы JavaScript, доступные клиенту) │ └─ таблицы стилей / (Содержит доступный клиенту CSS) │ └─ style.css Таблица стилей CSS сайта. ├─ routes / (содержит логику для отдельных маршрутов сайта) │ ├─ index.js Логика "индекс" маршрут (/). │ └─ users.js Логика "пользователи" маршрут (/ пользователи). └─ views / (содержит шаблоны HTML) ├─ error.pug Просмотр, отображаемый для страниц с ошибками, таких как HTML 404. ├─ index.pug Вид, отображаемый для корня сайта (/). └─ layout.pug Просмотр шаблона макета, общего для всех страниц.

Основные функции веб-сайта определены в app.js. Маршруты названы и указаны в этом файле.

А маршрут это страница или раздел сайта с уникальным путем в URL-адресе, например www.example.com/поиск, www.example.com/авторизоваться, и т. д. Эти маршруты названы и связаны со сценариями логики маршрута в app.js.

Скрипты логики маршрута хранятся в маршруты папка. Когда пользователь запрашивает маршрут, его сценарий логики маршрута обрабатывает данные HTTP-запроса и отправляет ответ..

В взгляды папка содержит шаблоны HTML, называемые взгляды, которые обрабатываются движком просмотра (Pug).

Реализация: JavaScript, CSS и мопс.

Следующий код реализует веб-приложение Express..

Файловая структура приложения

myapp / ├─ app.js Основная логика приложения ├─ bin / │ └─ www
├─ node_modules / ├─ пакет-lock.json
├─ package.json
├─ общественные / │ ├─ изображений/ │ ├─ javascripts / │ │ └─ menu.js Переключатель меню реализует │ └─ таблицы стилей / │ └─ style.css Таблица стилей ├─ маршруты / │ ├─ about.js Логика для маршрута / о │ ├─ advice.js Логика маршрута / совета │ ├─ contact.js Логика для маршрута / контакта │ ├─ index.js Логика для маршрута / │ ├─ recipes.js Логика для маршрута / рецептов │ ├─ tips.js Логика маршрута / подсказки │ └─ users.js Не используется, можно удалить └─ взгляды/ ├─ о. мопс Просмотр маршрута / о ├─ совет. мопс Просмотр маршрута / совета ├─ contact.pug Просмотр маршрута / контакта ├─ error.pug
├─ index.pug Просмотр маршрута / ├─ layout.pug Просмотреть шаблон, общий для всех страниц ├─ recipes.pug Просмотр маршрута / рецептов └─ советы. мопс Просмотр маршрута / советов синий = изменено, зеленый = новый, красный = не используется

myapp / app.js

Основная логика приложения по существу такая же, как и в приложении Express по умолчанию, с определенными дополнительными маршрутами. В "пользователи" маршрут удален.

// основные зависимости var createError = require (‘http-errors’); var express = require (‘экспресс’); var path = require (‘путь’); var cookieParser = require (‘cookie-parser’); var logger = require (‘morgan’); // создаем объекты маршрута var indexRouter = require (‘./ routes / index’); var aboutRouter = require (‘./ routes / about’); var contactRouter = require (‘./ routes / contact’); var tipsRouter = require (‘./routes/tips’);var recipesRouter = require (‘ ./ routes / recipes ‘); var adviceRouter = require (‘ ./ routes / advice ‘);
// объект приложения var app = express (); // просмотр настройки движка app.set (‘views’, path.join (__ dirname, ‘views’)); app.set (‘двигатель просмотра’, ‘мопс’); // конфигурация приложения app.use (logger (‘dev’)); app.use (express.json ()); app.use (express.urlencoded ({extended: false})); app.use (cookieParser ()); app.use (express.static (path.join (__ dirname, ‘public’))); // сообщаем приложению использовать эти маршруты app.use (‘/’, indexRouter); app.use (‘/ about’, aboutRouter); app.use (‘/ contact’, contactRouter); app.use (‘/ tips ‘, tipsRouter); app.use (‘ / recipes ‘, recipesRouter); app.use (‘ / advice ‘, adviceRouter);
// перехватить 404 и перейти к обработчику ошибок app.use (function (req, res, next) {next (createError (404));}); // обработчик ошибок app.use (function (err, req, res, next) {// установить локальные переменные, выдавая только ошибку в разработке res.locals.message = err.message; res.locals.error = req.app.get (‘env’) === ‘development’? err: {}; // отображаем страницу с ошибкой res.status (err.status || 500); res.render (‘error’);}); // предоставляем это приложение скриптам, которые этого требуют, т.е. myapp / bin / www module.exports = app;

myapp / маршруты / layout.pug

В layout.pug Файл содержит основной макет страницы, который используется на каждой странице сайта. Он содержит все необходимое для отображения страницы, кроме основного содержимого (блокировка основного корпуса).

doctype html html head title = pagetitle meta (charset = «utf-8») meta (name ="область просмотра" содержание ="width = ширина устройства, начальный масштаб = 1") скрипт (src ="/javascripts/menu.js") ссылка (rel ="таблица стилей", href ="/stylesheets/style.css") body # раздел меню # элементы меню .menubutton h1.menubutton (onclick ="menuToggle (‘скрыть’)") &# 9776; а (href ="/") h3.menuhead Наша ферма Стенд a (href ="/чаевые") h3.sectrule Советы для хорошей жизни a (href ="/ рецепты") h3 Рецепты a (href ="/совет") h3 Рекомендации по размещению a (href ="/о") h3.sectrule О нас a (href ="/контакт") h3 Свяжитесь с нами #container #header a (href ="/") h1.logo Наша ферма .headspace h1.menubutton (onclick ="menuToggle (‘показать’)") &# 9776; h1.placeholder &# 9776; h2.navitem a (href ="/о") .clickable-area О нас h2.navitem a (href ="/контакт") .clickable-area Свяжитесь с нами # panel.left section # разделы .sectionlink a (href ="/чаевые") .clickable-area Советы для хорошей жизни .sectionlink a (href ="/ рецепты") .clickable-area Рецепты .sectionlink a (href ="/совет") .clickable-area советы по усадьбе блокировка основного корпуса
# panel.right h3 Раздел наших друзей # partners.tall .partnerlink a (href ="/") .clickable-area Green Valley Greens .partnerlink a (href ="/") .clickable-area Ферма на холме в Турции .partnerlink a (href ="/") .clickable-area Кленовый сироп Берта .partnerlink a (href ="/") .clickable-area Only Organic Seeds #footer p Авторские права &копия; 2020 Алиса &amp; Ферма Боба

myapp / просмотров / index.pug

В index.pug файл расширяет layout.pug и содержит основное содержимое для маршрута /.

extends layout block mainbody #mainbody section.mainbodyitems h3 Announcements section.announcements .announceitem h4.title Открыт для бизнеса с даты 15 января p Ремонт нашего нового магазина завершен, и мы открыты для бизнеса. h3 Товары для продажи section.forsaleitems table tr th Item th Описание th Цена тыс. кол-во tr td Молоко td Хороший источник кальция. тд. цена 2 доллара за штуку / пол галлона. td.qty 3 tr td Яйца td Отлично подходит для завтрака и выпечки. т.д.цена 4 у.е. за единицу / доз. td.qty 6 tr td Цыпленок целиком td Идеально подходит для запекания. td.price $ 5 span.perunit / lb. td.qty 4 h3 Раздел о предстоящих мероприятиях .eventitem h4.title Cider Fest p.date 20 октября, 14:00&ndash; 18:00 p Отметьте сезон свежим сидром из наших садов. .eventitem h4.title Мастерская по выпечке хлеба дата 13 декабря, 9:00.&ndash; noon p Узнайте, как создавать и выращивать закваску. h3 Сообщение дня раздел .motditem p Ешьте лучше. Поддержите местную ферму. h3 # partners.wide Раздел наших друзей # partners.wide .partnerlink.wide a (href ="") .clickable-area Green Valley Greens .partnerlink.wide a (href ="") .clickable-area Turkey Hill Farm .partnerlink.wide a (href ="/") .clickable-area Кленовый сироп Берта .partnerlink.wide a (href ="") .clickable-area Только органические семена .bodyspace

myapp / routes / index.js

Файл index.js содержит логику для маршрута /.

var express = require (‘экспресс’); var router = express.Router (); router.get (‘/’, функция (req, res, next) {res.render (‘index’, {pagetitle: ‘Наша ферма’});}); module.exports = маршрутизатор;

myapp / общедоступные / javascripts / menu.js

Файл menu.js содержит JavaScript из примера Grid и Flexbox. Он реализует функцию переключения меню.

функция menuToggle (состояние) {var ele = document.getElementById (‘меню’); переключатель (состояние) {case ‘show’: ele.style.opacity = 1; ele.style.color = ‘rgb (96, 96, 96)’; ele.style.visibility = ‘видимый’; ele.style.transition = ‘видимость 0 с, непрозрачность 0,3 с’; перемена; case ‘hide’: ele.style.opacity = 0; ele.style.color = ‘черный’; ele.style.visibility = ‘скрытый’; ele.style.transition = ‘видимость 0,3 с, непрозрачность 0,3 с’; перемена; }}

myapp / общедоступные / таблицы стилей / style.css

Файл style.css содержит CSS из примера Grid и Flexbox.

/ * стили элементов * / * {margin: 0; / * по умолчанию все элементы (селектор *) не имеют поля * /} html {width: 100%; / * 100% ширина родительского (корневого) элемента * / height: 100vh; / * 100% высота области просмотра * / background: rgb (0, 0, 0, 0.1); / * 10% черный * / font-size: 1.0em; / * размер нашего корневого шрифта * / font-family: Arial, Helvetica, sans-serif; / * шрифт по умолчанию * /} body {min-height: 100%; } section {padding: 0.5rem; flex-grow: 1; / * во флекс-боксе разделы расширяются по оси флекс * /} h1 {/ * Название веб-сайта в заголовке * / font-size: 2.0rem; шрифт: нормальный; } h2 {/ * О программе, Контакты * / font-size: 1.25rem; } h3 {/ * Заголовки разделов * / font-size: 1.2rem; набивка: 0,5 бэр; } h4 {/ * Название элемента раздела * / font-weight: normal; набивка: 0,5 бэр; } p {/ * тело элемента раздела * / padding: 0.5rem; } a: link, a: посещенные {/ * якорные ссылки и посещенные якорные ссылки * / color: black; текстовое оформление: нет; / * отключение подчеркивания * /} a: hover {/ * при наведении курсора на привязку * / color: rgb (25, 25, 25); } a: active {/ * при щелчке по ссылке привязки * / color: rgb (96, 96, 96); } / * стили компонентов * / #container {display: grid; высота: 100vh; столбцы-шаблон-сетки: [слева] 10rem auto 10rem [справа]; сетка-шаблон-строки: [вверху] 5rem auto 5rem [внизу]; / * высота заголовка соответствует его содержимому * / grid-template-sizes: "голова голова голова" "левый основной корпус правый" "нога нога нога"; } #header {grid-area: head; / * соответствует имени в шаблоне * / background: rgb (0, 0, 0, 0.2); / * 20% черный * / display: flex; flex-direction: ряд; justify-content: пробел между; align-items: baseline; / * имя сайта и текст навигационного элемента выравниваются по базовой линии * / padding: 1.0rem; } #panel {/ * для элемента id ="панель" * / display: flex; / * этот элемент является родительским элементом flexbox * / flex-direction: column; / * его дочерние элементы изгибаются вертикально * / padding: 0.5rem; фон: rgb (0, 0, 0, 0.1); / * 10% черный * /} # panel.left {/ * для элемента id ="панель" и class ="оставили" * / grid-area: panleft; / * этот элемент заполняет область сетки * /} # panel.right {grid-area: panright; } #footer {grid-area: foot; дисплей: гибкий; / * этот элемент является родительским элементом flexbox * / flex-direction: column; / * его дочерние элементы изгибаются по вертикали * / justify-content: center; / * содержимое нижнего колонтитула по центру * / align-items: center; / * содержимое нижнего колонтитула по вертикали * / padding: 0.5rem; фон: rgb (0, 0, 0, 0.2); } #mainbody {/ * для элемента id ="основная часть" * / display: flex; / * этот элемент является родительским элементом flexbox * / flex-direction: column; / * его дочерние элементы изгибаются вертикально * / grid-area: mainbody; оправдать себя: центр; / * основное тело фиксированной ширины всегда центрируется * / width: 100%; минимальная ширина: 22,5 бэр; / * ширина основной части не может идти < 22.5rem * /} div # panel, div # mainbody {/ * дополнительное пространство под заголовком * / padding-top: 0.5rem; } #partners, #sections {/ * для элемента id ="партнеры" или id ="разделы" * / display: flex; / * этот элемент является родительским элементом flexbox * / flex-direction: row; / * его дочерние элементы сгибаются по горизонтали * / flex-wrap: wrap; / * его дочерние элементы могут переноситься на следующую строку * / align-content: flex-start; / * дочерние элементы начинаются в верхнем левом углу * /} # partners.wide {/ * для элемента id ="партнеры" и class ="широкий" * / display: none; / * по умолчанию не отображать этот элемент * /} #menu {position: absolute; / * позиция меню не зависит от других элементов * / right: 0; / * ноль пикселей от правой границы * / background: rgb (239, 239, 239); граница: 0,15 бэр, сплошной RGB (0, 0, 0, 0,4); видимость: скрыта; / * свойство видимости поддерживает переходы * / opacity: 0; / * непрозрачность + переход видимости = эффект исчезновения меню * / z-index: 1; / * убедитесь, что меню отображается поверх всего остального содержимого * /} #menuitems {/ * меню реализовано как контейнер flexbox * / display: flex; flex-direction: столбец; набивка: 1 бэр; } #menuitems h3 {border-top: 0.15rem твердый rgb (0, 0, 0, 0.1); / * светлая горизонтальная линейка * /} #menuitems .sectrule {border-color: rgb (0, 0, 0, 0.25); / * более темная горизонтальная линия * /} #menuitems .menuhead {border-top: none; } #menuitems h3: hover {background-color: rgb (0, 0, 0, 0.1); / * серый цвет элементов меню при наведении курсора * /} .menubutton {text-align: right; курсор: указатель; / * указывает, что по нему можно щелкнуть как по ссылке * / user-select: none; / * пользователь не может выбрать кнопку как текст * /} #menuitems .alignright {text-align: right; / * текст пункта меню с выравниванием по правому краю (не используется) * /} #header h1.menubutton {display: none; / * в виде по умолчанию (альбомный), скрыть кнопку меню * / border: 0.15rem solid rgb (0, 0, 0, 0); / * (невидимая) прокладка выравнивания * /} #header .placeholder {/ * эта невидимая кнопка отображается, когда меню * / color: rgb (0, 0, 0, 0); / * кнопка скрыта, поэтому высота заголовка совпадает. * / user-select: нет; / * пользователь не может выделить текст невидимой кнопки * /} .sectionlink, .partnerlink {border-radius: 0.25rem; / * придаем этому элементу слегка закругленный край * / font-weight: normal; размер шрифта: 1.1rem; набивка: 0,5 бэр; ширина: 7бэр; / * фиксированная ширина для этих элементов * / margin-bottom: 1rem; / * небольшой запас для удобочитаемости * / background: rgb (0, 0, 0, 0.1); } .sectionlink: hover, .partnerlink: hover {background-color: rgb (0, 0, 0, 0,065); / * яркость изображения при наведении курсора мыши * /} .partnerlink {height: 7rem; / * элементы-партнеры имеют дополнительно фиксированную высоту * /} .partnerlink.wide {margin: 0.5rem 1rem 0.5rem 0; / * поля для интервала, если они оборачиваются * /} .clickable-area {/ * использовать всякий раз, когда интерактивная область исключает поля * / height: 100%; / * интерактивная область охватывает высоту родительского элемента * /} .eventitem, .announceitem, .motditem {margin-bottom: 0.5rem; / * небольшой запас для удобочитаемости * /} .title {/ * например., "Открыт для бизнеса" * / font-style: курсив; шрифт: нормальный; размер шрифта: 1.1rem; } .date, .ingredient {/ * например, 1 января 2021 г. * / font-style: italic; размер шрифта: 0,9 бэр; заполнение: 0 0 0,01 бэр 0,5 бэр; цвет: rgb (0, 0, 0, 0,5); } .navitem {/ * О нас, Контакты * / font-weight: normal; набивка: 0 0,5 бэр 0 1 бэр; } .headspace, .panspace, .footspace, .bodyspace {flex-grow: 1; / * эти элементы расширяются по оси гибкости, чтобы заполнить пространство * /} / * стили таблицы ("вещи на продажу") * / table {граница-коллапс: коллапс; / * ячейки таблицы, смежные с пикселями * / width: 100%; нижнее поле: 1 бэр; } й {выравнивание текста: слева; } tr {маржа: 4rem 0 0 0; нижняя граница: 0,15 бэр, сплошной RGB (0, 0, 0, 0,2); / * горизонтальная линейка * /} td, th {padding: 0.5rem; вертикальное выравнивание: сверху; } td.price {белое пространство: nowrap; / * пробел в цене не переносит строку * /} td.qty, th.qty {text-align: center; } span.perunit {непрозрачность: 0,5; } / * адаптивные стили, применяемые в портретном режиме * / @media screen и (max-width: 45rem) {/ *, если ширина области просмотра < 45rem * / # panel.left {конец столбца сетки: слева; / * область сетки панели уменьшается до нуля * /} # panel.right {grid-column-start: right; / * область сетки панели уменьшается до нуля * /} # partners.tall {display: none; / * скрыть партнеров в панели (перезаписывает display: flex) * /} # partners.wide {display: flex; / * показать партнеров в теле (перезаписывает display: none) * /} #panel, / * они исчезают из макета * / #header .placeholder, .navitem {display: none; } #mainbody {начало столбца сетки: слева; / * mainbody теперь начинается с левого края * / grid-column-end: right; / * mainbody теперь заканчивается на правом краю * /} #header h1.menubutton {/ * отображать кнопку меню заголовка * / display: inline; / * заменяет отображение: нет * /}}

Вторичные маршруты

Следующие файлы содержат логику для вторичных маршрутов. — О нас, Консультации, Контакты, так далее.

myapp / маршруты / about.js

var express = require (‘экспресс’); var router = express.Router (); router.get (‘/’, функция (req, res, next) {res.render (‘about’, {pagetitle: ‘О нас’});}); module.exports = маршрутизатор;

myapp / routes / advice.js

var express = require (‘экспресс’); var router = express.Router (); router.get (‘/’, функция (req, res, next) {res.render (‘advice’, {pagetitle: ‘Homesteading Advice’});}); module.exports = маршрутизатор;

myapp / маршруты / contact.js

var express = require (‘экспресс’); var router = express.Router (); router.get (‘/’, функция (req, res, next) {res.render (‘contact’, {pagetitle: ‘Свяжитесь с нами’});}); module.exports = маршрутизатор;

myapp / маршруты / recipes.js

var express = require (‘экспресс’); var router = express.Router (); router.get (‘/’, функция (req, res, next) {res.render (‘recipes’, {pagetitle: ‘Recipes’});}); module.exports = маршрутизатор;

myapp / routes / tips.js

var express = require (‘экспресс’); var router = express.Router (); router.get (‘/’, функция (req, res, next) {res.render (‘советы’, {pagetitle: ‘Полезные советы’});}); module.exports = маршрутизатор;

Вторичные просмотры

Следующие представления наследуют layout.pug.

myapp / просмотров / about.pug

расширяет блок макета mainbody #mainbody section # mainbodyitems p Алиса &amp; Боб работает на своей ферме с 1992 года..

myapp / views / advice.pug

extends layout block mainbody #mainbody section # mainbodyitems h3 Совет по усадьбе p Никогда, никогда не стойте за телкой.

myapp / просмотров / contact.pug

расширяет блок макета mainbody #mainbody section # mainbodyitems h3 Alice &amp; Bob p 1344 Chattanooga Way p Homestead, VT 05401 p (802) 555-5555

myapp / просмотров / recipes.pug

extends layout block mainbody #mainbody section # mainbodyitems h3 Рецепты Алисы pb Без замеса на следующий день голландский хлеб в духовке, ингредиент 1/4 чайной ложки активных сухих дрожжей ингредиент 3 чашки универсальной муки на ингредиент 1 1/2 чайной ложки соли p.ingredient Кукурузная мука или пшеничные отруби для присыпки p В большой миске растворите дрожжи в воде. p Добавьте муку и соль, помешивая, пока не получится однородная смесь. p Закройте чашу. Дать отдохнуть не менее 8 часов, лучше от 12 до 18, при комнатной температуре около 70 градусов. p Когда поверхность теста покрывается пузырями, оно готово к складыванию. Слегка посыпьте мукой рабочую поверхность. Присыпать тесто мукой и один или два раза переложить на него. Неплотно накройте и дайте постоять около 15 минут. p Используя столько муки, чтобы тесто не прилипало, аккуратно сформируйте из него шар. Обильно смазать чистое кухонное полотенце мукой, пшеничными отрубями или кукурузной мукой. Выложите на полотенце шовную сторону теста. Накройте другим полотенцем и дайте подняться на 1-2 часа. p Нагрейте духовку до 475&град ;. Накрыть крышкой и запекать 30 минут..

myapp / views / tips.pug

extends layout block mainbody #mainbody section # mainbodyitems h3 Советы Алисы p Всегда вставайте до восхода солнца. p Никогда не используйте поддельный кленовый сироп. p Если медведь черный, будь громким, нападай. p Если медведь коричневый, прикидывайся мертвым, ложись.

Внешность

В портретном режиме доступ к второстепенным маршрутам осуществляется в меню..

Вид Portait

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

Панорамный вид