HTML Diff
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) =&gt; { res.locals.year = new Date().getFullYear() next() }) // Home app.get('/', (req, res) =&gt; { Cosmic.getObjects({ bucket: { slug: bucket_slug, read_key: read_key } }, (err, response) =&gt; { const cosmic = response if (cosmic.objects.type.posts) { cosmic.objects.type.posts.forEach(post =&gt; { 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'), () =&gt; { console.info('==&gt; &lt;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"&gt; 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) =&gt; { res.locals.year = new Date().getFullYear() next() }) // Home app.get('/', (req, res) =&gt; { Cosmic.getObjects({ bucket: { slug: bucket_slug, read_key: read_key } }, (err, response) =&gt; { const cosmic = response if (cosmic.objects.type.posts) { cosmic.objects.type.posts.forEach(post =&gt; { 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'), () =&gt; { console.info('==&gt; &lt;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"&gt; 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 {{&gt; header }} &lt;main class="container"&gt; {{# cosmic.objects.type.posts }} &lt;div class="card" data-href="/{{ slug }}"&gt; {{# metadata.hero.imgix_url }} &lt;div class="blog-post-hero blog-post-hero--short" style="background-image: url({{ metadata.hero.imgix_url }})"&gt;&lt;/div&gt; {{/ metadata.hero.imgix_url }} &lt;div class="card-padding"&gt; &lt;h2 class="blog__title blog__title--small"&gt; &lt;a href="/{{ slug }}"&gt;{{ title }}&lt;/a&gt; &lt;/h2&gt; &lt;div class="blog__author"&gt; &lt;div class="blog__author-image" style="background-image: url({{ metadata.author.metadata.image.imgix_url }}?w=100)"&gt;&lt;/div&gt; &lt;div class="blog__author-title"&gt;by &lt;a href="/author/{{ metadata.author.slug }}"&gt;{{ metadata.author.title }}&lt;/a&gt; on {{ friendly_date }}&lt;/div&gt; &lt;div class="clearfix"&gt;&lt;/div&gt; &lt;/div&gt; &lt;div class="blog__teaser droid"&gt;{{{ metadata.teaser }}}&lt;/div&gt; &lt;div class="blog__read-more"&gt; &lt;a href="/{{ slug }}"&gt;Read more...&lt;/a&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; {{/ cosmic.objects.type.posts }} &lt;/main&gt; {{&gt; footer }}<p>В результате у нас: 1. Формируется header (заголовок) с переменными Mustache. 2. Происходит извлечение данных Cosmic посредством переменной Mustache {{cosmic}}, имеющей всё нужное для компоновки динамических данных страницы. 3. Осуществляется проход по {{}}cosmic.objects.type.posts и вывод постов в нашем блоге.</p>
16 {{&gt; header }} &lt;main class="container"&gt; {{# cosmic.objects.type.posts }} &lt;div class="card" data-href="/{{ slug }}"&gt; {{# metadata.hero.imgix_url }} &lt;div class="blog-post-hero blog-post-hero--short" style="background-image: url({{ metadata.hero.imgix_url }})"&gt;&lt;/div&gt; {{/ metadata.hero.imgix_url }} &lt;div class="card-padding"&gt; &lt;h2 class="blog__title blog__title--small"&gt; &lt;a href="/{{ slug }}"&gt;{{ title }}&lt;/a&gt; &lt;/h2&gt; &lt;div class="blog__author"&gt; &lt;div class="blog__author-image" style="background-image: url({{ metadata.author.metadata.image.imgix_url }}?w=100)"&gt;&lt;/div&gt; &lt;div class="blog__author-title"&gt;by &lt;a href="/author/{{ metadata.author.slug }}"&gt;{{ metadata.author.title }}&lt;/a&gt; on {{ friendly_date }}&lt;/div&gt; &lt;div class="clearfix"&gt;&lt;/div&gt; &lt;/div&gt; &lt;div class="blog__teaser droid"&gt;{{{ metadata.teaser }}}&lt;/div&gt; &lt;div class="blog__read-more"&gt; &lt;a href="/{{ slug }}"&gt;Read more...&lt;/a&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; {{/ cosmic.objects.type.posts }} &lt;/main&gt; {{&gt; 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