0 added
0 removed
Original
2026-01-01
Modified
2026-03-10
1
<p>Сложно ли создать простейший блог, используя Node.js и Cosmic JS? На самом деле, нет. Что же, давайте попробуем!</p>
1
<p>Сложно ли создать простейший блог, используя Node.js и Cosmic JS? На самом деле, нет. Что же, давайте попробуем!</p>
2
<h2>Подготовка</h2>
2
<h2>Подготовка</h2>
3
<p>Для начала нужно убедиться, что платформа для разработки Node.js у вас установлена. Если это не так, следует перейти на официальный<a>сайт Node.js</a>, где можно скачать последнюю версию.</p>
3
<p>Для начала нужно убедиться, что платформа для разработки Node.js у вас установлена. Если это не так, следует перейти на официальный<a>сайт Node.js</a>, где можно скачать последнюю версию.</p>
4
<p>Следующий шаг - установка пакетного менеджера Yarn - он нужен для установки зависимостей нашего будущего блога:</p>
4
<p>Следующий шаг - установка пакетного менеджера Yarn - он нужен для установки зависимостей нашего будущего блога:</p>
5
<p>Далее давайте создадим папку для блога. Для этого нужно выполнить в терминале парочку команд:</p>
5
<p>Далее давайте создадим папку для блога. Для этого нужно выполнить в терминале парочку команд:</p>
6
mkdir simple-blog cd simple-blog<p>Следующий этап - создание файла<strong>package.json</strong>- он нужен для импорта зависимости для блога. В файл нужно добавить следующие строки:</p>
6
mkdir simple-blog cd simple-blog<p>Следующий этап - создание файла<strong>package.json</strong>- он нужен для импорта зависимости для блога. В файл нужно добавить следующие строки:</p>
7
{ "dependencies": { "cosmicjs": "^2.39.0", "express": "^4.15.2", "hogan-express": "^0.5.2", "nodemon": "^1.11.0" }, "scripts": { "start": "node app.js", "development": "nodemon app.js" } }<p>Мы объявили в файле зависимости, необходимые для разработки и запуска нашего блога, а именно: 1. Модуль Cosmic JS Node для получения данных с Cosmic JS Bucket. 2. Веб-фреймворк Express. 3. Пакет Hogan (нужен для обработки шаблонов). 4. Модуль Nodemon, обеспечивающий удобств разработки - автоматически перезагружает приложение, если в нём произошли изменения.</p>
7
{ "dependencies": { "cosmicjs": "^2.39.0", "express": "^4.15.2", "hogan-express": "^0.5.2", "nodemon": "^1.11.0" }, "scripts": { "start": "node app.js", "development": "nodemon app.js" } }<p>Мы объявили в файле зависимости, необходимые для разработки и запуска нашего блога, а именно: 1. Модуль Cosmic JS Node для получения данных с Cosmic JS Bucket. 2. Веб-фреймворк Express. 3. Пакет Hogan (нужен для обработки шаблонов). 4. Модуль Nodemon, обеспечивающий удобств разработки - автоматически перезагружает приложение, если в нём произошли изменения.</p>
8
<p>Чтобы установить зависимости, выполняем:</p>
8
<p>Чтобы установить зависимости, выполняем:</p>
9
<h2>Разработка</h2>
9
<h2>Разработка</h2>
10
<p>Теперь сформируем главную страницу блога. Для этого создадим app.js и добавим в него:</p>
10
<p>Теперь сформируем главную страницу блога. Для этого создадим app.js и добавим в него:</p>
11
const express = require('express') const app = express() const hogan = require('hogan-express') const http_module = require('http') const http = http_module.Server(app) app.engine('html', hogan) app.set('port', (process.env.PORT || 3000)) app.use('/', express.static(__dirname + '/public/')) const Cosmic = require('cosmicjs') const helpers = require('./helpers') const bucket_slug = process.env.COSMIC_BUCKET || 'simple-blog-website' const read_key = process.env.COSMIC_READ_KEY const partials = { header: 'partials/header', footer: 'partials/footer' } app.use('/', (req, res, next) => { res.locals.year = new Date().getFullYear() next() }) // Home app.get('/', (req, res) => { Cosmic.getObjects({ bucket: { slug: bucket_slug, read_key: read_key } }, (err, response) => { const cosmic = response if (cosmic.objects.type.posts) { cosmic.objects.type.posts.forEach(post => { const friendly_date = helpers.friendlyDate(new Date(post.created_at)) post.friendly_date = friendly_date.month + ' ' + friendly_date.date }) } else { cosmic.no_posts = true } res.locals.cosmic = cosmic res.render('index.html', { partials }) }) }) http.listen(app.get('port'), () => { console.info('==> <img draggable="false" data-mce-resize="false" data-mce-placeholder="1" data-wp-emoji="1" class="emoji" alt="?" src="https://s.w.org/images/core/emoji/2.3/svg/1f30e.svg"> Go to http://localhost:%s', app.get('port')); })<p>Что тут происходит: 1. Выполняется импорт модулей Express, Cosmic JS и прочих. 2. Присоединяются нижний и верхний колонтитулы. 3. При запросе ("/") осуществляется вызов Cosmic JS Bucket для вывода постов, плюс возвращается шаблон index.html. 4. Происходит добавление данных на страницу в виде глобального хранилища - cosmic. Такая структура делает реализацию шаблона интуитивной.</p>
11
const express = require('express') const app = express() const hogan = require('hogan-express') const http_module = require('http') const http = http_module.Server(app) app.engine('html', hogan) app.set('port', (process.env.PORT || 3000)) app.use('/', express.static(__dirname + '/public/')) const Cosmic = require('cosmicjs') const helpers = require('./helpers') const bucket_slug = process.env.COSMIC_BUCKET || 'simple-blog-website' const read_key = process.env.COSMIC_READ_KEY const partials = { header: 'partials/header', footer: 'partials/footer' } app.use('/', (req, res, next) => { res.locals.year = new Date().getFullYear() next() }) // Home app.get('/', (req, res) => { Cosmic.getObjects({ bucket: { slug: bucket_slug, read_key: read_key } }, (err, response) => { const cosmic = response if (cosmic.objects.type.posts) { cosmic.objects.type.posts.forEach(post => { const friendly_date = helpers.friendlyDate(new Date(post.created_at)) post.friendly_date = friendly_date.month + ' ' + friendly_date.date }) } else { cosmic.no_posts = true } res.locals.cosmic = cosmic res.render('index.html', { partials }) }) }) http.listen(app.get('port'), () => { console.info('==> <img draggable="false" data-mce-resize="false" data-mce-placeholder="1" data-wp-emoji="1" class="emoji" alt="?" src="https://s.w.org/images/core/emoji/2.3/svg/1f30e.svg"> Go to http://localhost:%s', app.get('port')); })<p>Что тут происходит: 1. Выполняется импорт модулей Express, Cosmic JS и прочих. 2. Присоединяются нижний и верхний колонтитулы. 3. При запросе ("/") осуществляется вызов Cosmic JS Bucket для вывода постов, плюс возвращается шаблон index.html. 4. Происходит добавление данных на страницу в виде глобального хранилища - cosmic. Такая структура делает реализацию шаблона интуитивной.</p>
12
<h2>Добавляем переменные шаблона домашней страницы</h2>
12
<h2>Добавляем переменные шаблона домашней страницы</h2>
13
<p>Следующая часть нашего процесса разработки блога является самой интересной, ведь именно здесь<strong>мы видим всю мощь Cosmic JS</strong>, которая очень эффектно сочетается с системой шаблонов<strong>Mustache</strong>.</p>
13
<p>Следующая часть нашего процесса разработки блога является самой интересной, ведь именно здесь<strong>мы видим всю мощь Cosmic JS</strong>, которая очень эффектно сочетается с системой шаблонов<strong>Mustache</strong>.</p>
14
<p>Итак, создаём папку views:</p>
14
<p>Итак, создаём папку views:</p>
15
<p>Теперь в данной папке создадим файл index.html и добавим в файл следующее:</p>
15
<p>Теперь в данной папке создадим файл index.html и добавим в файл следующее:</p>
16
{{> header }} <main class="container"> {{# cosmic.objects.type.posts }} <div class="card" data-href="/{{ slug }}"> {{# metadata.hero.imgix_url }} <div class="blog-post-hero blog-post-hero--short" style="background-image: url({{ metadata.hero.imgix_url }})"></div> {{/ metadata.hero.imgix_url }} <div class="card-padding"> <h2 class="blog__title blog__title--small"> <a href="/{{ slug }}">{{ title }}</a> </h2> <div class="blog__author"> <div class="blog__author-image" style="background-image: url({{ metadata.author.metadata.image.imgix_url }}?w=100)"></div> <div class="blog__author-title">by <a href="/author/{{ metadata.author.slug }}">{{ metadata.author.title }}</a> on {{ friendly_date }}</div> <div class="clearfix"></div> </div> <div class="blog__teaser droid">{{{ metadata.teaser }}}</div> <div class="blog__read-more"> <a href="/{{ slug }}">Read more...</a> </div> </div> </div> {{/ cosmic.objects.type.posts }} </main> {{> footer }}<p>В результате у нас: 1. Формируется header (заголовок) с переменными Mustache. 2. Происходит извлечение данных Cosmic посредством переменной Mustache {{cosmic}}, имеющей всё нужное для компоновки динамических данных страницы. 3. Осуществляется проход по {{}}cosmic.objects.type.posts и вывод постов в нашем блоге.</p>
16
{{> header }} <main class="container"> {{# cosmic.objects.type.posts }} <div class="card" data-href="/{{ slug }}"> {{# metadata.hero.imgix_url }} <div class="blog-post-hero blog-post-hero--short" style="background-image: url({{ metadata.hero.imgix_url }})"></div> {{/ metadata.hero.imgix_url }} <div class="card-padding"> <h2 class="blog__title blog__title--small"> <a href="/{{ slug }}">{{ title }}</a> </h2> <div class="blog__author"> <div class="blog__author-image" style="background-image: url({{ metadata.author.metadata.image.imgix_url }}?w=100)"></div> <div class="blog__author-title">by <a href="/author/{{ metadata.author.slug }}">{{ metadata.author.title }}</a> on {{ friendly_date }}</div> <div class="clearfix"></div> </div> <div class="blog__teaser droid">{{{ metadata.teaser }}}</div> <div class="blog__read-more"> <a href="/{{ slug }}">Read more...</a> </div> </div> </div> {{/ cosmic.objects.type.posts }} </main> {{> footer }}<p>В результате у нас: 1. Формируется header (заголовок) с переменными Mustache. 2. Происходит извлечение данных Cosmic посредством переменной Mustache {{cosmic}}, имеющей всё нужное для компоновки динамических данных страницы. 3. Осуществляется проход по {{}}cosmic.objects.type.posts и вывод постов в нашем блоге.</p>
17
<p>Что хорошо в таком подходе? Хотя бы то, что у нас логика шаблона отделена от остального кода, кроме некоторых циклов и запросов. Таким образом, код шаблона изолируется от кода основного приложения.</p>
17
<p>Что хорошо в таком подходе? Хотя бы то, что у нас логика шаблона отделена от остального кода, кроме некоторых циклов и запросов. Таким образом, код шаблона изолируется от кода основного приложения.</p>
18
<h2>Послесловие</h2>
18
<h2>Послесловие</h2>
19
<p>Всё вышеперечисленное - сокращённая версия блога, которая доступна для загрузки<a>здесь</a>. Что касается полной версии блога, то она включает в себя и страницу со всеми постами, и страницу с постами каждого из авторов. Впрочем, вам никто не мешает изучить<a>полную версию кода на GitHub</a>, а потом развернуть блог путём нескольких кликов на панели Cosmic JS и установить блог в Cosmic JS Bucket.</p>
19
<p>Всё вышеперечисленное - сокращённая версия блога, которая доступна для загрузки<a>здесь</a>. Что касается полной версии блога, то она включает в себя и страницу со всеми постами, и страницу с постами каждого из авторов. Впрочем, вам никто не мешает изучить<a>полную версию кода на GitHub</a>, а потом развернуть блог путём нескольких кликов на панели Cosmic JS и установить блог в Cosmic JS Bucket.</p>
20
<p><em>Источник -<a>"How to Build a Simple Blog Using Node.js"</a>.</em></p>
20
<p><em>Источник -<a>"How to Build a Simple Blog Using Node.js"</a>.</em></p>
21
21