commit d3a534ab6444ee154761a1168199de56e8281dfd Author: Mario Romero Date: Tue May 16 14:08:46 2023 -0400 First commit diff --git a/src/.fleek.json b/src/.fleek.json new file mode 100644 index 0000000..80d2e19 --- /dev/null +++ b/src/.fleek.json @@ -0,0 +1,7 @@ +{ + "build": { + "image": "denoland/deno", + "command": "deno task build --location=https://lume-blog.on.fleek.co", + "publicDir": "_site" + } +} diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 0000000..42de261 --- /dev/null +++ b/src/.gitignore @@ -0,0 +1,2 @@ +_site +_bin \ No newline at end of file diff --git a/src/404.md b/src/404.md new file mode 100644 index 0000000..c2d5b2a --- /dev/null +++ b/src/404.md @@ -0,0 +1,8 @@ +--- +layout: layouts/home.njk +url: /404.html +--- + +# Content not found. + +Go [home](/). diff --git a/src/_config.ts b/src/_config.ts new file mode 100644 index 0000000..53ca5e3 --- /dev/null +++ b/src/_config.ts @@ -0,0 +1,46 @@ +import lume from "lume/mod.ts"; +import date from "lume/plugins/date.ts"; +import postcss from "lume/plugins/postcss.ts"; +import codeHighlight from "lume/plugins/code_highlight.ts"; +import basePath from "lume/plugins/base_path.ts"; +import slugifyUrls from "lume/plugins/slugify_urls.ts"; +import resolveUrls from "lume/plugins/resolve_urls.ts"; +import netlifyCMS from "lume/plugins/netlify_cms.ts"; +import pageFind from "lume/plugins/pagefind.ts"; +import sitemap from "lume/plugins/sitemap.ts"; +import feed from "lume/plugins/feed.ts"; + +const site = lume({ + location: new URL("https://example.com/"), +}); + +site + .ignore("README.md") + .copy("img") + .use(postcss()) + .use(date()) + .use(codeHighlight()) + .use(basePath()) + .use(sitemap()) + .use(pageFind({ + ui: { + resetStyles: false, + }, + })) + .use(slugifyUrls({ alphanumeric: false })) + .use(feed({ + output: ["/feed.json", "/feed.xml"], + query: "type=posts", + info: { + title: "=site.title", + description: "=site.description", + }, + items: { + title: "=title", + content: "$.post-body", + } + })) + .use(resolveUrls()) + .use(netlifyCMS({ netlifyIdentity: true })); + +export default site; diff --git a/src/_data/netlify_cms.js b/src/_data/netlify_cms.js new file mode 100644 index 0000000..60c9b63 --- /dev/null +++ b/src/_data/netlify_cms.js @@ -0,0 +1,54 @@ +import f from "https://deno.land/x/netlify_cms_config@v0.2.0/mod.ts"; + +f.defaultRequired = false; + +const config = { + backend: { + name: "git-gateway", + branch: "master", + }, + media_folder: "img", + collections: [], +}; + +// Posts +config.collections.push( + f.folder("Posts", "posts") + .description("Here you can create or edit your posts") + .preview(false) + .create(true) + .viewFilter("Draft", "draft", true) + .fields([ + f.string("Title"), + f.string("Description"), + f.datetime("Date"), + f.list("Tags"), + f.boolean("Draft").required(false), + f.markdown("Body"), + ]) + .toJSON(), +); + +const pageFields = [ + f.string("Title"), + f.string("Url"), + f.markdown("Body"), + f.object("Menu", [ + f.boolean("Visible"), + f.number("Order"), + ]), + f.hidden("templateClass"), + f.hidden("layout"), +]; + +// Individual pages +config.collections.push( + f.files("Pages") + .description("Here you can edit your individual pages") + .preview(false) + .file("About", "about.md", pageFields) + .file("404", "404.md", pageFields) + .toJSON(), +); + +export default config; diff --git a/src/_data/site.yml b/src/_data/site.yml new file mode 100755 index 0000000..0e61942 --- /dev/null +++ b/src/_data/site.yml @@ -0,0 +1,6 @@ +title: 1159 +description: Mario Romero personal site. +author: + name: Mario Romero, + email: mario@1159.cl, + url: https://1159.cl/home/ diff --git a/src/_includes/css/navbar.css b/src/_includes/css/navbar.css new file mode 100644 index 0000000..4e25422 --- /dev/null +++ b/src/_includes/css/navbar.css @@ -0,0 +1,66 @@ +.navbar { + display: flex; + flex-wrap: wrap; + align-items: center; + padding: 1rem 1rem 1rem 2rem; + column-gap: 2rem; + row-gap: 1rem; + background-color: var(--bg-secondary); + + & a { + display: block; + color: var(--fg-secondary); + + &:not(:hover) { + text-decoration: none; + } + } +} + +.navbar-links { + padding: 0; + margin: 0; + list-style: none; + display: flex; + flex-wrap: wrap; + column-gap: 2rem; + + & [aria-current="page"] { + font-weight: bold; + text-decoration: underline; + } +} +.navbar-search { + flex-grow: 1; + max-width: 800px; + margin-left: auto; +} + +#search { + & .pagefind-ui__drawer { + margin-top: 2px; + position: absolute; + background: var(--bg-secondary); + padding: 0 2rem 1rem; + max-height: calc(100vh - 200px); + overflow-y: auto; + box-shadow: 0 10px 10px -5px rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.1); + border-bottom-right-radius: var(--pagefind-ui-border-radius); + border-bottom-left-radius: var(--pagefind-ui-border-radius); + width: 100%; + box-sizing: border-box; + } + & .pagefind-ui__message { + margin: 0; + padding: 0; + } + & .pagefind-ui__result-link { + color: var(--accent-primary); + } + & .pagefind-ui__result-excerpt { + color: var(--fg-primary); + } + & .pagefind-ui__search-input { + color: var(--fg-primary); + } +} diff --git a/src/_includes/css/post-list.css b/src/_includes/css/post-list.css new file mode 100644 index 0000000..e4d8e23 --- /dev/null +++ b/src/_includes/css/post-list.css @@ -0,0 +1,19 @@ +.postList { + list-style: none; + padding: 0; +} + +.postList-date { + font-size: 0.8rem; + color: var(--fg-primary); +} + +.postList-title { + display: inline-block; + padding: 0.5em 0.2em; + font-size: 1.2rem; + + &[aria-current="page"] { + font-weight: bold; + } +} diff --git a/src/_includes/css/post.css b/src/_includes/css/post.css new file mode 100644 index 0000000..4ee1df4 --- /dev/null +++ b/src/_includes/css/post.css @@ -0,0 +1,45 @@ +.post-header { + padding: 5vh 0; +} +.post-title { + font-size: 4rem; + font-size: clamp(2rem, 10vw, 4rem); + line-height: 1; + letter-spacing: -0.02em; + margin: 0 0 0.25em; +} +.post-tags { + display: inline; +} +.post-body { + font-size: 1.2em; + line-height: 1.4; + + & p, + & ul, + & ol { + max-width: 45em; + } + + & h2, + & h3, + & h4, + & h5, + & h6 { + max-width: 20em; + margin-bottom: 0; + } +} +.post-navigation { + & ul { + list-style: none; + padding: 0; + display: flex; + flex-wrap: wrap; + justify-content: center; + } + + & li { + padding: 1em; + } +} \ No newline at end of file diff --git a/src/_includes/css/reset.css b/src/_includes/css/reset.css new file mode 100644 index 0000000..1fa2859 --- /dev/null +++ b/src/_includes/css/reset.css @@ -0,0 +1,73 @@ +:root { + --bg-primary: #0a0a0a; /* Black */ + --bg-secondary: #171717; /* Dark gray */ + --accent-primary: #26a269; /* Teal */ + --accent-primary-pale: #26a269; /* Teal */ + --accent-secondary: #613583; /* Purple */ + --accent-secondary-pale: #c061cb; /* Light purple */ + --fg-primary: #ffffff; /* White */ + --fg-secondary: #f2f2f2; /* Light gray */ + --font-family: -apple-system, system-ui, sans-serif; +} + +html, +body { + padding: 0; + margin: 0; + font-family: var(--font-family); + color: var(--fg-primary); + background-color: var(--bg-primary); + + /** Pagefind variables */ + --pagefind-ui-scale: .8; + --pagefind-ui-primary: var(--accent-primary); + --pagefind-ui-text: var(--fg-primary); + --pagefind-ui-background: var(--bg-primary); + --pagefind-ui-border: var(--bg-secondary); + --pagefind-ui-tag: var(--bg-secondary); + --pagefind-ui-border-width: 1px; + --pagefind-ui-border-radius: 6px; + --pagefind-ui-image-border-radius: 6px; + --pagefind-ui-image-box-ratio: 3 / 2; + --pagefind-ui-font: var(--font-family); +} + +main { + padding: 5vh 5vw; + + & > :first-child { + margin-top: 0; + } +} + +a { + color: var(--accent-secondary-pale); +} + +/* Warning */ +.warning { + background-color: var(--bg-secondary); + padding: 1em 0.5em; +} + +table { + margin: 1em 0; + + & td, + & th { + padding-right: 1em; + } +} + +pre, +code { + font-family: Consolas, Menlo, Monaco, "Andale Mono WT", "Andale Mono", "Lucida Console", "Lucida Sans Typewriter", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Liberation Mono", "Nimbus Mono L", "Courier New", Courier, monospace; + line-height: 1.5; + font-size: 1rem; +} + +hr { + border: 0; + border-top: solid 2px var(--bg-secondary); + margin: 5vh 0; +} diff --git a/src/_includes/css/search.css b/src/_includes/css/search.css new file mode 100644 index 0000000..688a54d --- /dev/null +++ b/src/_includes/css/search.css @@ -0,0 +1,34 @@ +search-form { +} +oom-search::part(input) { + border: solid 2px var(--accent-primary); + border-radius: 4px; + padding: .5em; + background: none; +} +oom-search::part(label) { + font-weight: bold; +} +oom-search::part(input) { + border: solid 2px var(--accent-primary); + border-radius: 4px; + padding: .5em; + background: none; +} +oom-search::part(items) { + padding: .5em; + margin: .5em 0; + box-shadow: 0 2px 3px #0003; + background: var(--bg-primary); + width: auto; + min-width: 100%; + right: 0; +} +oom-search::part(item) { + background: none; + font: inherit; + padding: .5em 1em; +} +oom-search::part(active) { + background-color: var(--bg-primary); +} diff --git a/src/_includes/css/tag.css b/src/_includes/css/tag.css new file mode 100644 index 0000000..62bf836 --- /dev/null +++ b/src/_includes/css/tag.css @@ -0,0 +1,16 @@ +.tag { + display: inline-block; + text-transform: uppercase; + font-size: 0.7rem; + line-height: 1; + padding: 0.2em 0.5em; + margin-right: 0.8em; + background-color: var(--accent-primary); + color: var(--bg-primary); + border-radius: 0.25em; + text-decoration: none; + + &.is-big { + font-size: 1rem; + } +} diff --git a/src/_includes/layouts/archive.njk b/src/_includes/layouts/archive.njk new file mode 100644 index 0000000..fb89de0 --- /dev/null +++ b/src/_includes/layouts/archive.njk @@ -0,0 +1,30 @@ +--- +layout: layouts/base.njk +bodyClass: body-tag +--- +

