diff --git a/.gitignore b/.gitignore index e515729..364fdec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1 @@ -build -node_modules -npm-debug.log -contents/css/main.min.css +public/ diff --git a/Makefile b/Makefile deleted file mode 100644 index b24bbe0..0000000 --- a/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -WINTERSMITH = ./node_modules/.bin/wintersmith - -build: - @./node_modules/.bin/cleancss ./contents/css/main.css > ./contents/css/main.min.css - @$(WINTERSMITH) build - -clean: - @rm -rf build - -preview: build - @$(WINTERSMITH) preview - -pull: - git pull - -update: pull build - -.PHONY: build clean preview pull update diff --git a/README.md b/README.md index d644520..49e0faf 100644 --- a/README.md +++ b/README.md @@ -5,48 +5,31 @@ A satirical blog about programming and general technology. ## Installing +`theworstprogrammerever` requires `hugo` to build the server + ```shell git clone git://github.com/brettlangdon/theworstprogrammerever cd ./theworstprogrammerever -npm install -``` - -## Running - -### Building -If you would like to generate the blog you can run: +# build the static files +hugo -```shell -make build +# run development server at http://localhost:1313 +hugo server -w ``` -Which will generate the static files necessary for the blog in `./build` - - -### Preview - -If you would like to preview the blog or any changes that you have made you can -run: - -```shell -make preview -``` - -Then visit http://localhost:8080/ ## Contributing If you would like to contribute an article to http://theworstprogrammerever.com: 1. Fork this repository -2. Add your article to `contents/articles//index.md` +2. Add your article to `content/post//index.md` 1. Format for `index.md` should be: ```markdown --- title: author: date: YYY-MM-DD - template: article.jade --- Short summary here @@ -55,24 +38,14 @@ If you would like to contribute an article to http://theworstprogrammerever.com: This is the actual article. You can use whatever markdown you want. ``` -3. If this is your first article please add yourself to -`contents/authors/.json` - 1. Format for `.json` should be: - ```json - { - "name": "", - "website": "" - } - ``` -4. Create a pull request to this repo to await review/merge -5. Profit +3. Create a pull request to this repo to await review/merge +4. Profit # License -
This work -is licensed under a Creative Commons -Attribution-ShareAlike 4.0 International License. + + Creative Commons License + +
+This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. diff --git a/config.json b/config.json deleted file mode 100644 index 53ded1e..0000000 --- a/config.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "locals": { - "url": "http://theworstprogrammerever.com", - "name": "The Worst Programmer Ever", - "owner": "The Worst Programmer Ever", - "description": "The best advice from the worst programmers" - }, - "plugins": [ - "./plugins/paginator.coffee" - ], - "require": { - "moment": "moment", - "_": "underscore", - "typogr": "typogr" - }, - "jade": { - "pretty": true - }, - "markdown": { - "smartLists": true, - "smartypants": true, - "gfm": true - }, - "paginator": { - "perPage": 3 - } -} diff --git a/config.toml b/config.toml new file mode 100644 index 0000000..9b6ad49 --- /dev/null +++ b/config.toml @@ -0,0 +1,25 @@ +languageCode = "en-us" +title = "The Worst Programmer Ever" +baseURL = "https://theworstprogrammerever.com" +theme = "hugo-after-dark" +disqusShortname = "theworstprogrammerever" +googleAnalytics = "UA-43062483-1" +SectionPagesMenu = "main" + +[params] + description = "The best advice from the worst programmers" + show_menu = true + powered_by = false + theme_variant = "hack light" + +[[menu.main]] + name = "Home" + weight = 1 + identifier = "home" + url = "/" + +[[menu.main]] + name = "About" + weight = 2 + identifier = "about" + url = "/about" diff --git a/contents/about.md b/content/about.md similarity index 62% rename from contents/about.md rename to content/about.md index 60c5556..3286239 100644 --- a/contents/about.md +++ b/content/about.md @@ -1,10 +1,13 @@ --- -view: none +title: About --- -
This work -is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. + + diff --git a/contents/articles/cocode-is-bad-code/index.md b/content/post/cocode-is-bad-code/index.md similarity index 98% rename from contents/articles/cocode-is-bad-code/index.md rename to content/post/cocode-is-bad-code/index.md index b410487..3d65515 100644 --- a/contents/articles/cocode-is-bad-code/index.md +++ b/content/post/cocode-is-bad-code/index.md @@ -2,7 +2,6 @@ title: Co-Code is Bad Code author: colin date: 2014-10-14 -template: article.jade --- Learn why co-coding isn't all it is cracked up to be. diff --git a/contents/articles/how-to-contribute-to-open-source/index.md b/content/post/how-to-contribute-to-open-source/index.md similarity index 99% rename from contents/articles/how-to-contribute-to-open-source/index.md rename to content/post/how-to-contribute-to-open-source/index.md index a6ab273..22cd593 100644 --- a/contents/articles/how-to-contribute-to-open-source/index.md +++ b/content/post/how-to-contribute-to-open-source/index.md @@ -2,7 +2,6 @@ title: How to Contribute to Open Source author: brett date: 2014-10-14 -template: article.jade --- Learn how to get started in the big and scary Open Source community. diff --git a/contents/articles/microcommits/index.md b/content/post/microcommits/index.md similarity index 99% rename from contents/articles/microcommits/index.md rename to content/post/microcommits/index.md index 41cf5c1..dc0375a 100644 --- a/contents/articles/microcommits/index.md +++ b/content/post/microcommits/index.md @@ -2,7 +2,6 @@ title: Microcommits author: brett date: 2015-06-24 -template: article.jade --- A look into the new development methodology of microcommitting. diff --git a/contents/articles/scrum-is-life/index.md b/content/post/scrum-is-life/index.md similarity index 99% rename from contents/articles/scrum-is-life/index.md rename to content/post/scrum-is-life/index.md index 324dc1d..f8c6e83 100644 --- a/contents/articles/scrum-is-life/index.md +++ b/content/post/scrum-is-life/index.md @@ -2,7 +2,6 @@ title: Scrum is Life author: adam date: 2016-04-26 -template: article.jade --- If you're not doing scrum, you're doing it wrong. @@ -33,6 +32,7 @@ With this minimal (and agreed upon) process in place, it's hard for me to believ Images from: + * https://en.wikipedia.org/wiki/Scrum_(software_development) * https://dmquickscrum.wordpress.com/2014/11/07/in-scrum-can-a-sprint-be-cancelled-if-so-when/ -* http://leadinganswers.typepad.com/leading_answers/2012/02/timebox-alternatives.html \ No newline at end of file +* http://leadinganswers.typepad.com/leading_answers/2012/02/timebox-alternatives.html diff --git a/contents/archive.json b/contents/archive.json deleted file mode 100644 index 0fd2fd3..0000000 --- a/contents/archive.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "template": "archive.jade" -} diff --git a/contents/authors/adam.json b/contents/authors/adam.json deleted file mode 100644 index ad16b08..0000000 --- a/contents/authors/adam.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "Adam Weiss", - "website": "https://github.com/amweiss", - "bio": "Adam still thinks he can write code" -} diff --git a/contents/authors/brett.json b/contents/authors/brett.json deleted file mode 100644 index 87756a3..0000000 --- a/contents/authors/brett.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "Brett Langdon", - "website": "http://brett.is", - "bio": "Brett is the breaker of things" -} diff --git a/contents/authors/colin.json b/contents/authors/colin.json deleted file mode 100644 index dc26fa2..0000000 --- a/contents/authors/colin.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "Colin Higgins", - "website": "http://spykebytes.me", - "bio": "" -} diff --git a/contents/css/main.css b/contents/css/main.css deleted file mode 100644 index 8067a57..0000000 --- a/contents/css/main.css +++ /dev/null @@ -1,426 +0,0 @@ - -h1, h2, h3, h4, h5, h6, p, body, a, img, ul, ol, blockquote, pre { - margin: 0; padding: 0; border: 0; -} - -body { - font-family: 'Lora', serif; - font-size: 21px; - line-height: 1.52; - background-color: #f8f8f8; - text-rendering: optimizeLegibility; -} - -.content-wrap { - width: 34em; - margin: 0 auto; -} - -body, a { - color: #171717; -} - -a:hover { - color: #ff8000; - text-decoration: underline; -} - -p { - margin-bottom: 1.52em; -} - -pre { - font-size: 0.9em; - overflow: auto; - background: #fff; - border: 1px dashed #d2d2d2; - border-radius: 0.25em; - margin-bottom: 1.8em; - padding: 1em; -} - -h1 { - font-size: 2em; - margin-bottom: 1em; -} - -h2 { - font-size: 1.2em; - font-weight: 600; - line-height: 1.43; - margin-bottom: 1.35em; -} - -h3 { - font-style: italic; - text-align: center; - font-weight: 400; - font-size: 1.4em; - margin-top: 1.8em; - margin-bottom: 0.8em; -} - -ol, ul { - margin: 0 1.4em 1.4em 4em; -} - -li { - margin-bottom: 0.5em; -} - -blockquote { - margin: 1.2em 3em; - padding-left: 1em; - font-style: italic; -} - -hr { - border: 0; - border-top: 1px dashed #d2d2d2; - height: 0; - margin: 1.6em 0; -} - -/* page header */ - -.header { - margin: 3em 0 5em; -} - -.header h1, .header .title { - font-size: 2.0em; - text-align: center; - font-weight: 700; - margin: 0; -} - -.header a, .header a:hover { - text-decoration: none; - color: #171717; -} - -.header .author { - font-family: 'Merriweather', serif; - font-variant: small-caps; - text-transform: lowercase; - text-rendering: auto; - text-align: center; - font-weight: 400; - letter-spacing: 1px; -} - -.header .description { - font-size: 1.2em; - font-style: italic; - text-align: center; - margin-top: -0.3em; -} - -body.article-detail > header h1 { - font-size: 2em; - font-style: italic; - font-weight: 400; - margin-bottom: -0.2em; -} - -body.article-detail > header { - margin-bottom: 3em; -} - -/* page footer */ - -footer { - margin: 3em 0; -} - -footer .nav { - text-align: center; - margin-top: 1em; - margin-bottom: 1em; -} - -footer .nav a { - padding: 0 0.5em; - font-size: 1.2em; - text-decoration: none; -} - -footer .about { - font-size: 0.7em; - text-align: center; -} - -footer .copy { - text-align: center; - font-size: 0.7em; - font-style: italic; - margin-top: 1em; -} - -footer .copy, footer .copy a { - color: #8e8e8e; -} - -/* article */ - -.article { - margin: 3em 0 4em; -} - -.article header { - border-top: 1px dashed #d2d2d2; -} - -.article header h2 { - font-style: italic; - text-align: center; - font-weight: 400; - margin: 0.8em 0; - font-size: 1.4em; -} - -.article header h2 a { - text-decoration: none; -} - -.article header .date { - text-align: center; - font-size: 0.8em; - margin-top: -0.7em; -} - -.article header .date span { - background-color: #f8f8f8; - padding: 0 0.7em; -} - -.article.intro .content p { - display: inline; -} - -.article.intro .content .more { - text-decoration: underline; - font-weight: 700; - padding-left: 0.3em; -} - -.article .content img { - display: block; - width: 100%; -} - -.more, .date { - font-family: 'Merriweather', serif; - font-variant: small-caps; - text-transform: lowercase; - font-weight: 400; - text-rendering: auto; - letter-spacing: 1px; -} - -/* archive */ - -.archive { - width: 32em; - margin: 5em auto 6em; - padding-left: 2em; -} - -.archive h2 { - font-size: 2em; - margin: 0; - margin-left: 6.1em; - margin-bottom: 0.5em; - font-style: italic; -} - -.archive a, .archive span{ - display: block; - float: left; - margin-bottom: -1px; - text-decoration: none; -} -.archive li:not(:last-child) { - border-bottom: 1px solid #d2d2d2; - margin-bottom: -1px; -} - -.archive a.last, .archive span.last { - border: 0; - margin-bottom: 0; -} - -.archive a { - width: 21em; - text-indent: 1em; - white-space: nowrap; -} - -.archive .year-label, -.archive .month-label{ - width: 4em; - font-family: 'Merriweather', serif; - font-variant: small-caps; - text-transform: lowercase; - font-weight: 400; - text-rendering: auto; - letter-spacing: 1px; - text-align: center; -} - -.archive .month-label { - width: 7em; -} - -.archive ul { - list-style: none; - margin: 0; -} - -.archive ul li { - margin: 0; -} - -/* code styling */ - -code { - font-family: 'Anonymous Pro', monospace; - font-size: 0.85em; - color: #000; -} - -pre code { - display: block; - line-height: 1.1; -} - -p code { - padding: 0.1em 0.3em 0.2em; - border-radius: 0.3em; - position: relative; - background: #fffff3; - - white-space: nowrap; -} - -/* syntax hl stuff */ - -code.lang-markdown { - color: #424242; -} - -code.lang-markdown .header, -code.lang-markdown .strong { - font-weight: bold; -} - -code.lang-markdown .emphasis { - font-style: italic; -} - -code.lang-markdown .horizontal_rule, -code.lang-markdown .link_label, -code.lang-markdown .code, -code.lang-markdown .header, -code.lang-markdown .link_url { - color: #555; -} - -code.lang-markdown .blockquote, -code.lang-markdown .bullet { - color: #bbb; -} - -/* Tomorrow Theme */ -/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ -/* Original theme - https://github.com/chriskempson/tomorrow-theme */ -/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ -.tomorrow-comment, pre .comment, pre .title { - color: #8e908c; -} - -.tomorrow-red, pre .variable, pre .attribute, pre .tag, pre .regexp, pre .ruby .constant, pre .xml .tag .title, pre .xml .pi, pre .xml .doctype, pre .html .doctype, pre .css .id, pre .css .class, pre .css .pseudo { - color: #c82829; -} - -.tomorrow-orange, pre .number, pre .preprocessor, pre .built_in, pre .literal, pre .params, pre .constant { - color: #f5871f; -} - -.tomorrow-yellow, pre .class, pre .ruby .class .title, pre .css .rules .attribute { - color: #eab700; -} - -.tomorrow-green, pre .string, pre .value, pre .inheritance, pre .header, pre .ruby .symbol, pre .xml .cdata { - color: #718c00; -} - -.tomorrow-aqua, pre .css .hexcolor { - color: #3e999f; -} - -.tomorrow-blue, pre .function, pre .python .decorator, pre .python .title, pre .ruby .function .title, pre .ruby .title .keyword, pre .perl .sub, pre .javascript .title, pre .coffeescript .title { - color: #4271ae; -} - -.tomorrow-purple, pre .keyword, pre .javascript .function { - color: #8959a8; -} - -/* media queries */ - -@media (min-width: 1600px) { - body { font-size: 26px; } -} - -@media (max-width: 900px) { - body { font-size: 18px; } -} - -@media (max-width: 690px) { - .content-wrap { - width: auto; - padding: 0 1em; - } - .header { - margin: 1em 0; - } - .header h1 { - font-size: 1.4em; - margin-bottom: 0.6em; - } - .header .description { - font-size: 1em; - } - .article { - margin: 1em 0 2.5em; - } - .archive { - width: 80%; - margin: 0 auto; - } - .archive * { - float: none !important; - line-height: 1.6 !important; - width: auto !important; - height: auto !important; - text-align: left !important; - border: 0 !important; - margin: 0 !important; - } - footer .nav { - margin: 1em 0; - } - footer .about { - padding: 0; - font-size: 0.9em; - padding-top: 1.6em; - -webkit-column-count: 1; - -moz-column-count: 1; - -ms-column-count: 1; - column-count: 1; - } - footer .about p { - margin-bottom: 1em; - } -} diff --git a/contents/feed.json b/contents/feed.json deleted file mode 100644 index 9c3d3fd..0000000 --- a/contents/feed.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "template": "feed.jade", - "filename": "feed.xml" -} diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html new file mode 100644 index 0000000..62cf120 --- /dev/null +++ b/layouts/_default/baseof.html @@ -0,0 +1,51 @@ + + + + {{ .Hugo.Generator }} + + + {{ block "title" . }}{{ .Title }} | {{ .Site.Title }}{{ end }} + {{ with .Description }} + + {{ end }} + {{ $default_noindex_kinds := slice "section" "taxonomy" "taxonomyTerm" }} + {{ $noindex_kinds := .Site.Params.noindex_kinds | default $default_noindex_kinds }} + {{ $is_noindex_true := and (isset .Params "noindex") .Params.noindex }} + {{ if or (in $noindex_kinds .Kind) ($is_noindex_true) }} + + {{ end }} + {{ partial "meta/name-author" . }} + {{ template "_internal/opengraph.html" . }} + {{ partial "meta/ogimage-maybe" . }} + {{ partial "meta/theme-color" . }} + {{ if eq .Kind "home" }} + {{ partial "site-verification" . }} + {{ end }} + {{ template "_internal/google_analytics_async.html" . }} + {{ if .RSSLink }} + + {{ end }} + + {{ if (isset .Params "prev") }} + + {{ end }} + {{ if (isset .Params "next") }} + + {{ end }} + {{ partial "favicon" . }} + {{ partial "critical-vendor.css" }} + {{ partial "critical-theme.css" }} + {{ partial "critical-custom.css" }} + {{ $lazylist := findRE "class=\".*?\\blazyload\\b.*?\"|class=lazyload\b" .Content }} + {{ if ge (len $lazylist) 1 }} + + {{ end }} + + {{ $theme_variant := .Site.Params.theme_variant | default "hack dark" }} + + +
{{ block "header" . }}{{ end }}
+
{{ block "main" . }}{{ end }}
+
{{ block "footer" . }}{{ end }}
+ + diff --git a/layouts/partials/critical-custom.css.html b/layouts/partials/critical-custom.css.html new file mode 100644 index 0000000..d9bd42a --- /dev/null +++ b/layouts/partials/critical-custom.css.html @@ -0,0 +1,16 @@ + diff --git a/layouts/post/single.html b/layouts/post/single.html new file mode 100644 index 0000000..8d437ba --- /dev/null +++ b/layouts/post/single.html @@ -0,0 +1,36 @@ +{{ define "header" }} + {{ partial "menu" . }} +{{ end }} +{{ define "main" }} +
+ {{ template "_internal/schema.html" . }} +
+

