diff --git a/blog/config.toml b/blog/config.toml index 2fe016b4..b2c39a38 100644 --- a/blog/config.toml +++ b/blog/config.toml @@ -6,6 +6,7 @@ highlight_code = true highlight_theme = "visual-studio-dark" generate_feed = true feed_filename = "rss.xml" +compile_sass = true languages = [ { code = "zh-CN" }, # Chinese (simplified) diff --git a/blog/content/edition-3/_index.md b/blog/content/edition-3/_index.md new file mode 100644 index 00000000..7622d5d7 --- /dev/null +++ b/blog/content/edition-3/_index.md @@ -0,0 +1,4 @@ ++++ +title = "Third Edition (Alpha)" +template = "edition-3/index.html" ++++ diff --git a/blog/content/edition-3/chapters/_index.md b/blog/content/edition-3/chapters/_index.md new file mode 100644 index 00000000..78f9f535 --- /dev/null +++ b/blog/content/edition-3/chapters/_index.md @@ -0,0 +1,7 @@ ++++ +title = "Posts" +sort_by = "weight" +insert_anchor_links = "left" +render = false +page_template = "edition-3/raw.html" ++++ diff --git a/blog/content/edition-3/chapters/bare-bones.md b/blog/content/edition-3/chapters/bare-bones.md new file mode 100644 index 00000000..2855836b --- /dev/null +++ b/blog/content/edition-3/chapters/bare-bones.md @@ -0,0 +1,6 @@ ++++ ++++ + +## Bare Bones + +In this first chapter, we explain how to create an operating system for the `x86_64` architecture step for step. Starting from scratch, we first create a minimal Rust executable that doesn't depend on the standard library. We then turn it into a bootable OS kernel by combining it with a bootloader. The resulting disk image can then be launched in the [QEMU](https://www.qemu.org/) emulator or booted on a real machine. diff --git a/blog/sass/css/edition-3/main.scss b/blog/sass/css/edition-3/main.scss new file mode 100644 index 00000000..caa2c0d0 --- /dev/null +++ b/blog/sass/css/edition-3/main.scss @@ -0,0 +1,941 @@ +/* + * ___ + * /\_ \ + * _____ ___ ___\//\ \ __ + * /\ '__`\ / __`\ / __`\\ \ \ /'__`\ + * \ \ \_\ \/\ \_\ \/\ \_\ \\_\ \_/\ __/ + * \ \ ,__/\ \____/\ \____//\____\ \____\ + * \ \ \/ \/___/ \/___/ \/____/\/____/ + * \ \_\ + * \/_/ + * + * Designed, built, and released under MIT license by @mdo. Learn more at + * https://github.com/poole/poole. + * + * + * Adjusted by @phil-opp. + */ + +/* + * Contents + * + * Body resets + * Custom type + * Messages + * Container + * Masthead + * Posts and pages + * Pagination + * Reverse layout + * Themes + */ + +/* + * Body resets + * + * Update the foundational and global aspects of the page. + */ + +* { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +html, body { + margin: 0; + padding: 0; +} + +html { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + line-height: 1.5; +} + +@mixin set-colors-light { + --background-color: #fff; + --text-color: #515151; + --heading-color: #313131; + --heading-code-color: #a0565c; + --link-color: #268bd2; + --hr-color-top: #eee; + --hr-color-bottom: #fff; + --code-text-color: #bf616a; + --code-background-color: #f9f9f9; + --masthead-title-color: #505050; + --strong-color: #303030; + --masthead-subtitle: #c0c0c0; + --background-color-section-bare-bones: #f4f4ff; + --border-color-section-bare-bones: #e0e0ff; + --post-title-color: #228; +} + +@mixin set-colors-dark { + --background-color: #121212; + --text-color: #f5f5f5; + --heading-color: #eee; + --heading-code-color: #eee; + --link-color: #c59ff3; + --hr-color-top: #333; + --hr-color-bottom: #000; + --code-text-color: #eeeeee; + --code-background-color: #222222; + --masthead-title-color: #a0a0a0; + --strong-color: #c0c0c0; + --masthead-subtitle: #6f6f6f; + --background-color-section-bare-bones: #005; + --background-color-section-bare-bones: #225; + --post-title-color: #c8c8ff; +} + + +body { + @include set-colors-light(); +} + +body.dark { + @include set-colors-dark(); +} + +/* Styles for users who prefer dark mode at the OS level */ + +@media (prefers-color-scheme: dark) { + /* defaults to dark theme */ + body { + @include set-colors-dark(); + } + /* Override dark mode with light mode styles if the user decides to swap */ + body.light { + @include set-colors-light(); + } +} + + +body { + color: var(--text-color); + background-color: var(--background-color); + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} + +/* No `:visited` state is required by default (browsers will use `a`) */ + +a { + color: var(--link-color); + text-decoration: none; +} + +/* `:focus` is linked to `:hover` for basic accessibility */ + +a:hover, a:focus { + text-decoration: underline; +} + +/* Headings */ + +h1, h2, h3, h4, h5, h6 { + margin-bottom: .5rem; + font-weight: bold; + line-height: 1.25; + color: var(--heading-color); + text-rendering: optimizeLegibility; +} + +h1 { + font-size: 2rem; +} + +h2 { + margin-top: 1rem; + font-size: 1.5rem; +} + +h3 { + margin-top: 1.5rem; + font-size: 1.25rem; +} + +h4, h5, h6 { + margin-top: 1rem; + font-size: 1rem; +} + +/* Body text */ + +p { + margin-top: 0; + margin-bottom: 1rem; +} + +strong { + color: var(--strong-color); +} + +/* Lists */ + +ul, ol, dl { + margin-top: 0; + margin-bottom: 1rem; +} + +/* Nested lists */ + +li ul, li ol, li dl { + margin-bottom: 0; +} + +li ul+p, li ol+p, li dl+p { + margin-top: 1rem; +} + +dt { + font-weight: bold; +} + +dd { + margin-bottom: .5rem; +} + +/* Misc */ + +hr { + position: relative; + margin: 1.5rem 0; + border: 0; + border-top: 1px solid var(--hr-color-top); + border-bottom: 1px solid var(--hr-color-bottom); +} + +abbr { + font-size: 85%; + font-weight: bold; + color: #555; + text-transform: uppercase; +} + +abbr[title] { + cursor: help; + border-bottom: 1px dotted #e5e5e5; +} + +/* Code */ + +code, pre { + font-family: Menlo, Monaco, Consolas, monospace; +} + +code { + padding: .25em .5em; + font-size: 85%; + color: var(--code-text-color); + background-color: var(--code-background-color); + border-radius: 3px; +} + +pre { + display: block; + margin-top: 0; + margin-bottom: 1rem; + padding: .5rem; + font-size: .85rem; + line-height: 1.4; + white-space: pre; + overflow: auto; + word-wrap: normal; + background-color: var(--code-background-color); +} + +pre code { + padding: 0; + font-size: 100%; + color: inherit; + background-color: transparent; +} + +.highlight { + margin-bottom: 1rem; + border-radius: 4px; +} + +.highlight pre { + margin-bottom: 0; +} + +/* Quotes */ + +blockquote { + padding: .5rem 1rem; + margin: .8rem 0; + color: #7a7a7a; + border-left: .25rem solid #e5e5e5; +} + +blockquote p:last-child { + margin-bottom: 0; +} + +@media (min-width: 30rem) { + blockquote { + padding-right: 5rem; + padding-left: 1.25rem; + } +} + +img { + display: block; + margin: 0 0 1rem; + border-radius: 5px; + max-width: 100%; + color: grey; + font-style: italic; +} + +/* Tables */ + +table { + margin-bottom: 1rem; + width: 100%; + border: 1px solid #e5e5e5; + border-collapse: collapse; +} + +td, th { + padding: .25rem .5rem; + border: 1px solid #e5e5e5; +} + +tbody tr:nth-child(odd) td, tbody tr:nth-child(odd) th { + background-color: var(--code-background-color); +} + +/* + * Custom type + * + * Extend paragraphs with `.lead` for larger introductory text. + */ + +.lead { + font-size: 1.25rem; + font-weight: 300; +} + +/* + * Messages + * + * Show alert messages to users. You may add it to single elements like a `

`, + * or to a parent if there are multiple elements to show. + */ + +.message { + margin-bottom: 1rem; + padding: 1rem; + color: #717171; + background-color: var(--code-background-color); +} + +/* + * Container + * + * Center the page content. + */ + +.container { + max-width: 45rem; + padding-left: 1rem; + padding-right: 1rem; + margin-left: auto; + margin-right: auto; +} + +/* + * Masthead + * + * Super small header above the content for site name and short description. + */ + +.masthead { + padding-top: 1rem; + padding-bottom: 1rem; + margin-bottom: 1rem; +} + +.masthead-title { + margin-top: 0; + margin-bottom: 0; + color: var(--masthead-title-color); +} + +.masthead-title a { + color: var(--masthead-title-color); +} + +.masthead small { + font-size: 75%; + font-weight: 400; + color: var(--masthead-subtitle); + letter-spacing: 0; +} + +/* + * Posts and pages + * + * Each post is wrapped in `.post` and is used on default and post layouts. Each + * page is wrapped in `.page` and is only used on the page layout. + */ + +.page { + margin-bottom: 4em; +} + +/* Blog post or page title */ + +.page-title, .post-title, .post-title a { + color: var(--post-title-color); +} + +.page-title, .post-title { + margin-top: 0; +} + +/* Meta data line below post title */ + +.post-date { + display: block; + margin-top: -.5rem; + margin-bottom: 1rem; + color: #9a9a9a; +} + +/* Related posts */ + +.related { + padding-top: 2rem; + padding-bottom: 2rem; + border-top: 1px solid #eee; +} + +.related-posts { + padding-left: 0; + list-style: none; +} + +.related-posts h3 { + margin-top: 0; +} + +.related-posts li small { + font-size: 75%; + color: #999; +} + +.related-posts li a:hover { + color: #268bd2; + text-decoration: none; +} + +.related-posts li a:hover small { + color: inherit; +} + +/* + * Pagination + * + * Super lightweight (HTML-wise) blog pagination. `span`s are provide for when + * there are no more previous or next posts to show. + */ + +.pagination { + overflow: hidden; + /* clearfix */ + margin-left: -1rem; + margin-right: -1rem; + font-family: "PT Sans", Helvetica, Arial, sans-serif; + color: #ccc; + text-align: center; +} + +/* Pagination items can be `span`s or `a`s */ + +.pagination-item { + display: block; + padding: 1rem; + border: 1px solid #eee; +} + +.pagination-item:first-child { + margin-bottom: -1px; +} + +/* Only provide a hover state for linked pagination items */ + +a.pagination-item:hover { + background-color: #f5f5f5; +} + +@media (min-width: 30rem) { + .pagination { + margin: 3rem 0; + } + .pagination-item { + float: left; + width: 50%; + } + .pagination-item:first-child { + margin-bottom: 0; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + } + .pagination-item:last-child { + margin-left: -1px; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + } +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + padding: 0; + color: var(--heading-code-color); + font-size: 95%; + background-color: inherit; +} + +.masthead-title { + font-size: 1.25rem; + display: inline; +} + +.masthead p { + font-size: 1.25rem; + display: inline; + margin: 0; + margin-left: 1rem; + padding: 0; + line-height: 1; +} + +.front-page-introduction { + margin-bottom: 2rem; +} + +.navigation { + float: right; +} + +.navigation img { + height: 1em; + vertical-align: baseline; + display: inline-block; + margin: 0; + padding: 0; + border-radius: 0; +} + +main img { + max-width: 100%; + margin: auto; +} + +.post { + margin-bottom: 2em; +} + +.post:last-child { + margin-bottom: 0em; +} + +.frontpage-section { + margin-bottom: 2rem; +} + +.posts { + padding: 0.5rem 1rem 0.5rem 1rem; + border-radius: 5px; + margin-bottom: 2rem; + margin-left: -0.5rem; + margin-right: -0.5rem; +} + +.posts.neutral { + border: 2px solid #999; +} + +.posts.subscribe { + border: 2px solid #aaa; +} + +.posts.edition-1 { + border: 2px solid #aaa; + background-color: #99ff0022; +} + +.posts.bare-bones { + background-color: var(--background-color-section-bare-bones); + border: 2px solid var(--border-color-section-bare-bones); +} + +.posts.memory-management { + border: 2px solid #fc0 +} + +.posts.interrupts { + border: 2px solid #f66; +} + +.posts.multitasking { + border: 2px solid #556b2f; +} + +.posts hr { + margin: 2rem 0; +} + +.post-summary { + margin-bottom: 1rem; +} + +.post-summary p { + display: inline; +} + +.read-more { + margin-left: 5px; +} + +.no-translation { + margin-top: .3rem; + color: #999999; +} + +.post-category { + margin-right: 0.5rem; + text-transform: uppercase; + font-size: 0.8rem; + text-align: right; +} + +.post-category.bare-bones { + color: #55d; +} + +.post-category.memory-management { + color: #990; +} + +.post-category.interrupts { + color: #f33; +} + +.post-category.multitasking { + color: #556b2f; +} + +.post-footer-support { + margin-top: 2rem; +} + +.PageNavigation { + font-size: 0.9em; + display: table; + width: 100%; + overflow: hidden; +} + +.PageNavigation a { + display: table-cell; +} + +.PageNavigation .previous { + text-align: left; +} + +.PageNavigation .next { + text-align: right; +} + +footer.footer { + margin-top: 1rem; + margin-bottom: 1rem; +} + +.footnotes { + font-size: 85%; +} + +.footnotes li { + margin-bottom: 1rem; +} + +sup, sub { + line-height: 0; +} + +a.anchorjs-link:hover { + text-decoration: none; +} + +#toc-aside { + display: none; +} + +#toc-inline summary { + margin-bottom: .2rem; +} + +aside#all-posts-link { + font-size: 90%; + margin-top: 0.5rem; +} + +@media (min-width: 80rem) { + #toc-inline { + display: none; + } + #toc-aside { + display: block; + width: 12rem; + position: sticky; + float: left; + top: 3.5rem; + margin-top: -4rem; + margin-left: -15rem; + font-size: 90%; + line-height: 1.2; + } + #toc-aside li>a, #toc-aside h2 { + opacity: .5; + transition: opacity .5s; + } + #toc-aside:hover li>a, #toc-aside:hover h2 { + opacity: 1; + } + #toc-aside li.active>a { + font-weight: bold; + } + #toc-aside h2 { + font-size: 110%; + margin-bottom: .2rem; + } + #toc-aside ol { + margin: 0 0 .2rem 0; + padding: 0 0 0 1rem; + list-style: none; + } + #toc-aside ol li a:before { + content: ""; + border-color: transparent #008eef; + border-style: solid; + border-width: 0.35em 0 0.35em 0.45em; + display: block; + height: 0; + width: 0; + left: -1em; + top: 0.9em; + position: relative; + } + #toc-aside.coarse li ol { + display: none; + } + aside.page-aside-right { + position: absolute; + min-width: 11rem; + max-width: 17rem; + top: 4rem; + margin-left: 45rem; + margin-right: 2rem; + font-size: 90%; + } + aside.page-aside-right .block { + margin-bottom: 1.5rem; + } + aside.page-aside-right h2 { + font-size: 110%; + margin-bottom: .2rem; + } + aside.page-aside-right ul { + margin: 0 0 .2rem 0; + padding: 0 0 0 1rem; + } + aside.page-aside-right ul li { + margin-top: .5rem; + } + #language-selector li { + margin-top: 0; + } + aside#all-posts-link { + position: fixed; + top: 1.25rem; + margin-top: 0; + margin-left: -15rem; + } +} + +aside.page-aside-right time { + color: #9a9a9a; +} + +a code { + color: var(--link-color); +} + +a.zola-anchor { + opacity: 0; + position: absolute; + margin-left: -1.5em; + padding-right: 1em; + font-size: 0.6em; + vertical-align: baseline; + line-height: 2em; +} + +:hover>a.zola-anchor { + opacity: 1; + text-decoration: none; +} + +a.zola-anchor:hover { + text-decoration: none; +} + +div.note { + padding: .7rem 1rem; + margin: 1rem .2rem; + border: 2px solid #6ad46a; + border-radius: 5px; + background-color: #99ff991f; +} + +div.note p:last-child { + margin-bottom: 0; +} + +div.warning { + padding: .7rem 1rem; + margin: 1rem .2rem; + border: 2px solid orange; + border-radius: 5px; + background-color: #ffa50022; +} + +div.warning p:last-child { + margin-bottom: 0; +} + +form.subscribe { + margin: 1rem; +} + +div.subscribe-fields { + display: flex; +} + +form.subscribe input { + padding: .5rem; + border: 1px solid #e5e5e5; +} + +form.subscribe input[type=email] { + flex: 1; +} + +form.subscribe input[type=submit] { + padding: .25rem .5rem; + cursor: pointer; +} + +/* Asides */ + +aside.post_aside { + font-style: italic; + padding: 0rem 1rem 0rem; + margin: .8rem 0; + border-left: .1rem solid #e5e5e5; + border-right: .1rem solid #e5e5e5; +} + +details summary { + cursor: pointer; +} + +details summary h3, details summary h4, details summary h5, details summary h6 { + display: inline; +} + +.gh-repo-box { + border: 1px solid #d1d5da; + border-radius: 3px; + padding: 16px; + margin-top: 0.5rem; + color: #586069; + font-size: 80%; +} + +.gh-repo-box .repo-link { + color: #0366d6; + font-weight: 600; + font-size: 120%; +} + +.gh-repo-box .subtitle { + margin-bottom: 16px; +} + +.gh-repo-box .stars-forks { + margin-bottom: 0; +} + +.gh-repo-box .stars-forks a { + color: #586069; +} + +.gh-repo-box .stars-forks a:hover { + color: #0366d6; + text-decoration: none; +} + +.gh-repo-box .stars-forks svg { + vertical-align: text-bottom; + fill: currentColor; +} + +.gh-repo-box .stars { + display: inline-block; +} + +.gh-repo-box .forks { + display: inline-block; + margin-left: 16px; +} + +.gh-repo-box .sponsor { + display: inline-block; + margin-left: 16px; +} + +.hidden { + display: none; +} + +.toc-comments-link { + margin-top: .5rem; +} + +h5 { + font-style: italic; + font-size: 0.9rem; +} + +.gray { + color: gray; +} + +a strong { + color: #268bd2; +} + +.right-to-left { + direction: rtl; +} + +.left-to-right, .right-to-left pre { + direction: ltr; +} \ No newline at end of file diff --git a/blog/static/js/edition-3/main.js b/blog/static/js/edition-3/main.js new file mode 100644 index 00000000..dfa1dd4d --- /dev/null +++ b/blog/static/js/edition-3/main.js @@ -0,0 +1,63 @@ +window.onload = function() { + var container = document.querySelector('#toc-aside'); + + if (container != null) { + resize_toc(container); + toc_scroll_position(container); + window.onscroll = function() { toc_scroll_position(container) }; + } +} + +function resize_toc(container) { + var containerHeight = container.clientHeight; + + var resize = function() { + if (containerHeight > document.documentElement.clientHeight - 100) { + container.classList.add('coarse'); + } else { + container.classList.remove('coarse'); + } + }; + resize(); + + var resizeId; + window.onresize = function() { + clearTimeout(resizeId); + resizeId = setTimeout(resize, 300); + }; +} + +function toc_scroll_position(container) { + if (container.offsetParent === null) { + // skip computation if ToC is not visible + return; + } + var items = container.querySelectorAll("li") + + // remove active class for all items + for (item of container.querySelectorAll("li")) { + item.classList.remove("active"); + } + + // look for active item + var site_offset = document.documentElement.scrollTop; + var current_toc_item = null; + for (item of container.querySelectorAll("li")) { + if (item.offsetParent === null) { + // skip items that are not visible + continue; + } + var anchor = item.firstElementChild.getAttribute("href"); + var heading = document.querySelector(anchor); + if (heading.offsetTop <= (site_offset + document.documentElement.clientHeight / 3)) { + current_toc_item = item; + } else { + break; + } + } + + // set active class for current ToC item + if (current_toc_item != null) { + current_toc_item.classList.add("active"); + } +} diff --git a/blog/templates/edition-3/base.html b/blog/templates/edition-3/base.html new file mode 100644 index 00000000..26be6aa6 --- /dev/null +++ b/blog/templates/edition-3/base.html @@ -0,0 +1,13 @@ +{% extends "edition-3/foundation.html" %} + +{% block masthead %} +

+
+

+ {{ config.title | safe }} (Third Edition - Alpha) +

+

{{ config.extra.subtitle | replace(from=" ", to=" ") | safe }}

+ {% block header %}{% endblock header %} +
+
+{% endblock masthead %} diff --git a/blog/templates/edition-3/extra.html b/blog/templates/edition-3/extra.html new file mode 100644 index 00000000..7692188a --- /dev/null +++ b/blog/templates/edition-3/extra.html @@ -0,0 +1,22 @@ +{% extends "edition-3/base.html" %} + +{% import "macros.html" as macros %} + +{% block title %}{{ page.title }} | {{ config.title }}{% endblock title %} + +{% block description -%} +{{ page.summary | safe | striptags | truncate(length=150) }} +{%- endblock description %} + +{% block main %} +

{{ page.title }}

+ {{ page.content | safe }} +{% endblock main %} + +{% block after_main %} +
+
+

Comments

+ {{ macros::utterances() }} +
+{% endblock after_main %} diff --git a/blog/templates/edition-3/foundation.html b/blog/templates/edition-3/foundation.html new file mode 100644 index 00000000..bc5ec391 --- /dev/null +++ b/blog/templates/edition-3/foundation.html @@ -0,0 +1,61 @@ + + + + + + + + + + + + {% if current_url %} + + {% endif %} + + + + + + + {% block title %}{% endblock title %} (Third Edition - Alpha) + + + +
+ {% block masthead %}{% endblock masthead %} + +
+ {% block toc_aside %}{% endblock toc_aside %} +
{% block main %}{% endblock main %}
+
+ +
{% block after_main %}{% endblock after_main %}
+ + +
+ + + + + + + diff --git a/blog/templates/edition-3/index.html b/blog/templates/edition-3/index.html new file mode 100644 index 00000000..19f1c136 --- /dev/null +++ b/blog/templates/edition-3/index.html @@ -0,0 +1,141 @@ +{% extends "edition-3/foundation.html" %} + +{% import "macros.html" as macros %} + +{% block title %}{{ config.title }}{% endblock title %} + +{% block main %} +{% set posts_section = get_section(path = "edition-3/posts/_index.md") %} +{% set posts = posts_section.pages %} + +

Writing an OS in Rust

+

{{ config.extra.subtitle | replace(from=" ", to=" ") | safe }}

+ +
+

+ This blog series creates a small operating system in the + Rust programming language. Each post is a small tutorial and includes all + needed code, so you can follow along if you like. The source code is also available in the corresponding + Github repository. +

+ +

Latest post: + {% set latest_post = posts|last %} + {{ latest_post.title }} +

+
+ + + +
+{%- set chapter = "none" -%} +{%- for post in posts -%} + {%- if post.extra["chapter"] -%} + {%- if post.extra["chapter"] != chapter -%} + {# Begin new chapter #} + {%- set_global chapter = post.extra["chapter"] -%} +
+ +{% set chapter_slug = chapter | slugify %} +
+{% set chapter_page = get_page(path = "edition-3/chapters/" ~ chapter_slug ~ ".md" ) %} +{{ chapter_page.content | safe }} + + {%- endif -%} + {%- endif -%} + + {{ macros::post_link_edition_3(page=post) }} +{%- endfor -%} +
+ +
+ +
+

Subscribe

+

Receive notifications about new posts and other major changes! You can either:

+ + +
+ +
+

Status Updates

+ {% set status_updates = get_section(path = "status-update/_index.md") %} +

{{ status_updates.description }}

+ +
+ +
+

First Edition

+

You are currently viewing the second edition of “Writing an OS in Rust”. The first edition is very different in many aspects, for example it builds upon the GRUB bootloader instead of using the `bootloader` crate. In case you're interested in it, it is still available. Note that the first edition is no longer updated and might contain outdated information. read the first edition »

+
+ +
+

Support Me

+ {% include "support.html" %} +
+{% endblock main %} + +{% block after_main %} + + +{% endblock after_main %} diff --git a/blog/templates/edition-3/page.html b/blog/templates/edition-3/page.html new file mode 100644 index 00000000..3aa33930 --- /dev/null +++ b/blog/templates/edition-3/page.html @@ -0,0 +1,130 @@ +{% extends "edition-3/base.html" %} + +{% import "macros.html" as macros %} + +{% block title %}{{ page.title }} | {{ config.title }}{% endblock title %} +{% block header %} + {% if lang != "en" -%} + + {%- else -%} + + {%- endif %} +{% endblock header %} + +{% block description -%} +{{ page.summary | safe | striptags | truncate(length=150) }} +{%- endblock description %} + +{% block toc_aside %} + +{% endblock toc_aside %} + +{% block main %} +
+

{{ page.title }}

+ +
+ + {% if page.extra.warning %} +
+ {% if page.extra.warning_short %} {{ page.extra.warning_short }} {% endif %} + {{ page.extra.warning | markdown(inline=true) | safe }} +
+ {% endif %} + + {%- if page.lang != "en" %} +
+ {% set translations = page.translations | filter(attribute="lang", value="en") %} + {% set original = translations.0 %} +

+ Translated Content: + This is a community translation of the {{ original.title }} post. It might be incomplete, outdated or contain errors. Please report any issues! +

+ {%- if page.extra.translators %} +

+ Translation by {% for user in page.extra.translators -%} + {%- if not loop.first -%} + {%- if loop.last %}, and {% else %}, {% endif -%} + {%- endif -%} + @{{user}} + {%- endfor %}. +

+ {% endif -%} +
+ {% endif %} + +
+ {{ page.content | replace(from="", to=macros::toc(toc=page.toc)) | safe }} +
+ +
+

Support Me

+ {% include "support.html" %} +
+ +
+ + +
+
+

Comments

+ + {%- if page.lang != "en" %} +

+ Please leave your comments in English if possible. +

+ {% endif %} + + {{ macros::utterances() }} +
+ + + +{% endblock main %} diff --git a/blog/templates/edition-3/raw.html b/blog/templates/edition-3/raw.html new file mode 100644 index 00000000..94723a25 --- /dev/null +++ b/blog/templates/edition-3/raw.html @@ -0,0 +1 @@ +{{ page.content | safe }} diff --git a/blog/templates/macros.html b/blog/templates/macros.html index 2566f973..3e86599f 100644 --- a/blog/templates/macros.html +++ b/blog/templates/macros.html @@ -21,6 +21,29 @@ {% endmacro post_link %} +{% macro post_link_edition_3(page) %} +
+ {% set translations = page.translations | filter(attribute="lang", value=lang) -%} + {%- if translations -%} + {%- set post = get_page(path = translations.0.path) -%} + {%- else -%} + {%- set post = page -%} + {%- set not_translated = true -%} + {%- endif -%} +

{{ post.title }}

+
+ {{ post.summary | safe }} + read more » + + {%- if lang and not_translated and lang != config.default_language -%} + + {%- endif -%} +
+
+{% endmacro post_link %} + {% macro utterances() %}