{{ title }}

+ +{% set postslist = results %} +{% include "templates/postslist.njk" %} + +
+ + \ No newline at end of file diff --git a/src/_includes/layouts/base.njk b/src/_includes/layouts/base.njk new file mode 100644 index 0000000..469b79e --- /dev/null +++ b/src/_includes/layouts/base.njk @@ -0,0 +1,42 @@ + + + + + + + {{ title or site.title }} + + + + + + + + +
+ {{ content | safe }} +
+ + + + + + diff --git a/src/_includes/layouts/home.njk b/src/_includes/layouts/home.njk new file mode 100644 index 0000000..f0acfa8 --- /dev/null +++ b/src/_includes/layouts/home.njk @@ -0,0 +1,6 @@ +--- +layout: layouts/base.njk +bodyClass: body-home +--- +aaa +{{ content | safe }} diff --git a/src/_includes/layouts/post.njk b/src/_includes/layouts/post.njk new file mode 100644 index 0000000..1794dd5 --- /dev/null +++ b/src/_includes/layouts/post.njk @@ -0,0 +1,43 @@ +--- +layout: layouts/base.njk +bodyClass: body-post +--- +
+
+

{{ title }}

+ + + + +
+ +
+ {{ content | safe }} +
+
+ +
+ + \ No newline at end of file diff --git a/src/_includes/layouts/tag.njk b/src/_includes/layouts/tag.njk new file mode 100644 index 0000000..3535475 --- /dev/null +++ b/src/_includes/layouts/tag.njk @@ -0,0 +1,14 @@ +--- +layout: layouts/base.njk +bodyClass: body-tag +--- +
+