{{ .Title }}

+

{{ partial "post/meta" . }}

+
+ {{ if .Description }} +
{{ .Description }}
+ {{ end }} + {{ partial "toc-maybe" . }} +
+ {{ .Content }} +
+ {{ if .Site.DisqusShortname }} +
+ {{ template "_internal/disqus.html" . }} +
+ {{ end }} +
+
+ {{ partial "post/byline" . }} + {{ partial "post/related-content" . }} + + Creative Commons License + +
+
+{{ end }} +{{ define "footer" }} + {{ partial "powered-by" . }} +{{ end }} diff --git a/package.json b/package.json deleted file mode 100644 index 8be80d2..0000000 --- a/package.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "dependencies": { - "clean-css": "^2.2.16", - "moment": "2.3.x", - "typogr": "0.5.x", - "underscore": "1.4.x", - "wintersmith": "~2.1.x" - }, - "repository": "none" -} diff --git a/plugins/paginator.coffee b/plugins/paginator.coffee deleted file mode 100644 index a8ce516..0000000 --- a/plugins/paginator.coffee +++ /dev/null @@ -1,91 +0,0 @@ - -module.exports = (env, callback) -> - ### Paginator plugin. Defaults can be overridden in config.json - e.g. "paginator": {"perPage": 10} ### - - defaults = - template: 'index.jade' # template that renders pages - articles: 'articles' # directory containing contents to paginate - first: 'index.html' # filename/url for first page - filename: 'page/%d/index.html' # filename for rest of pages - perPage: 2 # number of articles per page - - # assign defaults any option not set in the config file - options = env.config.paginator or {} - for key, value of defaults - options[key] ?= defaults[key] - - getArticles = (contents) -> - # helper that returns a list of articles found in *contents* - # note that each article is assumed to have its own directory in the articles directory - articles = contents[options.articles]._.directories.map (item) -> item.index - # skip articles that does not have a template associated - articles = articles.filter (item) -> item.template isnt 'none' - # sort article by date - articles.sort (a, b) -> b.date - a.date - return articles - - class PaginatorPage extends env.plugins.Page - ### A page has a number and a list of articles ### - - constructor: (@pageNum, @articles) -> - - getFilename: -> - if @pageNum is 1 - options.first - else - options.filename.replace '%d', @pageNum - - getView: -> (env, locals, contents, templates, callback) -> - # simple view to pass articles and pagenum to the paginator template - # note that this function returns a funciton - - # get the pagination template - template = templates[options.template] - if not template? - return callback new Error "unknown paginator template '#{ options.template }'" - - # setup the template context - ctx = {@articles, @pageNum, @prevPage, @nextPage} - - # extend the template context with the enviroment locals - env.utils.extend ctx, locals - - # finally render the template - template.render ctx, callback - - # register a generator, 'paginator' here is the content group generated content will belong to - # i.e. contents._.paginator - env.registerGenerator 'paginator', (contents, callback) -> - - # find all articles - articles = getArticles contents - - # populate pages - numPages = Math.ceil articles.length / options.perPage - pages = [] - for i in [0...numPages] - pageArticles = articles.slice i * options.perPage, (i + 1) * options.perPage - pages.push new PaginatorPage i + 1, pageArticles - - # add references to prev/next to each page - for page, i in pages - page.prevPage = pages[i - 1] - page.nextPage = pages[i + 1] - - # create the object that will be merged with the content tree (contents) - # do _not_ modify the tree directly inside a generator, consider it read-only - rv = {pages:{}} - for page in pages - rv.pages["#{ page.pageNum }.page"] = page # file extension is arbitrary - rv['index.page'] = pages[0] # alias for first page - rv['last.page'] = pages[(numPages-1)] # alias for last page - - # callback with the generated contents - callback null, rv - - # add the article helper to the environment so we can use it later - env.helpers.getArticles = getArticles - - # tell the plugin manager we are done - callback() diff --git a/contents/images/2000px-Scrum_process.png b/static/images/2000px-Scrum_process.png similarity index 100% rename from contents/images/2000px-Scrum_process.png rename to static/images/2000px-Scrum_process.png diff --git a/contents/images/sprint-planning.png b/static/images/sprint-planning.png similarity index 100% rename from contents/images/sprint-planning.png rename to static/images/sprint-planning.png diff --git a/contents/images/triangles.jpg b/static/images/triangles.jpg similarity index 100% rename from contents/images/triangles.jpg rename to static/images/triangles.jpg diff --git a/templates/archive.jade b/templates/archive.jade deleted file mode 100644 index 8113b30..0000000 --- a/templates/archive.jade +++ /dev/null @@ -1,34 +0,0 @@ - -extends layout -//- this logic should be moved to a view at some point - -block content - - var lineHeight = 2.2; - - var archives = _.chain(env.helpers.getArticles(contents)).groupBy(function(item) { - - return item.date.getFullYear() - - }).value() - - for (var archive in archives) { - - archives[archive] = _.groupBy(archives[archive], function(item){return item.date.getMonth();}) - - } - - var month_names = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] - section.archive - h2 Archive - ul - - var yearsK = _.chain(archives).keys().reverse().value() - - for(var year in yearsK) - - months = archives[yearsK[year]] - - var yearHeight = lineHeight * _.reduce(months, function(memo,month) { return memo + month.length; }, 0); - li - span.year-label(style='line-height:' + yearHeight+'em')=yearsK[year] - ul(style='margin-left:4em') - - var monthsK = _.chain(months).keys().reverse().value() - - for(month in monthsK){ - - var monthHeight = lineHeight * months[monthsK[month]].length - li - span.month-label(style='line-height:'+monthHeight+'em')=month_names[monthsK[month]] - ul(style='margin-left:7em') - each item in months[monthsK[month]] - li(style='height:'+ lineHeight + 'em;line-height:'+ lineHeight + 'em;') - a(href=item.url)=item.title - - } - \ No newline at end of file diff --git a/templates/article.jade b/templates/article.jade deleted file mode 100644 index 4ace439..0000000 --- a/templates/article.jade +++ /dev/null @@ -1,26 +0,0 @@ -include mixins/disqus -extends layout - -block append vars - - bodyclass = 'article-detail' - -block prepend title - | #{ page.title + " - "} - -block append header - include author - h1= page.title - p.author - | #{ "Written by " } - mixin author(page.metadata.author) - -block content - article.article - section.content!= typogr(page.html).typogrify() - - section.comments - +disqus - -block prepend footer - div.nav - a(href=contents.index.url) « Home diff --git a/templates/author.jade b/templates/author.jade deleted file mode 100644 index ab7c9a5..0000000 --- a/templates/author.jade +++ /dev/null @@ -1,8 +0,0 @@ - -mixin author(authorName) - - var author = contents.authors[authorName + '.json'] - span.author - if author - a(href=author.metadata.website)= author.metadata.name - else - =authorName diff --git a/templates/feed.jade b/templates/feed.jade deleted file mode 100644 index 19f0343..0000000 --- a/templates/feed.jade +++ /dev/null @@ -1,25 +0,0 @@ -doctype xml -rss(version='2.0', - xmlns:content='http://purl.org/rss/1.0/modules/content/', - xmlns:wfw='http://wellformedweb.org/CommentAPI/', - xmlns:dc='http://purl.org/dc/elements/1.1/' - xmlns:atom='http://www.w3.org/2005/Atom') - channel - - var articles = env.helpers.getArticles(contents); - title= locals.name - atom:link(href=locals.url + '/feed.xml', rel='self', type='application/rss+xml') - link= locals.url - description= locals.description - pubDate= articles[0].rfc822date - generator Wintersmith - https://github.com/jnordberg/wintersmith - language en - for article in articles - - var permalink = locals.url + article.url - item - title= article.title - link= permalink - pubDate= article.rfc822date - guid(isPermaLink='true')= permalink - author= article.author - //- passing locals.url resolves all relative urls to absolute - description= article.getHtml(locals.url) diff --git a/templates/index.jade b/templates/index.jade deleted file mode 100644 index 81aed0c..0000000 --- a/templates/index.jade +++ /dev/null @@ -1,29 +0,0 @@ -extends layout - -block content - include author - each article in articles - article.article.intro - header - p.date - span= moment.utc(article.date).format('DD. MMMM YYYY') - h2 - a(href=article.url)= article.title - section.content - if article.intro.length > 0 - | !{ typogr(article.intro).typogrify() } - if article.hasMore - p.more - a(href=article.url) more - -block prepend footer - div.nav - if prevPage - a(href=prevPage.url) « Newer - else - a(href='/archive.html') « Archives - if nextPage - a(href=nextPage.url) Next page » - - - diff --git a/templates/layout.jade b/templates/layout.jade deleted file mode 100644 index f0cf4bc..0000000 --- a/templates/layout.jade +++ /dev/null @@ -1,45 +0,0 @@ -doctype html -block vars - - var bodyclass = null; -html(lang='en') - head - block head - meta(charset='utf-8') - meta(http-equiv='X-UA-Compatible', content='IE=edge,chrome=1') - meta(name='viewport', content='width=device-width') - title - block title - = locals.name - link(rel='alternate', href=locals.url+'/feed.xml', type='application/rss+xml', title=locals.description) - link(rel='stylesheet', href='http://fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic|Anonymous+Pro:400,700,400italic,700italic|Merriweather:400,700,300') - link(rel='stylesheet', href='/css/main.min.css') - body(class=bodyclass) - header.header - div.content-wrap - block header - div.logo - h1.title - a(href=locals.url)= locals.name - p.description= locals.description - div#content - div.content-wrap - block content - h2 Welcome to The Worst Programmer Ever! - footer - div.content-wrap - block footer - section.about - !=contents['about.md'].html - section.copy - p © #{ new Date().getFullYear() } #{ locals.owner } — powered by  - a(href='https://github.com/jnordberg/wintersmith') Wintersmith - //- please leave the "powered by" if you use the design - script(type='text/javascript'). - (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ - (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), - m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) - })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); - ga('create', 'UA-43062483-1', 'auto'); - ga('send', 'pageview'); - a(href="https://github.com/brettlangdon/theworstprogrammerever", target="_blank") - img(style="position: absolute; top: 0; left: 0; border: 0;", src="https://camo.githubusercontent.com/567c3a48d796e2fc06ea80409cc9dd82bf714434/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f6c6566745f6461726b626c75655f3132313632312e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_left_darkblue_121621.png") diff --git a/templates/mixins/disqus.jade b/templates/mixins/disqus.jade deleted file mode 100644 index d07ceb7..0000000 --- a/templates/mixins/disqus.jade +++ /dev/null @@ -1,18 +0,0 @@ -mixin disqus - #disqus_thread - script(type="text/javascript"). - var disqus_shortname = 'theworstprogrammerever'; - var disqus_identifier = 'http://theworstprogrammerever.com#{page.url}'; - var disqus_title = '#{page.title}'; - var disqus_url = "http://theworstprogrammerever.com#{page.url}"; - (function() { - var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true; - dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js'; - (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq); - })(); - noscript - | Please enable JavaScript to view the - a(href="http://disqus.com/?ref_noscript")=" comments powered by Disqus." - a(href="http://disqus.com").dsq-brlink - | comments powered by - span.logo-disqus=" Disqus" diff --git a/themes/hugo-after-dark/.gitignore b/themes/hugo-after-dark/.gitignore new file mode 100644 index 0000000..646ac51 --- /dev/null +++ b/themes/hugo-after-dark/.gitignore @@ -0,0 +1,2 @@ +.DS_Store +node_modules/ diff --git a/themes/hugo-after-dark/CHANGELOG.md b/themes/hugo-after-dark/CHANGELOG.md new file mode 100644 index 0000000..f728a82 --- /dev/null +++ b/themes/hugo-after-dark/CHANGELOG.md @@ -0,0 +1,33 @@ +# Change Log + +All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. + + +# [1.2.0](https://github.com/comfusion/after-dark/compare/v1.1.0...v1.2.0) (2017-03-30) + + +### Features + +* **highlighting:** add syntax highlighting ([455062f](https://github.com/comfusion/after-dark/commit/455062f)) +* **shortcodes:** add figure shortcode ([8a0317f](https://github.com/comfusion/after-dark/commit/8a0317f)) + + + + +# [1.1.0](https://github.com/comfusion/after-dark/compare/v1.0.0...v1.1.0) (2017-03-30) + + +### Features + +* **shortcodes:** add blockquote shortcode ([ea293e3](https://github.com/comfusion/after-dark/commit/ea293e3)) + + + + +# 1.0.0 (2017-03-30) + + +### Bug Fixes + +* 404 page theme color url ref ([79d2377](https://github.com/comfusion/after-dark/commit/79d2377)) +* add add theme color to 404 page ([4f5ec87](https://github.com/comfusion/after-dark/commit/4f5ec87)) diff --git a/themes/hugo-after-dark/LICENSE b/themes/hugo-after-dark/LICENSE new file mode 100644 index 0000000..72878ea --- /dev/null +++ b/themes/hugo-after-dark/LICENSE @@ -0,0 +1,7 @@ +ISC License (ISC) + +Copyright 2017 Josh Habdas + +Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/themes/hugo-after-dark/README.md b/themes/hugo-after-dark/README.md new file mode 100644 index 0000000..2b511c5 --- /dev/null +++ b/themes/hugo-after-dark/README.md @@ -0,0 +1,504 @@ +

