diff --git a/.eleventy.js b/.eleventy.js
index 18ca7b03..9be8cc4e 100644
--- a/.eleventy.js
+++ b/.eleventy.js
@@ -131,8 +131,10 @@ module.exports = function (config) {
const currentMonth = months.indexOf(date[1])
const titledLink = stringParts[1].split('](')
post['date'] = new Date(Date.parse(`${currentYear}-${currentMonth + 1}-${currentDay}`)).toISOString()
+ post['shortDate'] = `${date[0]} ${date[1]}`
post['title'] = titledLink[0].replace(/^\[/, '')
post['url'] = titledLink[1].replace(/\/[^/]+$/, '/')
+ post['authors'] = stringParts[1].split('), ')[1].split(', ')
const rawArticle = collectionApi.getFilteredByGlob(
`src${post['url'].replace('https://doka.guide', '')}*.md`,
)[0]
diff --git a/src/includes/blocks/changelog.njk b/src/includes/blocks/changelog.njk
new file mode 100644
index 00000000..e5f0da3f
--- /dev/null
+++ b/src/includes/blocks/changelog.njk
@@ -0,0 +1,23 @@
+
+
Новые статьи
+
+
+ {% for item in changeLog %}
+ -
+
+
+ {% endfor %}
+
+
+
diff --git a/src/styles/blocks/changelog.css b/src/styles/blocks/changelog.css
new file mode 100644
index 00000000..52c9ef90
--- /dev/null
+++ b/src/styles/blocks/changelog.css
@@ -0,0 +1,172 @@
+.changelog {
+ padding-block-end: clamp(40px, 4.8%, 80px);
+}
+
+.changelog-list {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+ line-height: 1.3;
+}
+
+.changelog-list__item:not(:last-child) {
+ margin-block-end: 24px;
+}
+
+.changelog-item {
+ display: flex;
+ justify-content: space-between;
+ align-items: baseline;
+}
+
+.changelog-item__time,
+.changelog-item__author {
+ display: flex;
+ align-items: baseline;
+ font-size: 28px;
+}
+
+.changelog-item__time::after,
+.changelog-item__author::before {
+ content: '';
+ flex: 1 1 auto;
+ border-block-end: 5px dotted var(--color-text);
+ opacity: 0.3;
+ margin-inline: 20px;
+}
+
+.changelog-item__time {
+ flex-shrink: 0;
+ inline-size: calc(100% / 3);
+ font-family: var(--font-family);
+}
+
+.changelog-item__title {
+ margin: 0;
+ font-weight: normal;
+ font-size: 24px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.changelog-item__author {
+ flex-wrap: wrap;
+ flex: 1 0 25%;
+ justify-content: end;
+}
+
+.changelog-item__author-link {
+ font-family: var(--font-family);
+}
+
+.changelog-item__author-link:not(:first-child) {
+ margin-inline-start: 1ch;
+}
+
+.changelog-footer {
+ display: flex;
+ justify-content: space-between;
+ margin-block-start: 45px;
+}
+
+.changelog-footer::before {
+ content: "";
+ flex-basis: calc(100% / 3);
+}
+
+.changelog-footer__item {
+ margin: 0;
+}
+
+.changelog-footer__item:last-child {
+ flex-grow: 1;
+ text-align: end;
+}
+
+@media (width <= 1200px) {
+ .changelog-item {
+ flex-wrap: wrap;
+ }
+
+ .changelog-item__time {
+ inline-size: 100%;
+ justify-content: end;
+ }
+
+ .changelog-item__time::after {
+ display: none;
+ }
+
+ .changelog-item__title {
+ max-inline-size: 55%;
+ font-size: 18px;
+ }
+
+ .changelog-item__author::before {
+ border-block-end-width: 3px;
+ }
+
+ .changelog-item__time,
+ .changelog-item__author {
+ font-size: 22px;
+ }
+
+ .changelog-footer {
+ flex-direction: column;
+ font-size: 18px;
+ }
+
+ .changelog-footer::before {
+ display: none;
+ }
+
+ .changelog-footer__item:last-child {
+ text-align: start;
+ }
+}
+
+@media (width <= 768px) {
+ .changelog-item {
+ flex-direction: column;
+ justify-content: start;
+ }
+
+ .changelog-item__time {
+ inline-size: fit-content;
+ justify-content: start;
+ text-indent: -9999px;
+ line-height: 0;
+ }
+
+ .changelog-item__time::before {
+ content: attr(data-mobile);
+ display: block;
+ text-indent: 0;
+ line-height: initial;
+ }
+
+ .changelog-item__title {
+ max-inline-size: 90dvw;
+ font-size: 20px;
+ }
+
+ .changelog-item__author {
+ flex: 0 0 auto;
+ justify-content: start;
+ }
+
+ .changelog-item__author::before {
+ display: none;
+ }
+
+ .changelog-item__time,
+ .changelog-item__author {
+ font-size: 20px;
+ }
+
+ .changelog-footer {
+ margin-block-start: 30px;
+ font-size: 17px;
+ }
+}
diff --git a/src/styles/index.css b/src/styles/index.css
index b633d054..10d0dd90 100644
--- a/src/styles/index.css
+++ b/src/styles/index.css
@@ -88,3 +88,4 @@
@import url("blocks/subscribe-popup.css");
@import url("blocks/subscribe-page.css");
@import url("blocks/baseline.css");
+@import url("blocks/changelog.css");
diff --git a/src/views/index.11tydata.js b/src/views/index.11tydata.js
index 36caf997..ff331c2c 100644
--- a/src/views/index.11tydata.js
+++ b/src/views/index.11tydata.js
@@ -38,6 +38,32 @@ module.exports = {
documentDescription: 'Документация для разработчиков на понятном языке',
eleventyComputed: {
+ changeLog: async function (data) {
+ const { collections } = data
+ const { posts, peopleById } = collections
+ const peopleIds = Object.keys(peopleById)
+
+ return posts
+ ? posts
+ .filter((p) => typeof p !== 'string')
+ .slice(0, 5)
+ .map((p) => {
+ p['title'] = p['title'].replace(/^`/, '').replace(/`$/, '
')
+ p['authors'] = p['authors'].map((a) => {
+ return {
+ name: a,
+ url: `/people/${peopleIds.filter((p) => peopleById[p].data.name === a)[0]}`,
+ }
+ })
+ const date = new Date(p['date'])
+ const day = String(date.getDate())
+ const month = String(date.getMonth() + 1)
+ p['mobileDate'] = `${day.length > 1 ? day : `0${month}`}.${month.length > 1 ? month : `0${month}`}`
+ return p
+ })
+ : []
+ },
+
promoData: async function (data) {
const { collections } = data
const { promos } = collections
diff --git a/src/views/index.njk b/src/views/index.njk
index 2460dacb..0de4a555 100644
--- a/src/views/index.njk
+++ b/src/views/index.njk
@@ -29,6 +29,8 @@
+ {% include "blocks/changelog.njk" %}
+
{% include "articles-gallery.njk" %}