Tagged “{{ tag }}”

+ + {% set postslist = search.pages("'" + tag + "'") %} + {% include "templates/postslist.njk" %} + +
+ +

See all tags.

+
\ No newline at end of file diff --git a/src/_includes/templates/postslist.njk b/src/_includes/templates/postslist.njk new file mode 100644 index 0000000..b577fd5 --- /dev/null +++ b/src/_includes/templates/postslist.njk @@ -0,0 +1,24 @@ + diff --git a/src/about.md b/src/about.md new file mode 100644 index 0000000..6bbedc3 --- /dev/null +++ b/src/about.md @@ -0,0 +1,10 @@ +--- +layout: layouts/post.njk +title: About Me +templateClass: tmpl-post +menu: + visible: true + order: 2 +--- + +I am a person that writes stuff. diff --git a/src/archive.tmpl.js b/src/archive.tmpl.js new file mode 100644 index 0000000..7150cf7 --- /dev/null +++ b/src/archive.tmpl.js @@ -0,0 +1,28 @@ +export const layout = "layouts/archive.njk"; +export const title = "Archive"; + +export default function* ({ search, paginate }) { + const posts = search.pages("type=posts", "date=desc"); + + for ( + const data of paginate(posts, { url, size: 10 }) + ) { + // Show the first page in the menu + if (data.pagination.page === 1) { + data.menu = { + visible: true, + order: 1, + }; + } + + yield data; + } +} + +function url(n) { + if (n === 1) { + return "/posts/"; + } + + return `/posts/${n}/`; +} diff --git a/src/deno.json b/src/deno.json new file mode 100644 index 0000000..ddc662f --- /dev/null +++ b/src/deno.json @@ -0,0 +1,11 @@ +{ + "imports": { + "lume/": "https://deno.land/x/lume@v1.17.3/" + }, + "lock": false, + "tasks": { + "build": "deno task lume", + "serve": "deno task lume -s", + "lume": "echo \"import 'lume/cli.ts'\" | deno run --unstable -A -" + } +} diff --git a/src/img/.gitkeep b/src/img/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/index.njk b/src/index.njk new file mode 100644 index 0000000..3fe37f4 --- /dev/null +++ b/src/index.njk @@ -0,0 +1,25 @@ +--- +layout: layouts/home.njk +menu: + visible: true + title: Home + order: 0 +--- + +{% set postslist = search.pages("type=posts", "date=desc", 3) %} + +

Latest {% if postslist.length == 1 %}Post{% else %}{{ postslist.length }} Posts{% endif %}

+ +{% include "templates/postslist.njk" %} + +
+ +{% set postslist = search.pages("pinned=true") %} + +{%if postslist.length %} +

Pinned Post:

+ {% include "templates/postslist.njk" %} +
+{% endif %} + +

More posts can be found in the archive.

diff --git a/src/netlify.toml b/src/netlify.toml new file mode 100644 index 0000000..20c2d3e --- /dev/null +++ b/src/netlify.toml @@ -0,0 +1,6 @@ +[build] + publish = "_site" + command = """ + curl -fsSL https://deno.land/x/install/install.sh | sh && \ + /opt/buildhome/.deno/bin/deno task build --location=https://deno-blog.netlify.app/ \ + """ diff --git a/src/posts/_data.yml b/src/posts/_data.yml new file mode 100644 index 0000000..bd026d2 --- /dev/null +++ b/src/posts/_data.yml @@ -0,0 +1,2 @@ +type: posts +layout: layouts/post.njk \ No newline at end of file diff --git a/src/posts/fifthpost.md b/src/posts/fifthpost.md new file mode 100644 index 0000000..2618e39 --- /dev/null +++ b/src/posts/fifthpost.md @@ -0,0 +1,10 @@ +--- +title: This is the fifth post (in draft). +description: This post shouldn't be visible in production +date: 2021-01-01 +tags: + - second-tag +draft: true +--- + +To see this post, run `lume --dev` diff --git a/src/posts/firstpost.md b/src/posts/firstpost.md new file mode 100644 index 0000000..f7c0178 --- /dev/null +++ b/src/posts/firstpost.md @@ -0,0 +1,35 @@ +--- +title: This is my first post. +description: This is a post on My Blog about agile frameworks. +date: 2018-05-01 +tags: + - another-tag +--- + +Leverage agile frameworks to provide a robust synopsis for high level overviews. +Iterative approaches to corporate strategy foster collaborative thinking to +further the overall value proposition. Organically grow the holistic world view +of disruptive innovation via workplace diversity and empowerment. + +Bring to the table win-win survival strategies to ensure proactive domination. +At the end of the day, going forward, a new normal that has evolved from +generation X is on the runway heading towards a streamlined cloud solution. User +generated content in real-time will have multiple touchpoints for offshoring. + +## Section Header + +Capitalize on low hanging fruit to identify a ballpark value added activity to +beta test. Override the digital divide with additional clickthroughs from +DevOps. Nanotechnology immersion along the information highway will close the +loop on focusing solely on the bottom line. + +```js +// this is a command +function myCommand() { + let counter = 0; + counter++; +} + +// Test with a line break above this line. +console.log("Test"); +``` diff --git a/src/posts/fourthpost.md b/src/posts/fourthpost.md new file mode 100644 index 0000000..efdad53 --- /dev/null +++ b/src/posts/fourthpost.md @@ -0,0 +1,24 @@ +--- +title: This is my fourth post. +description: This is a post on My Blog about touchpoints and circling wagons. +date: 2018-09-30 +tags: + - second-tag +--- + +Leverage agile frameworks to provide a robust synopsis for high level overviews. +Iterative approaches to corporate strategy foster collaborative thinking to +further the overall value proposition. Organically grow the holistic world view +of disruptive innovation via workplace diversity and empowerment. + +Bring to the table win-win survival strategies to ensure proactive domination. +At the end of the day, going forward, a new normal that has evolved from +generation X is on the runway heading towards a streamlined cloud solution. User +generated content in real-time will have multiple touchpoints for offshoring. + +## Section Header + +Capitalize on low hanging fruit to identify a ballpark value added activity to +beta test. Override the digital divide with additional clickthroughs from +DevOps. Nanotechnology immersion along the information highway will close the +loop on focusing solely on the bottom line. diff --git a/src/posts/secondpost.md b/src/posts/secondpost.md new file mode 100644 index 0000000..3c8aeea --- /dev/null +++ b/src/posts/secondpost.md @@ -0,0 +1,28 @@ +--- +title: This is my second post. +description: This is a post on My Blog about leveraging agile frameworks. +date: 2018-07-04 +tags: + - number-2 + - second-tag + +--- + +Leverage agile frameworks to provide a robust synopsis for high level overviews. +Iterative approaches to corporate strategy foster collaborative thinking to +further the overall value proposition. Organically grow the holistic world view +of disruptive innovation via workplace diversity and empowerment. + +## Section Header + +[First post](firstpost.md) [Third post](thirdpost.md) + +Bring to the table win-win survival strategies to ensure proactive domination. +At the end of the day, going forward, a new normal that has evolved from +generation X is on the runway heading towards a streamlined cloud solution. User +generated content in real-time will have multiple touchpoints for offshoring. + +Capitalize on low hanging fruit to identify a ballpark value added activity to +beta test. Override the digital divide with additional clickthroughs from +DevOps. Nanotechnology immersion along the information highway will close the +loop on focusing solely on the bottom line. diff --git a/src/posts/thirdpost.md b/src/posts/thirdpost.md new file mode 100644 index 0000000..5371202 --- /dev/null +++ b/src/posts/thirdpost.md @@ -0,0 +1,37 @@ +--- +title: This is my third post. +description: This is a post on My Blog about win-win survival strategies. +date: 2018-08-24 +pinned: true +tags: + - second-tag +--- + +Leverage agile frameworks to provide a robust synopsis for high level overviews. +Iterative approaches to corporate strategy foster collaborative thinking to +further the overall value proposition. Organically grow the holistic world view +of disruptive innovation via workplace diversity and empowerment. + +```js +// this is a command +function myCommand() { + let counter = 0; + + counter++; +} + +// Test with a line break above this line. +console.log("Test"); +``` + +Bring to the table win-win survival strategies to ensure proactive domination. +At the end of the day, going forward, a new normal that has evolved from +generation X is on the runway heading towards a streamlined cloud solution. User +generated content in real-time will have multiple touchpoints for offshoring. + +## Section Header + +Capitalize on low hanging fruit to identify a ballpark value added activity to +beta test. Override the digital divide with additional clickthroughs from +DevOps. Nanotechnology immersion along the information highway will close the +loop on focusing solely on the bottom line. diff --git a/src/search.tmpl.js b/src/search.tmpl.js new file mode 100644 index 0000000..d20ea51 --- /dev/null +++ b/src/search.tmpl.js @@ -0,0 +1,25 @@ +export const url = "/search.json"; + +export default function ({ search }, { url }) { + const result = []; + + // Search tags + for (const tag of search.tags("type=posts")) { + result.push({ + label: `Tag: ${tag}`, + search: tag, + value: url(`/tags/${tag}/`), + }); + } + + // Search posts + for (const post of search.pages("type=posts")) { + result.push({ + label: post.data.title, + search: `${post.data.title} ${post.data.tags.join(" ")}`, + value: url(post.data.url), + }); + } + + return JSON.stringify(result); +} diff --git a/src/server.ts b/src/server.ts new file mode 100644 index 0000000..3b61169 --- /dev/null +++ b/src/server.ts @@ -0,0 +1,18 @@ +import Server from "lume/core/server.ts"; +import expires from "lume/middlewares/expires.ts"; +import notFound from "lume/middlewares/not_found.ts"; + +const server = new Server({ + port: 8000, + root: `${Deno.cwd()}/_site`, +}); + +server.use(expires()); +server.use(notFound({ + root: `${Deno.cwd()}/_site`, + page404: "/404.html", +})); + +server.start(); + +console.log("Listening on http://localhost:8000"); diff --git a/src/styles.css b/src/styles.css new file mode 100644 index 0000000..cebe754 --- /dev/null +++ b/src/styles.css @@ -0,0 +1,9 @@ +/* Code syntax highlight */ +@import "https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.0.0/build/styles/github-dark.min.css"; + +@import "css/reset.css"; +@import "css/navbar.css"; +@import "css/search.css"; +@import "css/post-list.css"; +@import "css/post.css"; +@import "css/tag.css"; diff --git a/src/tag.tmpl.js b/src/tag.tmpl.js new file mode 100644 index 0000000..ec3bb58 --- /dev/null +++ b/src/tag.tmpl.js @@ -0,0 +1,12 @@ +export const layout = "layouts/tag.njk"; + +export default function* ({ search }) { + for (const tag of search.tags()) { + yield { + url: `/tags/${tag}/`, + title: `Tagged “${tag}”`, + type: "tag", + tag, + }; + } +} diff --git a/src/tags.njk b/src/tags.njk new file mode 100644 index 0000000..a9f8f28 --- /dev/null +++ b/src/tags.njk @@ -0,0 +1,8 @@ +--- +layout: layouts/base.njk +--- +

Tags

+ +{% for page in search.pages("type=tag", "tag") %} + {{ page.data.tag }} +{% endfor %}