After Dark

+ +

+ A simple, yet highly configurable responsive dark theme for the Hugo static site generator. +

+ +After Dark theme screenshots + +

+ NPM downloads per month + Latest NPM version + Project license +

+ +## Features + +
+ + View the full list of features + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureSummary
Deceptive SimplicityAfter Dark is a Hugo theme, making it a suitable starting point for novice and advanced developers alike. It advances using the "Code for today, not for tomorrow" philosophy of XP, and includes only what's necessary to create and run your site – nothing more.
Semantic VersioningPredictable changes enable theme users stay up-to-date with what's happening. After Dark uses Semantic Versioning and maintains a CHANGELOG for easy consumption.
Inclusive DesignOptimized for mobile, tablet, desktop and terminal browsers.
Performance OptimizedPage content and styles load in a single request on all pages. External resources, if present, are loaded asynchronously, and only when necessary. This keeps pages zippy, and affords ~1 second page loads over 2G when hosted using a CDN.
Vertical ScalingAfter Dark is capable of generating ~1000 pages per second thanks to Hugo, and is likely to become faster over time.
Search AwarenessUsing Schema Structured Data and meta tags, After Dark gives crawlers rich data about the site structure, page and page author. No configuration required.
Social AwarenessAfter Dark provides automatic and configurable OpenGraph support, making social shares pop like 37 pieces of flair.
PersonalizationNot completely satisfied with the default look-and-feel? Customize the theme to your liking using one of the available theme variants provided by hack.css.
Section MenuAdd and customize your site's global navigation. After Dark uses Hugo's Section Menu for "the Lazy Blogger", making navigation easy to create and predictable to use. Don't want navigation? Simply disable it from your site configuration.
Intelligent LazyloadingLazyload your images, iFrames and script embeds. After Dark uses the lazysizes library, a zero-configuration JavaScript library with support for LQIP and responsive images.
Related ContentPromote more of your content to your site visitors. By offering your readers more content that's relevant to them you can increase your site's page views, the time spent on your site and reader loyalty.
Table Of ContentsHelp users locate and share information on your site. By providing a TOC, users will spend less time scrolling to locate information in larger documents, and are more likely to deep link to specific information on a page.
AnalyticsUnderstand and action on user behavior by enabling Google Analytics. After Dark uses the async tracking snippet to boost performance and allow script preloading.
User Generated ContentImprove search rankings and provide interactivity to users with UGC. Enable Disqus commenting to get started.
Reading TimeSet user expectations up-front. After Dark provides estimated reading time for each post near the top of the page. This feature is automatic and assumes a reading speed of 200-250 words per minute.
Modification DatingSurface recently updated content to users and crawlers, allowing them to understand when a post or page was was last modified. Recently updated posts will be flagged as modified, and visually lifted upwards in chronological listings.
Syntax HighlightingShare code snippets with style. After Dark provides opt-in syntax highlighting with support for line numbers and highlighted lines.
Taxonomy PagesHelp users discover taxonomic content. After Dark automatically generates taxonomy and taxonomy terms pages, and links to them in post bylines.
Post BylinesRich post bylines include optional author name, word count, links to taxonomy pages and metadata for search engines.
PaginationPagination can be hard. After Dark makes it easy with simple list pagination with page indication.
Animated Error PageDecrease bounce rate when URL errors occur. After Dark provides an engaging 404 page with animated background.
AccessibilityAfter Dark uses semantic HTML5 markup to provide a better experience for aural readers and facilitates navigation via keyboard only.
+
+ +## Demo & Tutorial + +Head to [Hack Cabin](https://hackcabin.com) for a **live example** running on AWS and learn more about the [site architecture](https://hackcabin.com/post/initial-commit/). I've also written a [step-by-step guide](http://go.habd.as/zero-to-http-2) to hosting After Dark on Amazon, which includes a **free year of hosting**. For cloud hosting using a VPS, [Vultr](http://go.habd.as/2oiL54G) and [DigitalOcean](http://go.habd.as/2oDN04T) are options. + +## Getting Started + +[Install Hugo](https://gohugo.io/#action) on your machine and use it to create a new site. Instructions for [Homebrew](https://brew.sh/) on macOS: + +```shell +brew install hugo +hugo new site flying-toasters && cd $_ +``` + +Clone After Dark and use it to serve your site: + +```shell +(cd themes; git clone https://github.com/comfusion/after-dark) +hugo serve --theme=after-dark +``` + +Copy custom archetypes to your site: + +```shell +cp themes/after-dark/archetypes/* archetypes +``` + +Finally, include the settings in your site's `config.toml`: + +```toml +baseurl = "https://c74ce35e.ngrok.io" # Controls base URL +languageCode = "en-US" # Controls html lang attribute +title = "After Dark" # Homepage title and page title suffix +paginate = 5 # Number of posts to show before paginating + +# theme = "after-dark" # Uncomment to use as default theme + +enableRobotsTXT = true # Suggested, enable robots.txt file +googleAnalytics = "" # Optional, add tracking Id for analytics +disqusShortname = "" # Optional, add Disqus shortname for comments +SectionPagesMenu = "main" # Enable menu system for lazy bloggers +footnoteReturnLinkContents = "↩" # Provides a nicer footnote return link + +[params] + description = "" # Suggested, controls default description meta + author = "" # Optional, controls author name display on posts + hide_author = false # Optional, set true to hide author name on posts + show_menu = false # Optional, set true to enable section menu + powered_by = true # Optional, set false to disable credits + images = [] # Suggested, controls default OpenGraph images + theme_variant = "" # Optional, for use to overriding default theme +``` + +That's it! Everything else is optional. Read on to learn how to configure specific features and customize the theme. + +## Customizing + +### Section Menu + +Theme uses [Section Menu for Lazy Bloggers](https://gohugo.io/extras/menus/#section-menu-for-the-lazy-blogger) to produce global site navigation, if enabled. + +To customize the menu, update the settings in `config.toml` like: + +```toml +[[menu.main]] + name = "Home" + weight = 1 + identifier = "home" + url = "/" +[[menu.main]] + name = "Posts" + weight = 2 + identifier = "post" + url = "/post/" +``` + +Or update the menu using front matter from your pages: + +```toml +menu = "main" +weight = 3 +``` + +### Intelligent Lazyloading + +Lazyloading prioritizes when and how images and more are downloaded, improving perceived performance and reducing page load times. When activated, lazyloading will start working automatically. No JavaScript configuration is necessary. + +**What makes it _Intelligent_?** If no lazyloaded content is detected on a page when the site is generated, the feature will not be activated and no additional downloads will occur. + +To activate lazyloading with [lazysizes], add `lazyload` to the `class` attribute of your images/iframes in conjunction with a `data-src` and/or `data-srcset` attribute: + +```html + + +``` + +```html + + +``` + +```html + + +``` + +Additional information and examples, including how to set-up and use LQIP (Low-Quality Image Placeholders), are available on the [lazysizes] repository on GitHub. + +### Related Content + +Promote more of your content to your site visitors. By offering your readers more content that's relevant to them you can increase your site's page views, the time spent on your site and reader loyalty. + +Related content surfaces content across sections by matching taxonomy tags. If After Dark finds related content it will automatically output a list of links to that content in reverse chronological order below the byline of your post content. + +By default After Dark will display up to 7 items by title along with their reading times. You can limit the number of items displayed by setting the following optional parameter in the `[params]` section of your `config.toml` file: + +```toml +related_content_limit = 5 +``` + +### Table Of Contents + +Help users locate and share information on your site. By providing a TOC, users will spend less time scrolling to location information in larger documents, and are more likely to deep to specific information on a page. + +To automatically generate a TOC for a post based on the [page outline](https://gsnedders.html5.org/outliner/), add the following to your post front matter: + +```toml +toc = true +``` + +To hide the TOC set `toc = false`, or simply remove the setting from the post front matter. + +After Dark uses the HTML5 [`details`](http://devdocs.io/html/element/details) and [`summary`](http://devdocs.io/html/element/summary) elements to provide a TOC which does not require use of CSS or JavaScript to function. + +When a page is first loaded, the TOC will be collapsed so it does not clutter up the page. Once expanded, selecting an item in the TOC will smooth scroll to that section within the document, highlight the section header and updating the browser's location bar for deep linking and back-button support. + +### OpenGraph + +After Dark leverages OpenGraph tags using the *undocumented* [internal template](https://github.com/spf13/hugo/blob/95ad3ad2fa3e6f4514166b47b77f051d280c16e9/tpl/template_embedded.go#L161-L204) to achieve rich sharing cards for Facebook and other social networks, as shown here: + +![OpenGraph image with author attribution](https://cloud.githubusercontent.com/assets/440298/22554715/156ba7f0-e99c-11e6-9d5b-14f0ac4fe496.png) + +Specify `author` in `config.toml` and, optionally, override it from your post front matter: + +```toml +title = "Become a Digital Nomad in Bali: The Lost Guide" +description = "Everything you need to know to become a Digital Nomad in Bali." +author = "After Dark" +date = "2017-02-02T11:57:24+08:00" +publishdate = "2017-01-28T02:31:22+08:00" +images = [ + "https://source.unsplash.com/-09QE4q0ezw/2000x1322" +] +``` + +To configure a site-wide OpenGraph images and fallbacks for posts not specifying their own, add the following to your site parameters in `config.toml` in the `[params]` section: + +```toml +images = [ + "https://source.unsplash.com/-09QE4q0ezw/2000x1322" # Default OpenGraph image for site +] +``` + +Test how things are looking during development using a combination of the [Facebook Sharing Debugger](https://developers.facebook.com/tools/debug/) and [ngrok](https://ngrok.com/). + +### SEO and UX + +After Dark is built with SEO in mind. Aside from OpenGraph, Schema Structured Data and SEO meta is applied to give robots what they want, automatically, without any user configuration necessary. This helps ensure your After Dark site will rank well in Search Engine Results Pages (SERPs) and prevent crawlers from indexing undesirable content. + +Fine-tune your SEO settings using the following available options. + +### Webmaster Verification + +Verify your site with several webmaster tools including Google, Bing, Alexa and Yandex. To allow verification of your site with any or all of these providers simply add the following to your `config.toml` and fill in their respective values: + +```toml +[params.seo.webmaster_verifications] + google = "" # Optional, Google verification code + bing = "" # Optional, Bing verification code + alexa = "" # Optional, Alexa verification code + yandex = "" # Optional, Yandex verification code +``` + +**Note:** Claiming your site with Alexa was [retired in May 2016](https://support.alexa.com/hc/en-us/articles/219135887-Claiming-has-been-retired-May-2016). However, Alexa verification has been added as a convenience for existing sites migrating to After Dark. + +### Meta Descriptions + +Well-crafted page titles help catch the human eye on search results pages. And meta descriptions provide a summary of the content and why its relevant for the reader, driving click-throughs. + +To add a custom meta description to your pages and posts add `description` to the front matter: + +```toml +description = "Everything you need to know to become a Digital Nomad in Bali." +``` + +In addition to appearing in search engines, meta descriptions also appear on individual pages and in content summaries in After Dark, adding transparency to how your page will appear in search. + +If no custom description is provided After Dark will fallback to the description provided in `config.toml`. Learn more on [how to craft your meta descriptions](https://moz.com/learn/seo/meta-description). + +### Modification Dating + +Help user agents know when posts were last modified. To do so add `publishdate` to your page front matter and update `date` anytime you make an update to a post. + +Updates will be made visible to readers by surfacing content higher in your page and post listings, and using using visible callouts on content summaries. For robots, making this change will automatically update Schema Structured Data and Web feeds, as well as the `lastmod` setting your `sitemap.xml` file. + +You can be specific and use a datetime (with timezone offset) like: + +``` +date = "2017-02-02T01:20:56-06:00" +publishdate = "2016-11-21T10:32:33+08:00" +``` + +Or less specific and use just the dates: + +``` +date = "2017-02-02" +publishdate = "2016-11-21" +``` + +Review the W3C website for more [information on dates and times](https://www.w3.org/TR/html51/infrastructure.html#dates-and-times) for the Web infrastructure. + +### Link Types + +For related content split across multiple pages in a sequence After Dark supports use of `prev` and `next` settings in your front matter. + +Learn more about [link types](http://devdocs.io/html/link_types). + +### Index Blocking + +Just because a page appears in your `sitemap.xml` does not mean you want it to appear in a SERP. Examples of pages which will appear in your `sitemap.xml` that you typically do not want indexed by crawlers include error pages, search pages, legal pages, and pages that simply list summaries of other pages. + +Though it's possible to block search indexing from a `robots.txt` file, After Dark makes it possible to block page indexing using Hugo configuration as well. By default the following page types will be blocked: + +- Section Pages (e.g. Post listings) +- Taxonomy Pages (e.g. Category and Tag listings) +- Taxonomy Terms Pages (e.g. Pages listing taxonomies) + +To customize default blocking configure the `noindex_kinds` setting in the `[params]` section of your `config.toml`. For example, if you want to enable crawling for sections appearing in [Section Menu](#adding-a-section-menu) add the following to your configuration file: + +``` +[params] + noindex_kinds = [ + "taxonomy", + "taxonomyTerm" + ] +``` + +To block individual pages from being indexed add `nofollow` to your page's front matter and set the value to `true`, like: + +```toml +noindex = true +``` + +And, finally, if you're using Hugo `v0.18` or better, you can also add an `_index.md` file with the `noindex` front matter to control indexing for specific section list layouts: + +```shell +├── content +│ ├── modules +│ │ ├── starry-night.md +│ │ └── flying-toilets.md +│ └── news +│ ├── _index.md +│ └── return-flying-toasters.md +``` + +To learn more about how crawlers use this feature read [block search indexing with meta tags](https://support.google.com/webmasters/answer/93710). + +### Markdown Output + +Gain more control over markdown conversion to HTML. By modifying the markdown processor settings you can take advantage of [Blackfriday](https://github.com/russross/blackfriday) features not enabled by default. + +To customize conversion output add a `[blackfriday]` section to your site's `config.toml` file like so: + +```toml +[blackfriday] + hrefTargetBlank = true + fractions = false +``` + +Overrides to theme markdown processing defaults are available from page front matter as well, giving you control on a page-by-page basis. + +See the Hugo docs for additional [configuration options](http://gohugo.io/overview/configuration/#configure-blackfriday-rendering). + +### Shortcodes + +Keep your content DRY and improve thematic consistency across your site. To help achieve this, Hugo provides [Shortcodes](https://gohugo.io/extras/shortcodes). + +Shortcodes are very powerful, and can be used to achieve functionality not otherwise available in the markdown processor. Hugo provides a number of [built-in shortcodes](https://gohugo.io/extras/shortcodes#built-in-shortcodes) you can use on your site. And After Dark provides some as well. + +Here's the `blockquote` shortcode provided by After Dark: + +```html +
+ {{ .Inner }} + {{ with .Get "citelink" }} + {{ $.Get "cite" }} + {{ else }} + {{ .Get "cite" }} + {{ end }} +
+``` + +Use it in your markdown files like: + +```html +{{< blockquote cite="Bitly" citelink="https://bitly.is/2mkxskj" >}} +

When you create your own Branded Short Domain, you can expect to see up to a 34% increase in CTR when compared to standard bit.ly links.

+{{< /blockquote >}} +``` + +Additional theme-provided shortcodes at your disposal: + +- `figure` - Similar to the Hugo built-in, but with [Intelligent Lazyloading](#intelligent-lazyloading), an adjusted caption title and smaller caption text. + +To create your own custom shortcodes add a `layouts/shortcodes` directory to your site, place your shortcodes within and start using them in your markdown content. + +Reference the Hugo docs for [shortcode usage instructions](https://gohugo.io/extras/shortcodes#using-a-shortcode). + +### Syntax Highlighting + +Provide a richer experience when sharing code snippets on your site. After Dark provides support for code highlighting using the lovely [One Dark](https://github.com/atom/one-dark-syntax) or [One Light](https://github.com/atom/one-light-syntax) syntax themes used in [Atom](https://github.com/atom/atom). + +**Why not use Highlight.js?** Because it's slow, doesn't support line numbers or highlighting of individual lines. In addition, JS-based solutions force browsers to do the same work over and over when that work can be done once during site generation. + +To set-up syntax highlighting for your After Dark site: + +- Follow Hugo's [Pygments installation](https://gohugo.io/extras/highlighting/#pygments) instructions. +- Open the `themes/after-dark` folder and run `npm i` (assumes NPM installed) +- Then open `./node_modules/atom-one-pygments` and `npm i` +- Once dependencies are installed, issue `npm run build` to generate the stylesheets to the `./dist` directory + +Then choose either `./dist/light.css` or `dark.css` depending on your [Theme Variant](#theme-variants), and copy the contents of the file into your [Custom CSS](#custom-css) file. + +Once configured, syntax highlighting can be achieved using the Hugo built-in [`highlight` shortcode](https://gohugo.io/extras/shortcodes#highlight). Reference Hugo's Syntax Highlighting docs for [additional usage instructions](https://gohugo.io/extras/highlighting/#usage). + +### Custom CSS + +To add your own theme css or override existing CSS without having to change theme files do the following: + +1. Create a `critical-custom.css.html` in your site's `layouts/partials directory`. +1. Add your customizations inside a `style` element. + +Example customization file: + +```html + +``` + +Your customizations will automatically be added to generated pages, inline in the document `HEAD`. Thanks to [@rsommerard](https://github.com/rsommerard) for making the suggestion. + +### Theme Variants + +[`hack.css`](http://hackcss.com/) provides a few variants you may wish to use instead of the After Dark defaults. To download them do an `npm i` from `/themes/after-dark/` (assumes NPM installed). + +Once downloaded, open `node_modules/hack/dist` directory and replace the CSS contents of `critical-vendor.css.html` with those you wish to use, updating the `theme_variant` setting in the site configuration like: + + theme_variant = "standard dark-grey" + +**Why not use external CSS files?** After Dark is optimized for speed, and, as a result, limits the number of HTTP requests whenever possible. This just so happens to be of those occasions. + +Once the vendor file is updated, open your favorite dev tools and test the changes by previewing your site on mobile, tablet and desktop at different display resolutions and orientations, making any tweaks necessary to `critical-theme.css.html`. + +And, finally, adjust your [Customized CSS](#custom-css), 404 page and `/meta/theme-color` as necessary. + +## Contributing + +If you've spotted a bug or would like to make an enhancement suggestion, please [open an issue on GitHub](https://github.com/comfusion/after-dark/issues). Build something awesome with After Dark? [Add it to the wiki](https://github.com/comfusion/after-dark/wiki) for others to see. For general questions or support, please feel free to reach out to me directly at: [https://habd.as/contact](https://habd.as/contact). Thanks! + +## License + +[ISC](https://github.com/comfusion/after-dark/blob/master/LICENSE) + +[lazysizes]: https://github.com/aFarkas/lazysizes diff --git a/themes/hugo-after-dark/archetypes/default.md b/themes/hugo-after-dark/archetypes/default.md new file mode 100644 index 0000000..bb378b3 --- /dev/null +++ b/themes/hugo-after-dark/archetypes/default.md @@ -0,0 +1,3 @@ ++++ +description = "" ++++ diff --git a/themes/hugo-after-dark/archetypes/post.md b/themes/hugo-after-dark/archetypes/post.md new file mode 100644 index 0000000..8a4b38e --- /dev/null +++ b/themes/hugo-after-dark/archetypes/post.md @@ -0,0 +1,6 @@ ++++ +description = "" +draft = true +categories = [""] +tags = ["", ""] ++++ diff --git a/themes/hugo-after-dark/images/design/dark_code_editor_window.sketch b/themes/hugo-after-dark/images/design/dark_code_editor_window.sketch new file mode 100755 index 0000000..52c74b3 Binary files /dev/null and b/themes/hugo-after-dark/images/design/dark_code_editor_window.sketch differ diff --git a/themes/hugo-after-dark/images/design/minimalMacbook.sketch b/themes/hugo-after-dark/images/design/minimalMacbook.sketch new file mode 100644 index 0000000..ad40dff Binary files /dev/null and b/themes/hugo-after-dark/images/design/minimalMacbook.sketch differ diff --git a/themes/hugo-after-dark/images/minimal-mac.png b/themes/hugo-after-dark/images/minimal-mac.png new file mode 100644 index 0000000..89b69d8 Binary files /dev/null and b/themes/hugo-after-dark/images/minimal-mac.png differ diff --git a/themes/hugo-after-dark/images/screenshot.png b/themes/hugo-after-dark/images/screenshot.png new file mode 100644 index 0000000..4db063e Binary files /dev/null and b/themes/hugo-after-dark/images/screenshot.png differ diff --git a/themes/hugo-after-dark/images/terminal.png b/themes/hugo-after-dark/images/terminal.png new file mode 100644 index 0000000..557a5c2 Binary files /dev/null and b/themes/hugo-after-dark/images/terminal.png differ diff --git a/themes/hugo-after-dark/images/tn.png b/themes/hugo-after-dark/images/tn.png new file mode 100644 index 0000000..6db6a8a Binary files /dev/null and b/themes/hugo-after-dark/images/tn.png differ diff --git a/themes/hugo-after-dark/layouts/404.html b/themes/hugo-after-dark/layouts/404.html new file mode 100644 index 0000000..d110b21 --- /dev/null +++ b/themes/hugo-after-dark/layouts/404.html @@ -0,0 +1,100 @@ + + {{ .Hugo.Generator }} + + + + 404 Error | {{ .Site.Title }} + {{ partial "favicon" . }} + {{ partial "meta/theme-color" . }} + {{ template "_internal/google_analytics_async.html" . }} + + + + +
+ +

404

+
+
+ + diff --git a/themes/hugo-after-dark/layouts/_default/baseof.html b/themes/hugo-after-dark/layouts/_default/baseof.html new file mode 100644 index 0000000..dcf38e7 --- /dev/null +++ b/themes/hugo-after-dark/layouts/_default/baseof.html @@ -0,0 +1,50 @@ + + + + {{ .Hugo.Generator }} + + + {{ block "title" . }}{{ .Title }} | {{ .Site.Title }}{{ end }} + {{ with .Description }} + + {{ end }} + {{ $default_noindex_kinds := slice "section" "taxonomy" "taxonomyTerm" }} + {{ $noindex_kinds := .Site.Params.noindex_kinds | default $default_noindex_kinds }} + {{ $is_noindex_true := and (isset .Params "noindex") .Params.noindex }} + {{ if or (in $noindex_kinds .Kind) ($is_noindex_true) }} + + {{ end }} + {{ partial "meta/name-author" . }} + {{ template "_internal/opengraph.html" . }} + {{ partial "meta/ogimage-maybe" . }} + {{ partial "meta/theme-color" . }} + {{ if eq .Kind "home" }} + {{ partial "site-verification" . }} + {{ end }} + {{ template "_internal/google_analytics_async.html" . }} + {{ if .RSSLink }} + + {{ end }} + + {{ if (isset .Params "prev") }} + + {{ end }} + {{ if (isset .Params "next") }} + + {{ end }} + {{ partial "favicon" . }} + {{ partial "critical-vendor.css" }} + {{ partial "critical-theme.css" }} + {{ partial "critical-custom.css" }} + {{ $lazylist := findRE "class=\".*?\\blazyload\\b.*?\"|class=lazyload\b" .Content }} + {{ if ge (len $lazylist) 1 }} + + {{ end }} + + {{ $theme_variant := .Site.Params.theme_variant | default "hack dark" }} + +
{{ block "header" . }}{{ end }}
+
{{ block "main" . }}{{ end }}
+
{{ block "footer" . }}{{ end }}
+ + diff --git a/themes/hugo-after-dark/layouts/_default/list.html b/themes/hugo-after-dark/layouts/_default/list.html new file mode 100644 index 0000000..3b6ecc1 --- /dev/null +++ b/themes/hugo-after-dark/layouts/_default/list.html @@ -0,0 +1,15 @@ +{{ define "header" }} + {{ partial "menu" . }} +{{ end }} +{{ define "main" }} +
+

{{ .Title }}

+
+ {{ range .Paginator.Pages }} + {{ partial "page-summary" . }} + {{ end }} +{{ end }} +{{ define "footer" }} + {{ partial "pagination" . }} + {{ partial "powered-by" . }} +{{ end }} diff --git a/themes/hugo-after-dark/layouts/_default/single.html b/themes/hugo-after-dark/layouts/_default/single.html new file mode 100644 index 0000000..831d523 --- /dev/null +++ b/themes/hugo-after-dark/layouts/_default/single.html @@ -0,0 +1,15 @@ +{{ define "title" -}} + {{ .Title }} | {{ .Site.Title }} +{{- end }} +{{ define "header" }} + {{ partial "menu" . }} +{{ end }} +{{ define "main" }} +
+

{{ .Title }}

+
+ {{ .Content }} +{{ end }} +{{ define "footer" }} + {{ partial "powered-by" . }} +{{ end }} diff --git a/themes/hugo-after-dark/layouts/_default/taxonomy.html b/themes/hugo-after-dark/layouts/_default/taxonomy.html new file mode 100644 index 0000000..3b6ecc1 --- /dev/null +++ b/themes/hugo-after-dark/layouts/_default/taxonomy.html @@ -0,0 +1,15 @@ +{{ define "header" }} + {{ partial "menu" . }} +{{ end }} +{{ define "main" }} +
+

{{ .Title }}

+
+ {{ range .Paginator.Pages }} + {{ partial "page-summary" . }} + {{ end }} +{{ end }} +{{ define "footer" }} + {{ partial "pagination" . }} + {{ partial "powered-by" . }} +{{ end }} diff --git a/themes/hugo-after-dark/layouts/_default/terms.html b/themes/hugo-after-dark/layouts/_default/terms.html new file mode 100644 index 0000000..d54f6f7 --- /dev/null +++ b/themes/hugo-after-dark/layouts/_default/terms.html @@ -0,0 +1,16 @@ +{{ define "header" }} + {{ partial "menu" . }} +{{ end }} +{{ define "main" }} +
+

{{ .Title }}

+
+
    + {{ range $key, $value := .Data.Terms }} +
  • {{ $key }} ({{ len $value }}) + {{ end }} +
+{{ end }} +{{ define "footer" }} + {{ partial "powered-by" . }} +{{ end }} diff --git a/themes/hugo-after-dark/layouts/index.html b/themes/hugo-after-dark/layouts/index.html new file mode 100644 index 0000000..fe15cd6 --- /dev/null +++ b/themes/hugo-after-dark/layouts/index.html @@ -0,0 +1,18 @@ +{{ define "title" -}} + {{ .Site.Title }} +{{- end }} +{{ define "header" }} + {{ partial "menu" . }} +{{ end }} +{{ define "main" }} +
+

{{ .Title }}

+
+ {{ range (.Paginate (where .Data.Pages "Type" "post")).Pages }} + {{ partial "page-summary" . }} + {{ end }} +{{ end }} +{{ define "footer" }} + {{ partial "pagination" . }} + {{ partial "powered-by" . }} +{{ end }} diff --git a/themes/hugo-after-dark/layouts/partials/critical-custom.css.html b/themes/hugo-after-dark/layouts/partials/critical-custom.css.html new file mode 100644 index 0000000..79f9409 --- /dev/null +++ b/themes/hugo-after-dark/layouts/partials/critical-custom.css.html @@ -0,0 +1,3 @@ + diff --git a/themes/hugo-after-dark/layouts/partials/critical-theme.css.html b/themes/hugo-after-dark/layouts/partials/critical-theme.css.html new file mode 100644 index 0000000..e14745c --- /dev/null +++ b/themes/hugo-after-dark/layouts/partials/critical-theme.css.html @@ -0,0 +1,59 @@ + diff --git a/themes/hugo-after-dark/layouts/partials/critical-vendor.css.html b/themes/hugo-after-dark/layouts/partials/critical-vendor.css.html new file mode 100644 index 0000000..915ed46 --- /dev/null +++ b/themes/hugo-after-dark/layouts/partials/critical-vendor.css.html @@ -0,0 +1,4 @@ + diff --git a/themes/hugo-after-dark/layouts/partials/favicon.html b/themes/hugo-after-dark/layouts/partials/favicon.html new file mode 100644 index 0000000..5b7ac09 --- /dev/null +++ b/themes/hugo-after-dark/layouts/partials/favicon.html @@ -0,0 +1,127 @@ + diff --git a/themes/hugo-after-dark/layouts/partials/menu.html b/themes/hugo-after-dark/layouts/partials/menu.html new file mode 100644 index 0000000..78fc8c1 --- /dev/null +++ b/themes/hugo-after-dark/layouts/partials/menu.html @@ -0,0 +1,8 @@ +{{ if ne .Site.Params.show_menu false }} + +{{ end }} diff --git a/themes/hugo-after-dark/layouts/partials/meta/name-author.html b/themes/hugo-after-dark/layouts/partials/meta/name-author.html new file mode 100644 index 0000000..32fa8f1 --- /dev/null +++ b/themes/hugo-after-dark/layouts/partials/meta/name-author.html @@ -0,0 +1,8 @@ + +{{ if isset .Params "author" }} + +{{ else }} + +{{ end }} diff --git a/themes/hugo-after-dark/layouts/partials/meta/ogimage-maybe.html b/themes/hugo-after-dark/layouts/partials/meta/ogimage-maybe.html new file mode 100644 index 0000000..e5865e1 --- /dev/null +++ b/themes/hugo-after-dark/layouts/partials/meta/ogimage-maybe.html @@ -0,0 +1,13 @@ + +{{ if and (.IsNode) (.Site.Params.images) }} + +{{ end }} + +{{ if and (.IsPage) (not .Params.images) (.Site.Params.images) }} + +{{ end }} diff --git a/themes/hugo-after-dark/layouts/partials/meta/theme-color.html b/themes/hugo-after-dark/layouts/partials/meta/theme-color.html new file mode 100644 index 0000000..63566aa --- /dev/null +++ b/themes/hugo-after-dark/layouts/partials/meta/theme-color.html @@ -0,0 +1 @@ + diff --git a/themes/hugo-after-dark/layouts/partials/page-summary.html b/themes/hugo-after-dark/layouts/partials/page-summary.html new file mode 100644 index 0000000..80d031f --- /dev/null +++ b/themes/hugo-after-dark/layouts/partials/page-summary.html @@ -0,0 +1,19 @@ +
+
+

+ {{ .Title }} +

+ {{ if eq .Type "post" }} +

{{ partial "post/meta" . }}

+ {{ end }} +
+ {{ if .Description }} +
{{ .Description }}
+ {{ end }} +
+ {{ .Summary }} +
+ {{ if .Truncated }} +

+ {{ end }} +
diff --git a/themes/hugo-after-dark/layouts/partials/pagination.html b/themes/hugo-after-dark/layouts/partials/pagination.html new file mode 100644 index 0000000..a96a32c --- /dev/null +++ b/themes/hugo-after-dark/layouts/partials/pagination.html @@ -0,0 +1,11 @@ + diff --git a/themes/hugo-after-dark/layouts/partials/post/byline.html b/themes/hugo-after-dark/layouts/partials/post/byline.html new file mode 100644 index 0000000..579a64d --- /dev/null +++ b/themes/hugo-after-dark/layouts/partials/post/byline.html @@ -0,0 +1,20 @@ +

+ Published + {{ if ne .Site.Params.hide_author true }} + {{ with .Params.author }} + by + {{ else }} + by + {{ end }} + {{ end }} + + {{ with .Params.categories }} + in {{ delimit (apply (apply (sort .) "partial" "post/category-link" ".") "chomp" ".") ", " " and " }} + {{ end }} + {{ with .Params.tags }} + and tagged {{ delimit (apply (apply (sort .) "partial" "post/tag-link" ".") "chomp" ".") ", " " and " }} + {{ end }} + using {{ .WordCount }} words. +

diff --git a/themes/hugo-after-dark/layouts/partials/post/category-link.html b/themes/hugo-after-dark/layouts/partials/post/category-link.html new file mode 100644 index 0000000..6bee96b --- /dev/null +++ b/themes/hugo-after-dark/layouts/partials/post/category-link.html @@ -0,0 +1 @@ +{{ . }} diff --git a/themes/hugo-after-dark/layouts/partials/post/meta.html b/themes/hugo-after-dark/layouts/partials/post/meta.html new file mode 100644 index 0000000..d26bb9e --- /dev/null +++ b/themes/hugo-after-dark/layouts/partials/post/meta.html @@ -0,0 +1,15 @@ + + + + +{{ .ReadingTime }} minute read + + + +{{ if .PublishDate.IsZero }} + Published: +{{ else if lt .PublishDate .Lastmod }} + Modified: +{{ else }} + Published: +{{ end }} diff --git a/themes/hugo-after-dark/layouts/partials/post/related-content.html b/themes/hugo-after-dark/layouts/partials/post/related-content.html new file mode 100644 index 0000000..7083fd5 --- /dev/null +++ b/themes/hugo-after-dark/layouts/partials/post/related-content.html @@ -0,0 +1,15 @@ +{{ range first 1 (where (where .Site.Pages ".Params.tags" "intersect" .Params.tags) "Permalink" "!=" .Permalink) }} + {{ $.Scratch.Set "has_related" true }} +{{ end }} + +{{ if $.Scratch.Get "has_related" }} + +{{ end }} diff --git a/themes/hugo-after-dark/layouts/partials/post/tag-link.html b/themes/hugo-after-dark/layouts/partials/post/tag-link.html new file mode 100644 index 0000000..8c03421 --- /dev/null +++ b/themes/hugo-after-dark/layouts/partials/post/tag-link.html @@ -0,0 +1 @@ +{{ . }} diff --git a/themes/hugo-after-dark/layouts/partials/powered-by.html b/themes/hugo-after-dark/layouts/partials/powered-by.html new file mode 100644 index 0000000..1c58584 --- /dev/null +++ b/themes/hugo-after-dark/layouts/partials/powered-by.html @@ -0,0 +1,8 @@ +{{ if ne .Site.Params.powered_by false }} +

+ This page was generated using + After Dark + for + Hugo. +

+{{ end }} diff --git a/themes/hugo-after-dark/layouts/partials/site-verification.html b/themes/hugo-after-dark/layouts/partials/site-verification.html new file mode 100644 index 0000000..c4d8b05 --- /dev/null +++ b/themes/hugo-after-dark/layouts/partials/site-verification.html @@ -0,0 +1,12 @@ +{{ if .Site.Params.seo.webmaster_verifications.google }} + +{{ end }} +{{ if .Site.Params.seo.webmaster_verifications.bing }} + +{{ end }} +{{ if .Site.Params.seo.webmaster_verifications.alexa }} + +{{ end }} +{{ if .Site.Params.seo.webmaster_verifications.yandex }} + +{{ end }} diff --git a/themes/hugo-after-dark/layouts/partials/toc-maybe.html b/themes/hugo-after-dark/layouts/partials/toc-maybe.html new file mode 100644 index 0000000..cf03efc --- /dev/null +++ b/themes/hugo-after-dark/layouts/partials/toc-maybe.html @@ -0,0 +1,20 @@ +{{ if and (isset .Params "toc") .Params.toc }} +
+ Table of Contents + {{ .TableOfContents }} +
+ +{{ end }} diff --git a/themes/hugo-after-dark/layouts/post/single.html b/themes/hugo-after-dark/layouts/post/single.html new file mode 100644 index 0000000..d65c584 --- /dev/null +++ b/themes/hugo-after-dark/layouts/post/single.html @@ -0,0 +1,32 @@ +{{ define "header" }} + {{ partial "menu" . }} +{{ end }} +{{ define "main" }} +
+ {{ template "_internal/schema.html" . }} +
+

{{ .Title }}

+

{{ partial "post/meta" . }}

+
+ {{ if .Description }} +
{{ .Description }}
+ {{ end }} + {{ partial "toc-maybe" . }} +
+ {{ .Content }} +
+ {{ if .Site.DisqusShortname }} +
+ {{ template "_internal/disqus.html" . }} +
+ {{ end }} +
+
+ {{ partial "post/byline" . }} + {{ partial "post/related-content" . }} +
+
+{{ end }} +{{ define "footer" }} + {{ partial "powered-by" . }} +{{ end }} diff --git a/themes/hugo-after-dark/layouts/shortcodes/blockquote.html b/themes/hugo-after-dark/layouts/shortcodes/blockquote.html new file mode 100644 index 0000000..aab805f --- /dev/null +++ b/themes/hugo-after-dark/layouts/shortcodes/blockquote.html @@ -0,0 +1,8 @@ +
+ {{ .Inner }} + {{ with .Get "citelink" }} + {{ $.Get "cite" }} + {{ else }} + {{ .Get "cite" }} + {{ end }} +
diff --git a/themes/hugo-after-dark/layouts/shortcodes/figure.html b/themes/hugo-after-dark/layouts/shortcodes/figure.html new file mode 100644 index 0000000..620acec --- /dev/null +++ b/themes/hugo-after-dark/layouts/shortcodes/figure.html @@ -0,0 +1,35 @@ + +
+ {{ with .Get "link" }}{{ end }} + {{ if .Get "lqipsrc" }} + + {{ else }} + + {{ end }} + {{ if .Get "link" }}{{ end }} + {{ if or (or (.Get "title") (.Get "caption")) (.Get "attr")}} +
{{ if isset .Params "title" }} +
{{ .Get "title" }}
{{ end }} + {{ if or (.Get "caption") (.Get "attr")}} + {{ .Get "caption" }} + {{ with .Get "attrlink" }} {{ end }} + {{ .Get "attr" }} + {{ if .Get "attrlink"}} {{ end }} + {{ end }} +
+ {{ end }} +
+ diff --git a/themes/hugo-after-dark/package.json b/themes/hugo-after-dark/package.json new file mode 100644 index 0000000..f0c15df --- /dev/null +++ b/themes/hugo-after-dark/package.json @@ -0,0 +1,29 @@ +{ + "name": "after-dark", + "version": "1.2.0", + "description": "A simple, yet highly configurable responsive dark theme for the Hugo static site generator.", + "author": "Josh Habdas (https://habd.as/)", + "keywords": [ + "hugo", + "vaporwave", + "jamstack", + "theme" + ], + "repository": "comfusion/after-dark", + "scripts": { + "copy:lazysizes": "cp -i node_modules/lazysizes/lazysizes.min.js static/js", + "copy:smoothscroll": "cp -i node_modules/smoothscroll-polyfill/dist/smoothscroll.js static/js", + "test": "echo \"Error: no test specified\" && exit 1", + "release": "standard-version" + }, + "dependencies": { + "atom-one-pgyments": "^1.0.0", + "hack": "0.7.7", + "lazysizes": "^3.0.0-rc4", + "smoothscroll-polyfill": "^0.3.4" + }, + "devDependencies": { + "standard-version": "^4.0.0" + }, + "license": "ISC" +} diff --git a/themes/hugo-after-dark/static/js/lazysizes.min.js b/themes/hugo-after-dark/static/js/lazysizes.min.js new file mode 100644 index 0000000..f5917c5 --- /dev/null +++ b/themes/hugo-after-dark/static/js/lazysizes.min.js @@ -0,0 +1,2 @@ +/*! lazysizes - v3.0.0-rc4 */ +!function(a,b){var c=b(a,a.document);a.lazySizes=c,"object"==typeof module&&module.exports&&(module.exports=c)}(window,function(a,b){"use strict";if(b.getElementsByClassName){var c,d=b.documentElement,e=a.Date,f=a.HTMLPictureElement,g="addEventListener",h="getAttribute",i=a[g],j=a.setTimeout,k=a.requestAnimationFrame||j,l=a.requestIdleCallback,m=/^picture$/i,n=["load","error","lazyincluded","_lazyloaded"],o={},p=Array.prototype.forEach,q=function(a,b){return o[b]||(o[b]=new RegExp("(\\s|^)"+b+"(\\s|$)")),o[b].test(a[h]("class")||"")&&o[b]},r=function(a,b){q(a,b)||a.setAttribute("class",(a[h]("class")||"").trim()+" "+b)},s=function(a,b){var c;(c=q(a,b))&&a.setAttribute("class",(a[h]("class")||"").replace(c," "))},t=function(a,b,c){var d=c?g:"removeEventListener";c&&t(a,b),n.forEach(function(c){a[d](c,b)})},u=function(a,c,d,e,f){var g=b.createEvent("CustomEvent");return g.initCustomEvent(c,!e,!f,d||{}),a.dispatchEvent(g),g},v=function(b,d){var e;!f&&(e=a.picturefill||c.pf)?e({reevaluate:!0,elements:[b]}):d&&d.src&&(b.src=d.src)},w=function(a,b){return(getComputedStyle(a,null)||{})[b]},x=function(a,b,d){for(d=d||a.offsetWidth;df&&(f=0),a||9>f&&l?i():j(i,f))}},B=function(a){var b,c,d=99,f=function(){b=null,a()},g=function(){var a=e.now()-c;d>a?j(g,d-a):(l||f)(f)};return function(){c=e.now(),b||(b=j(g,d))}},C=function(){var f,k,l,n,o,x,C,E,F,G,H,I,J,K,L,M=/^img$/i,N=/^iframe$/i,O="onscroll"in a&&!/glebot/.test(navigator.userAgent),P=0,Q=0,R=0,S=-1,T=function(a){R--,a&&a.target&&t(a.target,T),(!a||0>R||!a.target)&&(R=0)},U=function(a,c){var e,f=a,g="hidden"==w(b.body,"visibility")||"hidden"!=w(a,"visibility");for(F-=c,I+=c,G-=c,H+=c;g&&(f=f.offsetParent)&&f!=b.body&&f!=d;)g=(w(f,"opacity")||1)>0,g&&"visible"!=w(f,"overflow")&&(e=f.getBoundingClientRect(),g=H>e.left&&Ge.top-1&&FR&&(a=f.length)){e=0,S++,null==K&&("expand"in c||(c.expand=d.clientHeight>500&&d.clientWidth>500?500:370),J=c.expand,K=J*c.expFactor),K>Q&&1>R&&S>2&&o>2&&!b.hidden?(Q=K,S=0):Q=o>1&&S>1&&6>R?J:P;for(;a>e;e++)if(f[e]&&!f[e]._lazyRace)if(O)if((p=f[e][h]("data-expand"))&&(m=1*p)||(m=Q),q!==m&&(C=innerWidth+m*L,E=innerHeight+m,n=-1*m,q=m),g=f[e].getBoundingClientRect(),(I=g.bottom)>=n&&(F=g.top)<=E&&(H=g.right)>=n*L&&(G=g.left)<=C&&(I||H||G||F)&&(l&&3>R&&!p&&(3>o||4>S)||U(f[e],m))){if(ba(f[e]),j=!0,R>9)break}else!j&&l&&!i&&4>R&&4>S&&o>2&&(k[0]||c.preloadAfterLoad)&&(k[0]||!p&&(I||H||G||F||"auto"!=f[e][h](c.sizesAttr)))&&(i=k[0]||f[e]);else ba(f[e]);i&&!j&&ba(i)}},W=A(V),X=function(a){r(a.target,c.loadedClass),s(a.target,c.loadingClass),t(a.target,Z)},Y=z(X),Z=function(a){Y({target:a.target})},$=function(a,b){try{a.contentWindow.location.replace(b)}catch(c){a.src=b}},_=function(a){var b,d,e=a[h](c.srcsetAttr);(b=c.customMedia[a[h]("data-media")||a[h]("media")])&&a.setAttribute("media",b),e&&a.setAttribute("srcset",e),b&&(d=a.parentNode,d.insertBefore(a.cloneNode(),a),d.removeChild(a))},aa=z(function(a,b,d,e,f){var g,i,k,l,o,q;(o=u(a,"lazybeforeunveil",b)).defaultPrevented||(e&&(d?r(a,c.autosizesClass):a.setAttribute("sizes",e)),i=a[h](c.srcsetAttr),g=a[h](c.srcAttr),f&&(k=a.parentNode,l=k&&m.test(k.nodeName||"")),q=b.firesLoad||"src"in a&&(i||g||l),o={target:a},q&&(t(a,T,!0),clearTimeout(n),n=j(T,2500),r(a,c.loadingClass),t(a,Z,!0)),l&&p.call(k.getElementsByTagName("source"),_),i?a.setAttribute("srcset",i):g&&!l&&(N.test(a.nodeName)?$(a,g):a.src=g),(i||l)&&v(a,{src:g})),a._lazyRace&&delete a._lazyRace,s(a,c.lazyClass),y(function(){(!q||a.complete&&a.naturalWidth>1)&&(q?T(o):R--,X(o))},!0)}),ba=function(a){var b,d=M.test(a.nodeName),e=d&&(a[h](c.sizesAttr)||a[h]("sizes")),f="auto"==e;(!f&&l||!d||!a.src&&!a.srcset||a.complete||q(a,c.errorClass))&&(b=u(a,"lazyunveilread").detail,f&&D.updateElem(a,!0,a.offsetWidth),a._lazyRace=!0,R++,aa(a,b,f,e,d))},ca=function(){if(!l){if(e.now()-x<999)return void j(ca,999);var a=B(function(){c.loadMode=3,W()});l=!0,c.loadMode=3,W(),i("scroll",function(){3==c.loadMode&&(c.loadMode=2),a()},!0)}};return{_:function(){x=e.now(),f=b.getElementsByClassName(c.lazyClass),k=b.getElementsByClassName(c.lazyClass+" "+c.preloadClass),L=c.hFac,i("scroll",W,!0),i("resize",W,!0),a.MutationObserver?new MutationObserver(W).observe(d,{childList:!0,subtree:!0,attributes:!0}):(d[g]("DOMNodeInserted",W,!0),d[g]("DOMAttrModified",W,!0),setInterval(W,999)),i("hashchange",W,!0),["focus","mouseover","click","load","transitionend","animationend","webkitAnimationEnd"].forEach(function(a){b[g](a,W,!0)}),/d$|^c/.test(b.readyState)?ca():(i("load",ca),b[g]("DOMContentLoaded",W),j(ca,2e4)),f.length?(V(),y._lsFlush()):W()},checkElems:W,unveil:ba}}(),D=function(){var a,d=z(function(a,b,c,d){var e,f,g;if(a._lazysizesWidth=d,d+="px",a.setAttribute("sizes",d),m.test(b.nodeName||""))for(e=b.getElementsByTagName("source"),f=0,g=e.length;g>f;f++)e[f].setAttribute("sizes",d);c.detail.dataAttr||v(a,c.detail)}),e=function(a,b,c){var e,f=a.parentNode;f&&(c=x(a,f,c),e=u(a,"lazybeforesizes",{width:c,dataAttr:!!b}),e.defaultPrevented||(c=e.detail.width,c&&c!==a._lazysizesWidth&&d(a,f,e,c)))},f=function(){var b,c=a.length;if(c)for(b=0;c>b;b++)e(a[b])},g=B(f);return{_:function(){a=b.getElementsByClassName(c.autosizesClass),i("resize",g)},checkElems:g,updateElem:e}}(),E=function(){E.i||(E.i=!0,D._(),C._())};return function(){var b,d={lazyClass:"lazyload",loadedClass:"lazyloaded",loadingClass:"lazyloading",preloadClass:"lazypreload",errorClass:"lazyerror",autosizesClass:"lazyautosizes",srcAttr:"data-src",srcsetAttr:"data-srcset",sizesAttr:"data-sizes",minSize:40,customMedia:{},init:!0,expFactor:1.5,hFac:.8,loadMode:2};c=a.lazySizesConfig||a.lazysizesConfig||{};for(b in d)b in c||(c[b]=d[b]);a.lazySizesConfig=c,j(function(){c.init&&E()})}(),{cfg:c,autoSizer:D,loader:C,init:E,uP:v,aC:r,rC:s,hC:q,fire:u,gW:x,rAF:y}}}); \ No newline at end of file diff --git a/themes/hugo-after-dark/static/js/smoothscroll.js b/themes/hugo-after-dark/static/js/smoothscroll.js new file mode 100644 index 0000000..916cd11 --- /dev/null +++ b/themes/hugo-after-dark/static/js/smoothscroll.js @@ -0,0 +1,291 @@ +/* + * smoothscroll polyfill - v0.3.4 + * https://iamdustan.github.io/smoothscroll + * 2016 (c) Dustan Kasten, Jeremias Menichelli - MIT License + */ + +(function(w, d, undefined) { + 'use strict'; + + /* + * aliases + * w: window global object + * d: document + * undefined: undefined + */ + + // polyfill + function polyfill() { + // return when scrollBehavior interface is supported + if ('scrollBehavior' in d.documentElement.style) { + return; + } + + /* + * globals + */ + var Element = w.HTMLElement || w.Element; + var SCROLL_TIME = 468; + + /* + * object gathering original scroll methods + */ + var original = { + scroll: w.scroll || w.scrollTo, + scrollBy: w.scrollBy, + scrollIntoView: Element.prototype.scrollIntoView + }; + + /* + * define timing method + */ + var now = w.performance && w.performance.now + ? w.performance.now.bind(w.performance) : Date.now; + + /** + * changes scroll position inside an element + * @method scrollElement + * @param {Number} x + * @param {Number} y + */ + function scrollElement(x, y) { + this.scrollLeft = x; + this.scrollTop = y; + } + + /** + * returns result of applying ease math function to a number + * @method ease + * @param {Number} k + * @returns {Number} + */ + function ease(k) { + return 0.5 * (1 - Math.cos(Math.PI * k)); + } + + /** + * indicates if a smooth behavior should be applied + * @method shouldBailOut + * @param {Number|Object} x + * @returns {Boolean} + */ + function shouldBailOut(x) { + if (typeof x !== 'object' + || x === null + || x.behavior === undefined + || x.behavior === 'auto' + || x.behavior === 'instant') { + // first arg not an object/null + // or behavior is auto, instant or undefined + return true; + } + + if (typeof x === 'object' + && x.behavior === 'smooth') { + // first argument is an object and behavior is smooth + return false; + } + + // throw error when behavior is not supported + throw new TypeError('behavior not valid'); + } + + /** + * finds scrollable parent of an element + * @method findScrollableParent + * @param {Node} el + * @returns {Node} el + */ + function findScrollableParent(el) { + var isBody; + var hasScrollableSpace; + var hasVisibleOverflow; + + do { + el = el.parentNode; + + // set condition variables + isBody = el === d.body; + hasScrollableSpace = + el.clientHeight < el.scrollHeight || + el.clientWidth < el.scrollWidth; + hasVisibleOverflow = + w.getComputedStyle(el, null).overflow === 'visible'; + } while (!isBody && !(hasScrollableSpace && !hasVisibleOverflow)); + + isBody = hasScrollableSpace = hasVisibleOverflow = null; + + return el; + } + + /** + * self invoked function that, given a context, steps through scrolling + * @method step + * @param {Object} context + */ + function step(context) { + // call method again on next available frame + context.frame = w.requestAnimationFrame(step.bind(w, context)); + + var time = now(); + var value; + var currentX; + var currentY; + var elapsed = (time - context.startTime) / SCROLL_TIME; + + // avoid elapsed times higher than one + elapsed = elapsed > 1 ? 1 : elapsed; + + // apply easing to elapsed time + value = ease(elapsed); + + currentX = context.startX + (context.x - context.startX) * value; + currentY = context.startY + (context.y - context.startY) * value; + + context.method.call(context.scrollable, currentX, currentY); + + // return when end points have been reached + if (currentX === context.x && currentY === context.y) { + w.cancelAnimationFrame(context.frame); + return; + } + } + + /** + * scrolls window with a smooth behavior + * @method smoothScroll + * @param {Object|Node} el + * @param {Number} x + * @param {Number} y + */ + function smoothScroll(el, x, y) { + var scrollable; + var startX; + var startY; + var method; + var startTime = now(); + var frame; + + // define scroll context + if (el === d.body) { + scrollable = w; + startX = w.scrollX || w.pageXOffset; + startY = w.scrollY || w.pageYOffset; + method = original.scroll; + } else { + scrollable = el; + startX = el.scrollLeft; + startY = el.scrollTop; + method = scrollElement; + } + + // cancel frame when a scroll event's happening + if (frame) { + w.cancelAnimationFrame(frame); + } + + // scroll looping over a frame + step({ + scrollable: scrollable, + method: method, + startTime: startTime, + startX: startX, + startY: startY, + x: x, + y: y, + frame: frame + }); + } + + /* + * ORIGINAL METHODS OVERRIDES + */ + + // w.scroll and w.scrollTo + w.scroll = w.scrollTo = function() { + // avoid smooth behavior if not required + if (shouldBailOut(arguments[0])) { + original.scroll.call( + w, + arguments[0].left || arguments[0], + arguments[0].top || arguments[1] + ); + return; + } + + // LET THE SMOOTHNESS BEGIN! + smoothScroll.call( + w, + d.body, + ~~arguments[0].left, + ~~arguments[0].top + ); + }; + + // w.scrollBy + w.scrollBy = function() { + // avoid smooth behavior if not required + if (shouldBailOut(arguments[0])) { + original.scrollBy.call( + w, + arguments[0].left || arguments[0], + arguments[0].top || arguments[1] + ); + return; + } + + // LET THE SMOOTHNESS BEGIN! + smoothScroll.call( + w, + d.body, + ~~arguments[0].left + (w.scrollX || w.pageXOffset), + ~~arguments[0].top + (w.scrollY || w.pageYOffset) + ); + }; + + // Element.prototype.scrollIntoView + Element.prototype.scrollIntoView = function() { + // avoid smooth behavior if not required + if (shouldBailOut(arguments[0])) { + original.scrollIntoView.call(this, arguments[0] || true); + return; + } + + // LET THE SMOOTHNESS BEGIN! + var scrollableParent = findScrollableParent(this); + var parentRects = scrollableParent.getBoundingClientRect(); + var clientRects = this.getBoundingClientRect(); + + if (scrollableParent !== d.body) { + // reveal element inside parent + smoothScroll.call( + this, + scrollableParent, + scrollableParent.scrollLeft + clientRects.left - parentRects.left, + scrollableParent.scrollTop + clientRects.top - parentRects.top + ); + // reveal parent in viewport + w.scrollBy({ + left: parentRects.left, + top: parentRects.top, + behavior: 'smooth' + }); + } else { + // reveal element in viewport + w.scrollBy({ + left: clientRects.left, + top: clientRects.top, + behavior: 'smooth' + }); + } + }; + } + + if (typeof exports === 'object') { + // commonjs + module.exports = { polyfill: polyfill }; + } else { + // global + polyfill(); + } +})(window, document); diff --git a/themes/hugo-after-dark/theme.toml b/themes/hugo-after-dark/theme.toml new file mode 100644 index 0000000..cff13bd --- /dev/null +++ b/themes/hugo-after-dark/theme.toml @@ -0,0 +1,41 @@ +name = "After Dark" +license = "ISC" +licenselink = "https://github.com/comfusion/after-dark/blob/master/LICENSE.md" +description = "A simple, yet highly configurable responsive dark theme." +homepage = "https://comfusion.github.io/after-dark/" +tags = [ + "personal", + "minimal", + "responsive", + "accessible", + "vaporwave" +] +features = [ + "Mobile-optimized", + "SEO-optimized", + "Responsive Design", + "Flexbox Layouts", + "Google Analytics", + "Disqus", + "Image lazyloading", + "OpenGraph", + "Schema Structured Data", + "Pagination", + "Reading time", + "Related content", + "Modification dating", + "Author byline", + "Word Count", + "Related Posts", + "Section Menu", + "Block Templates", + "Table of Contents", + "Keyboard accessible", + "Terminal friendly", + "Customizable theme" +] +min_version = 0.16 + +[author] + name = "Josh Habdas" + homepage = "https://habd.as"