Compare commits

...

98 Commits

Author SHA1 Message Date
Alan Orth a8ff91e1ea
CHANGELOG.md: Add note about Danish
continuous-integration/drone/push Build is passing Details
continuous-integration/drone Build is passing Details
2022-07-29 20:15:32 +03:00
Alan Orth 31ee2abcad
Merge pull request #146 from schack/feature_danish_translation
en.yaml translated to Danish
2022-07-29 20:14:07 +03:00
Henrik Schack 915caee6dd en.yaml translated to Danish 2022-07-29 15:06:27 +02:00
Alan Orth 08ae262312
CHANGELOG.md: add note about Bootstrap tables
continuous-integration/drone/push Build is passing Details
2022-07-29 10:09:02 +03:00
Alan Orth b781125ed8
Regenerate static assets 2022-07-29 10:07:28 +03:00
Alan Orth ddcae7c761
package-lock.json: run npm update 2022-07-29 10:07:16 +03:00
Alan Orth b415ee2879
Regenerate static assets 2022-07-29 10:05:11 +03:00
Alan Orth 4260a7e1af
source/scss/bootstrap.scss: enable tables
Requested by a user.

See: https://github.com/alanorth/hugo-theme-bootstrap4-blog/issues/145
2022-07-29 10:03:57 +03:00
Alan Orth a94ebccf3d
Use Node.js 14 instead of 12
continuous-integration/drone/push Build is passing Details
2022-06-07 09:36:46 +03:00
Alan Orth 54d3242633
CHANGELOG.md: update notes
continuous-integration/drone/push Build is passing Details
2021-10-18 15:03:01 +03:00
Alan Orth 1d4204a404
Regenerate static assets 2021-10-18 14:53:45 +03:00
Alan Orth 985070b311
package.json: update cleancss options
We use -O1 instead of --level 1 now.
2021-10-18 14:52:55 +03:00
Alan Orth 2e40f6cd69
Update npm dependencies 2021-10-18 14:52:43 +03:00
Alan Orth 99f1a6725c
Regenerate static assets
continuous-integration/drone/push Build is passing Details
2021-09-15 09:59:40 +03:00
Alan Orth 898d91701a
package-lock.json: Run npm update 2021-09-15 09:59:05 +03:00
Alan Orth 40b3fb4979
.drone.yml: Build on Node.js 16
continuous-integration/drone/push Build is passing Details
We want to build on LTS or "current" releases only.

See: https://nodejs.org/en/about/releases/
2021-08-19 16:09:05 +03:00
Alan Orth 5797675dbd
theme.toml: Add demo link
continuous-integration/drone/push Build is passing Details
As of 2021-07-01 the Hugo Themes showcase is no longer building our
themes so we need to include a link to a demo.
2021-07-09 22:36:07 +03:00
Alan Orth 8cdfeb297d
package.json: Run webpack without npx
continuous-integration/drone/push Build is passing Details
This only affects the CI, but the inability to run webpack seems
to have been due to using an older version of npm (v6.14.x), and
now we upgrade npm before install so we don't need this hack.
2021-03-23 11:25:21 +02:00
Alan Orth 7a2ac26879
.drone.yml: Update npm before install and build
continuous-integration/drone/push Build is passing Details
It seems that the issue with not being able to find webpack-cli is
due to some behavior with an older version of npm. My local devel-
opment environment has npm 7.6.x and so does the Node.js 15 conta-
iner, while the Node.js 12 and 14 containers have npm 6.14.x.

Updating npm fixes the issue with `npx webpack` not being able to
find webpack-cli's webpack command (perhaps it installs the peer
dependency automatically, I don't know).
2021-03-23 10:16:02 +02:00
Alan Orth 72fe18fd4d
package.json: Run webpack with npx
continuous-integration/drone/push Build is failing Details
My local dev environment automatically adds ./node_modules/.bin to
the shell PATH, but it seems a better way to do this is to use npx
so that it works here and on the CI.
2021-03-23 09:45:19 +02:00
Alan Orth 085cf9847f
.drone.yml: Run on current and LTS Node.js releases
Node.js v10 will cease to be LTS next month and I haven't even used
it for a while already, so let's change this to only run on 12, 14,
and 15, which are the current active and LTS releases.

See: https://nodejs.org/en/about/releases/
2021-03-23 09:39:40 +02:00
Alan Orth dbc97128f3
package-lock.json: Run npm update
continuous-integration/drone/push Build is failing Details
2021-03-22 13:45:47 +02:00
Alan Orth 5dd511963d
package.json: Only install webpack-cli
We don't explicitly need webpack, as webpack-cli will bring it in
for us.
2021-03-22 13:45:21 +02:00
Alan Orth d24e709cd3
CHANGELOG.md: Minor dependency updates
continuous-integration/drone/push Build is passing Details
2021-01-19 22:11:57 +02:00
Alan Orth 6c30836cc9
Regenerate static assets 2021-01-19 22:10:35 +02:00
Alan Orth ddd2836905
source/scss/bootstrap.scss: Update header
Minor, but can be very confusing when looking at CSS and wondering
why the version is old.
2021-01-19 22:10:04 +02:00
Alan Orth f3a5cf6630
Run npm update
Brings in Bootstrap v4.6.0 as well as a few others.
2021-01-19 22:09:26 +02:00
Alan Orth 1876747063
README.md: Fix link syntax
continuous-integration/drone/push Build is passing Details
2021-01-12 09:25:42 +02:00
Alan Orth 96d6304f09
Remove .travis.yml
continuous-integration/drone/push Build is passing Details
TravisCI changed their business model recently and I realized it is
better to not rely on free cloud services. I am now using a Drone.io
instance on my own infrastructure.
2020-12-10 12:56:02 +02:00
Alan Orth e0c8b5a057
README.md: Use badge from Drone CI 2020-12-10 12:55:37 +02:00
Alan Orth d6ab3cda0a
.drone.yml: Correct npm task
continuous-integration/drone/push Build is passing Details
2020-12-10 12:49:57 +02:00
Alan Orth e1dfe242a6
.travis.yml: Only build on Node.js LTS versions 2020-12-10 12:48:38 +02:00
Alan Orth bfac136c3e
Add .drone.yml for ci.mjanja.ch 2020-12-10 12:48:12 +02:00
Alan Orth 4a922d8657
README.md: Use travis-ci.com domain for badge 2020-12-08 09:07:25 +02:00
Alan Orth 94269648d6
.travis.yml: Try to build on AWS graviton2 instances
These are the second generation of Amazon's ARM-based instances.

See: https://blog.travis-ci.com/2020-09-11-arm-on-aws
2020-12-06 09:54:23 +02:00
Alan Orth 3fc531eb66
Move unreleased changes to 1.6.0 2020-12-05 19:01:52 +02:00
Alan Orth 82362818a1
README.md: Add note about new figure shortcode 2020-12-05 18:59:06 +02:00
Alan Orth 54f85c3beb
layouts/_default/single.html: Fix for images in the page bundle 2020-12-04 14:09:27 +02:00
Alan Orth c6498a4bfb
layouts/partials: Override internal templates for page bundles
The Hugo internal Twitter and OpenGraph templates assume your post
images are in the static directory. This tries to look them up in
the page bundle first and falls back to the Hugo default behavior.
2020-12-04 14:06:47 +02:00
Alan Orth 147ee8cf76
layouts/shortcodes/figure.html: Add srcset support
This overrides Hugo's default figure shortcode to enable img srcset
support, which allows the client to decide which size of image they
want to download based on a CSS media query. During build time Hugo
creates several versions of each image to match several breakpoints.
Unfortunately this only works if the images are in the post's page
bundle, falling back to retrieving images from the static directory
if they aren't found in the bundle.

This shortcode was originally from Charl P. Botha, but I modified
it to automatically rotate images that have orientation EXIF data.

See: https://gohugo.io/content-management/page-bundles/
See: http://www.johann-oberdorfer.eu/blog/2020/01/05/20-01-05_leverage_page_bundles_in_hugo/
See: https://cpbotha.net/2020/05/02/drop-in-replacement-for-hugo-figure-shortcode-with-responsive-img-srcset/
2020-12-04 14:03:29 +02:00
Alan Orth cb81c7818d
CHANGELOG.md: Add note about dart sass 2020-11-30 12:45:04 +02:00
Alan Orth 37e48b1e28
Regenerate static assets 2020-11-30 12:42:10 +02:00
Alan Orth 39a9a8fd2a
Adjust source/scss for dart sass
Imports are relative to the current file it seems.
2020-11-30 12:41:53 +02:00
Alan Orth 64d62a9179
Migrate to dart sass
libsass (and therefore node-sass) is deprecated and dart sass is
recommended.

See: https://sass-lang.com/blog/libsass-is-deprecated
2020-11-30 12:39:54 +02:00
Alan Orth 6dde205d0d
Move unreleased changes to v1.5.1 2020-11-15 11:58:56 +02:00
Alan Orth 28a2013d85
theme.toml: Use picturingjordan.com as homepage
It's more current and it's the one that is using this theme anyway.
2020-11-15 11:57:58 +02:00
Alan Orth 66298fa0ef
package.json: Upgrade to node-sass v5.0.0 2020-11-15 11:56:59 +02:00
Alan Orth a38342b330
Regenerate static assets 2020-11-15 11:36:45 +02:00
Alan Orth 6d8df04c19
Upgrade to webpack 5 2020-11-15 11:36:25 +02:00
Alan Orth 900bb6468c
CHANGELOG.md: Add note about omitting date 2020-10-29 12:54:33 +03:00
Alan Orth 7d40acef85 CHANGELOG.md: Add note about JSON-LD fix 2020-10-29 12:54:03 +03:00
Jeremy Campbell 7dbe547dce Allow content without PublishDate, eliminates extraneous date output. 2020-10-29 12:53:14 +03:00
Jeremy Campbell 43d4fb3d2d Fixed formatting of ld-json keywords list on list.html default 2020-10-29 12:50:49 +03:00
Alan Orth 5fe17ee120
.travis.yml: Use Ubuntu 20.04 "Focal" environment 2020-10-29 00:12:57 +03:00
Alan Orth ab444c93b5
Regenerate static assets 2020-10-19 16:26:33 +03:00
Alan Orth eb70aea769
source/scss/bootstrap.scss: Bump version in comment
This can be super confusing when you're looking at CSS.
2020-10-19 16:26:01 +03:00
Alan Orth 5b548c730a
Run npm update 2020-10-19 16:25:24 +03:00
Alan Orth 2a42864125
package.json: Bootstrap v4.5.3 2020-10-19 16:25:06 +03:00
Alan Orth 7f819cfdd1
CHANGELOG.md: Add note about deps 2020-10-09 23:19:34 +03:00
Alan Orth 4b2b1617c0
Regenerate static assets 2020-10-09 23:18:48 +03:00
Alan Orth 415ae8956c
source/scss/bootstrap.scss: Bump version to 4.5.2
This is only a comment but it shows in the generated CSS and can be
confusing when you are expecting to see one number, but see another.
2020-10-09 23:17:45 +03:00
Alan Orth 3987192a31
Run npm update 2020-10-09 23:16:45 +03:00
Alan Orth 3254306148
.travis.yml: Node.js 15 isn't released yet
See: https://nodejs.org/en/about/releases/
2020-07-27 15:40:55 +03:00
Alan Orth 536dd793fe
.travis.yml: Add current Node.js versions
See: https://nodejs.org/en/about/releases/
2020-07-27 15:38:55 +03:00
Alan Orth 9b877752b7
Version 1.5.0 2020-05-17 22:48:58 +03:00
Alan Orth ef714f2192
layouts: Fix error in Haven invocation 2020-05-17 22:45:23 +03:00
Alan Orth d72552cde3
layouts: Update Haven invocation
If the user has configured a cookie consent information URL we will
show it in the banner.
2020-05-17 22:42:56 +03:00
Alan Orth 21aab8a79d
README.md: Update Google Analytics description
Now consent is mandatory if you enable Google Analytics.
2020-05-17 22:40:32 +03:00
Alan Orth 26f170bfdd
layouts: Test for existence of Google Analytics ID
Previously we showed the Cookie Usage banner if the site's config
had a cookie consent URL specified. As of 2018-05 (GDPR) it makes
more sense to only display this banner if the site has a Google
Analytics ID set. Because we are using Haven for consent manage-
ment we can now inject Google Analytics automatically after the
user has agreed, so we no longer need to use Hugo's internal te-
mplate.
2020-05-17 22:32:12 +03:00
Alan Orth dedea8ccc0
README.md: Update feature description for Google Analytics 2020-05-17 22:26:24 +03:00
Alan Orth 006e3f49bd
CHANGELOG.md: Move unreleased changes to v1.5.0 2020-05-17 22:24:52 +03:00
Alan Orth a019ed776f
CHANGELOG.md: Add note about Haven 2020-05-13 14:19:04 +03:00
Alan Orth 3b360d2eef
Use haven for GDPR popup instead of cookieconsent
Haven is newer and more well maintained (and also it is actually
open source instead of open core with an upsell to a paid subscrip-
tion). Haven is configured to be 100% *opt-in* for Google Analytics,
which means it does not load or send a hit until the user agrees.

This is mostly a drop-in replacement, but translations need to make
sure the following strings are updated:

- cookieAccept
- cookieDecline
2020-05-13 13:19:41 +03:00
Alan Orth e840f783e7
CHANGELOG: Add unreleased changes 2020-05-13 10:01:18 +03:00
Alan Orth 8da96f34ef
Regenerate static assets 2020-05-13 10:00:27 +03:00
Alan Orth 2845e18f9a
package.json: Run npm update
Minor version bumps to webpack, fontawesome, and node-sass.
2020-05-13 09:58:50 +03:00
Alan Orth 8448af2481
Bootstrap v4.5.0
See: https://github.com/twbs/bootstrap/releases/tag/v4.5.0
2020-05-13 09:54:43 +03:00
Alan Orth a390958117
Revert ".travis.yml: Use an LXD container instead of VM"
This reverts commit faa3c3cf5b.

Build took over six minutes for each Node.js version because NVM
had to build each from source. So yeah, let's go back to amd64 VMs.
2020-03-30 09:31:34 +03:00
Alan Orth faa3c3cf5b
.travis.yml: Use an LXD container instead of VM
We need to specify OS and Arch in order to use an LXD container in-
stead of a VM. This should theoretically be much faster according
to the Travis docs. Here we are building on arm64 because there is
no amd64 container support right now, but it shouldn't matter beca-
use we are only doing npm build.

See: https://docs.travis-ci.com/user/reference/overview/
2020-03-30 09:16:38 +03:00
Alan Orth bbc5ef18cf
.travis.yml: Don't use Node.js v14
It is not released yet.

See: https://nodejs.org/en/about/releases/
2020-03-29 16:49:49 +03:00
Alan Orth 1cb082e1f1
.travis.yml: Update
Remove deprecated sudo, update Node.js versions to current actively
maintained and LTS versions, use Ubuntu 18.04 "Bionic" environment
instead of 16.04 "Xenial".
2020-03-29 16:44:33 +03:00
Alan Orth 3a83d4e43e
CHANGELOG.md: Add note about DE i18n strings 2020-03-25 14:18:53 +02:00
Marcel Mellor 3c21de9fcd Added missing language keys DE 2020-03-25 14:16:49 +02:00
Alan Orth ce89342827
exampleSite/config.toml: Show how to override date format 2020-03-22 15:28:33 +02:00
Alan Orth a2ac9fe29e
CHANGELOG.md: Update cookieconsent to 3.1.1 2020-03-22 15:10:23 +02:00
Alan Orth 77e05f010e
Regenerate static asssets 2020-03-22 15:09:46 +02:00
Alan Orth 320ee71b75
Update to cookieconsent 3.1.1
In my minimal testing this works for the default popup.
2020-03-22 15:09:01 +02:00
Alan Orth 9bbfab2f1b
Version 1.4.2 2020-03-22 11:17:27 +02:00
Alan Orth f7d9451aa6
layouts: Fix minor encoding issue with dates
This is similar to other encoding issues we have fixed lately where
we need to make sure Hugo (or Golang's HTML template library) does
not escape our non-ASCII content.

For example, this is how our datetimes end up currently:

    <p class="blog-post-meta"><time datetime="2020-01-16T09:23:20&#43;02:00">Thu Jan 16, 2020</time> by Alan Orth

After printing them with `printf` and filtering them with the Hugo
built-in function `safeHTMLAttr` they look like this:

    <p class="blog-post-meta"><time datetime="2020-01-16T09:23:20+02:00">Thu Jan 16, 2020</time> by Alan Orth

See: https://github.com/gohugoio/hugo/blob/master/tpl/tplimpl/embedded/templates/opengraph.html
See: https://github.com/alanorth/hugo-theme-bootstrap4-blog/pull/111
2020-03-22 11:09:27 +02:00
Alan Orth 85abd20ba7
layouts: Fix more structured data escaping issues
I think we actually only need to quote string literals. Otherwise,
it seems that Hugo automatically adds quoting for us, and doesn't
use funny escaping of URLs, special characters, etc.
2020-03-19 15:45:31 +02:00
Alan Orth 9e0b00038a
Version 1.4.1
And oops, I had forgotten to bump the version in package.json for
v1.4.0.
2020-03-19 15:29:30 +02:00
Alan Orth 9676a9736b
CHANGELOG.md: Add note about fix for structured data 2020-03-19 15:27:51 +02:00
Alan Orth 4a88be4434
layouts: Remove quoting of structured data
I don't understand it, but quoting these values causes Hugo to use
escape codes for non-ASCII (?) characters. For example:

  "description": "A thriving oasis in Jordan\x27s desert is at risk of disappearing."

Google's Search Console shows the following error:

    Unparsable structured data > Bad escape sequence in string

We had a similar issue with dates that was fixed in #111 and the
solution is the same here.
2020-03-19 15:22:29 +02:00
Alan Orth 780444bfb0
README.md: Add note about Farsi 2020-03-16 11:57:37 +02:00
Alan Orth 58d01baba6
CHANGELOG.md: Add note about updated dependencies 2020-03-16 09:49:32 +02:00
Alan Orth 9fb0baa0a5
Regenerate static assets 2020-03-16 09:47:25 +02:00
Alan Orth 550b5c066d
Run npm update
Brings new versions of rtlcss, webpack, and fontawesome.
2020-03-16 09:46:39 +02:00
Alan Orth 3be21cba1d
CHANGELOG.md: Adjust headings 2020-01-28 11:06:03 +02:00
40 changed files with 3357 additions and 5025 deletions

View File

@ -1,6 +1,6 @@
image: archlinux
packages:
- nodejs-lts-erbium
- nodejs-lts-fermium
- npm
sources:
- https://git.sr.ht/~alanorth/hugo-theme-bootstrap4-blog

28
.drone.yml Normal file
View File

@ -0,0 +1,28 @@
kind: pipeline
type: docker
name: node14
steps:
- name: build
image: node:14-alpine
commands:
- npm --version
- npm install -g npm
- npm --version
- npm install
- npm run build
---
kind: pipeline
type: docker
name: node16
steps:
- name: build
image: node:16-alpine
commands:
- npm --version
- npm install -g npm
- npm --version
- npm install
- npm run build

View File

@ -1,10 +0,0 @@
language: node_js
node_js:
- 8
- 10
- 11
script: npm run build
sudo: false
dist: xenial
# vim: ts=2 sw=2 et

View File

@ -4,22 +4,72 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased Changes
### Updated
- Bootstrap v4.6.0, webpack v5, haven 0.7.0, clean-css-cli, etc
- Use Node.js 14 in CI, remove Node.js 12
## Added
- Support for Bootstrap table classes (#145)
- i18n language keys for Danish (@schack, #146)
## [[ 1.6.0 ]] - 2020-12-05
### Changed
- Migrate to dart sass from node-sass (see [LibSass is Deprecated](https://sass-lang.com/blog/libsass-is-deprecated))
- Use new [figure shortcode](https://cpbotha.net/2020/05/02/drop-in-replacement-for-hugo-figure-shortcode-with-responsive-img-srcset/a) that automatically processes images in a post's page bundle to multiple resolutions and outputs an appropriate img srcset (falls back to getting images from static dir)
## [[1.5.1]] - 2020-11-15
### Updated
- Minor version bump for bootstrap, node-sass, and fontawesome
- Update to webpack 5 (brings better tree shaking, reduces fontawesome JS by 8K)
### Fixed
- JSON-LD keyword formatting @jeremyrcampb #140
### Added
- Ability to omit date in front matter @jeremyrcampb #141
## [[1.5.0]] - 2020-05-17
### Updated
- i18n language keys for German (@dermellor, #131)
- Boostrap v4.5.0
- Minor version bump for webpack, node-sass, and fontawesome
### Changed
- Use Haven for GDPR-compliant popup instead of cookieconsent, which is now
configured as *opt-in* and does not load Google Analytics or send a hit until
the user agrees.
- Note to translators that some strings have changed, please check:
- `cookieAccept`: the string for the "Agree" button
- `cookieDecline`: the string for the "Disagree" button
## [[1.4.2]] - 2020-03-22
### Fixed
- Encoding of dates in HTML (@alanorth)
## [[1.4.1]] - 2020-03-19
### Updated
- npm dependencies: rtlcss 2.5.0, webpack 4.42.0, fontawesome solid icons 5.12.1
### Fixed
- Fix "Unparsable structured data" error in JSON-LD (@alanorth)
## [[1.4.0]] - 2020-01-28
### Added
- Farsi strings for user interface
## Updated
### Updated
- bootstrap 4.4.1
- Fix typo in README.md (@xekon, #118)
- Font Awesome 5 (make sure you [update](https://fontawesome.com/how-to-use/on-the-web/setup/upgrading-from-version-4) any custom icons you might be using in your content, site layouts, partials, etc).
## Changed
### Changed
- Use Hugo's built-in subresource integrity support instead of the generatesri
tooling that I wrote by hand a few years ago (#120, @alanorth)
- Use Font Awesome SVGs via JavaScript instead of web fonts (@alanorth)
- Category and tag links now have a trailing slash (#128, @alanorth)
## Removed
### Removed
- Several references to Google Plus (@xekon, #122)
## [[1.3.3]] - 2019-12-02

View File

@ -1,4 +1,4 @@
# Hugo Bootstrap v4 Blog [![Build Status](https://travis-ci.org/alanorth/hugo-theme-bootstrap4-blog.svg?branch=master)](https://travis-ci.org/alanorth/hugo-theme-bootstrap4-blog) [![builds.sr.ht status](https://builds.sr.ht/~alanorth/hugo-theme-bootstrap4-blog.svg)](https://builds.sr.ht/~alanorth/hugo-theme-bootstrap4-blog?)
# Hugo Bootstrap v4 Blog [![Build Status](https://ci.mjanja.ch/api/badges/alanorth/hugo-theme-bootstrap4-blog/status.svg)](https://ci.mjanja.ch/alanorth/hugo-theme-bootstrap4-blog) [![builds.sr.ht status](https://builds.sr.ht/~alanorth/hugo-theme-bootstrap4-blog.svg)](https://builds.sr.ht/~alanorth/hugo-theme-bootstrap4-blog?)
A simple but opinionated [Hugo](https://gohugo.io) theme geared towards blog-style content. Based on the older two-column [Bootstrap blog example](https://v4-alpha.getbootstrap.com/examples/blog/) that was used for several Bootstrap versions, but has now been retired in favor of a "snarky" (their words) new example as of version [4.0.0's final release](https://blog.getbootstrap.com/2018/01/18/bootstrap-4/).
![Screenshot](https://raw.githubusercontent.com/alanorth/hugo-theme-bootstrap4-blog/master/screenshot.png "Screenshot")
@ -11,14 +11,14 @@ See [picturingjordan.com](https://picturingjordan.com) for an example of this th
- Uses Bootstrap v4's [native system font stack](https://getbootstrap.com/docs/4.0/content/reboot/#native-font-stack) to load quickly and look good on all platforms
- Excellent [structured data](https://developers.google.com/search/docs/guides/intro-structured-data) (JSON-LD), [OpenGraph](http://ogp.me), and [Twitter Card](https://dev.twitter.com/cards/types) metadata support
- robots.txt linking to XML sitemap (disabled by default, see [Hugo docs](https://gohugo.io/extras/robots-txt/))
- Basic support for [multi-lingual content](https://gohugo.io/content-management/multilingual/) (added in Hugo 0.17) and user interface translation (i18n), including RTL languages like Arabic
- Basic support for [multi-lingual content](https://gohugo.io/content-management/multilingual/) (added in Hugo 0.17) and user interface translation (i18n), including RTL languages like Arabic and Farsi
- Supports Google, Bing, and Yandex site verification via meta tags
- Supports Google Analytics (async version), see [Hugo docs](https://gohugo.io/extras/analytics/)
- Supports GDPR-compliant Google Analytics (script is not even loaded until *after* the user agrees) with configurable consent banner, see [`exampleSite/config.toml`](https://github.com/alanorth/hugo-theme-bootstrap4-blog/blob/master/exampleSite/config.toml)
- Supports Disqus comments, see [Hugo docs](https://gohugo.io/extras/comments/)
- Can show a message about cookie usage to the user, see [`exampleSite/config.toml`](https://github.com/alanorth/hugo-theme-bootstrap4-blog/blob/master/exampleSite/config.toml)
- Allow addition of custom `<head>` code in site's `layouts/partials/head-custom.html` (see [#17](https://github.com/alanorth/hugo-theme-bootstrap4-blog/pull/17))
- Configurable display of summaries of content in list templates.
- Configurable keywords for every post
- Supports automatic generation of `<img>` srcsets for images in [page bundles](https://gohugo.io/content-management/page-bundles/) using a [new figure shortcode](https://cpbotha.net/2020/05/02/drop-in-replacement-for-hugo-figure-shortcode-with-responsive-img-srcset/) (falls back to default Hugo behavior of looking up images in the static directory)
## Usage
Clone the repository to your site's `themes` directory. Refer to [`exampleSite/config.toml`](https://github.com/alanorth/hugo-theme-bootstrap4-blog/blob/master/exampleSite/config.toml) for recommended configuration values.
@ -38,7 +38,7 @@ A few suggestions to help you get a good looking site quickly:
See the source code and structure of [picturingjordan.com](https://github.com/alanorth/picturingjordan.com) to get more ideas.
## Building (For Developers)
This theme uses the [Bootstrap](https://getbootstrap.com/) framework. A static version of this is already included, but if you want to bump the version, tweak the style, etc, you'll need to rebuild the assets. Make sure you have NodeJS >= v10 installed, and then run the following from inside the theme's directory:
This theme uses the [Bootstrap](https://getbootstrap.com/) framework. A static version of this is already included, but if you want to bump the version, tweak the style, etc, you'll need to rebuild the assets. Make sure you have Node.js >= v14 installed, and then run the following from inside the theme's directory:
```console
$ npm install

View File

@ -1,6 +0,0 @@
.cc-window{opacity:1;transition:opacity 1s ease}.cc-window.cc-invisible{opacity:0}.cc-animate.cc-revoke{transition:transform 1s ease}.cc-animate.cc-revoke.cc-top{transform:translateY(-2em)}.cc-animate.cc-revoke.cc-bottom{transform:translateY(2em)}.cc-animate.cc-revoke.cc-active.cc-bottom,.cc-animate.cc-revoke.cc-active.cc-top,.cc-revoke:hover{transform:translateY(0)}.cc-grower{max-height:0;overflow:hidden;transition:max-height 1s}
.cc-link,.cc-revoke:hover{text-decoration:underline}.cc-revoke,.cc-window{position:fixed;overflow:hidden;box-sizing:border-box;font-family:Helvetica,Calibri,Arial,sans-serif;font-size:16px;line-height:1.5em;display:-ms-flexbox;display:flex;-ms-flex-wrap:nowrap;flex-wrap:nowrap;z-index:9999}.cc-window.cc-static{position:static}.cc-window.cc-floating{padding:2em;max-width:24em;-ms-flex-direction:column;flex-direction:column}.cc-window.cc-banner{padding:1em 1.8em;width:100%;-ms-flex-direction:row;flex-direction:row}.cc-revoke{padding:.5em}.cc-header{font-size:18px;font-weight:700}.cc-btn,.cc-close,.cc-link,.cc-revoke{cursor:pointer}.cc-link{opacity:.8;display:inline-block;padding:.2em}.cc-link:hover{opacity:1}.cc-link:active,.cc-link:visited{color:initial}.cc-btn{display:block;padding:.4em .8em;font-size:.9em;font-weight:700;border-width:2px;border-style:solid;text-align:center;white-space:nowrap}.cc-banner .cc-btn:last-child{min-width:140px}.cc-highlight .cc-btn:first-child{background-color:transparent;border-color:transparent}.cc-highlight .cc-btn:first-child:focus,.cc-highlight .cc-btn:first-child:hover{background-color:transparent;text-decoration:underline}.cc-close{display:block;position:absolute;top:.5em;right:.5em;font-size:1.6em;opacity:.9;line-height:.75}.cc-close:focus,.cc-close:hover{opacity:1}
.cc-revoke.cc-top{top:0;left:3em;border-bottom-left-radius:.5em;border-bottom-right-radius:.5em}.cc-revoke.cc-bottom{bottom:0;left:3em;border-top-left-radius:.5em;border-top-right-radius:.5em}.cc-revoke.cc-left{left:3em;right:unset}.cc-revoke.cc-right{right:3em;left:unset}.cc-top{top:1em}.cc-left{left:1em}.cc-right{right:1em}.cc-bottom{bottom:1em}.cc-floating>.cc-link{margin-bottom:1em}.cc-floating .cc-message{display:block;margin-bottom:1em}.cc-window.cc-floating .cc-compliance{-ms-flex:1;flex:1}.cc-window.cc-banner{-ms-flex-align:center;align-items:center}.cc-banner.cc-top{left:0;right:0;top:0}.cc-banner.cc-bottom{left:0;right:0;bottom:0}.cc-banner .cc-message{-ms-flex:1;flex:1}.cc-compliance{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-line-pack:justify;align-content:space-between}.cc-compliance>.cc-btn{-ms-flex:1;flex:1}.cc-btn+.cc-btn{margin-left:.5em}
@media print{.cc-revoke,.cc-window{display:none}}@media screen and (max-width:900px){.cc-btn{white-space:normal}}@media screen and (max-width:414px) and (orientation:portrait),screen and (max-width:736px) and (orientation:landscape){.cc-window.cc-top{top:0}.cc-window.cc-bottom{bottom:0}.cc-window.cc-banner,.cc-window.cc-left,.cc-window.cc-right{left:0;right:0}.cc-window.cc-banner{-ms-flex-direction:column;flex-direction:column}.cc-window.cc-banner .cc-compliance{-ms-flex:1;flex:1}.cc-window.cc-floating{max-width:none}.cc-window .cc-message{margin-bottom:1em}.cc-window.cc-banner{-ms-flex-align:unset;align-items:unset}}
.cc-floating.cc-theme-classic{padding:1.2em;border-radius:5px}.cc-floating.cc-type-info.cc-theme-classic .cc-compliance{text-align:center;display:inline;-ms-flex:none;flex:none}.cc-theme-classic .cc-btn{border-radius:5px}.cc-theme-classic .cc-btn:last-child{min-width:140px}.cc-floating.cc-type-info.cc-theme-classic .cc-btn{display:inline-block}
.cc-theme-edgeless.cc-window{padding:0}.cc-floating.cc-theme-edgeless .cc-message{margin:2em 2em 1.5em}.cc-banner.cc-theme-edgeless .cc-btn{margin:0;padding:.8em 1.8em;height:100%}.cc-banner.cc-theme-edgeless .cc-message{margin-left:1em}.cc-floating.cc-theme-edgeless .cc-btn+.cc-btn{margin-left:0}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

12
assets/js/haven.umd.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -91,5 +91,7 @@ summaryLength = 50
# Languages to render
#[languages.en]
#[languages.bg]
# Bulgarian date format is dd.mm.yyyy
#date_format = "02.01.2006"
# vim: ts=2 sw=2 et

View File

@ -28,7 +28,7 @@
- id: cookieLink
translation: ".اعْرَف أَكْثَر"
- id: cookieDismiss
- id: cookieAccept
translation: "!أُوَافِق"
- id: backToTop

View File

@ -28,8 +28,11 @@
- id: cookieLink
translation: "Научете повече."
- id: cookieDismiss
translation: "Разбрах!"
- id: cookieAccept
translation: "Съгласен съм"
- id: cookieDecline
translation: "Не съм съгласен"
- id: backToTop
translation: "Нагоре"

50
i18n/da.yaml Normal file
View File

@ -0,0 +1,50 @@
- id: about
translation: "Om"
- id: home
translation: "Hjem"
- id: recentPosts
translation: "Seneste indlæg"
- id: readMore
translation: "Læs mere"
- id: translations
translation: "Oversættelser"
- id: share
translation: "Del"
- id: paginatorPrevious
translation: "Forrige side"
- id: paginatorNext
translation: "Næste side"
- id: cookieMessage
translation: "Denne hjemmeside anvender cookies."
- id: cookieLink
translation: "Læs mere."
- id: cookieAccept
translation: "OK"
- id: cookieDecline
translation: "Afbryd"
- id: backToTop
translation: "Til toppen"
- id: links
translation: "Links"
- id: authoredBy
translation: "af"
- id: postedIn
translation: "i"
- id: comma
translation: ","

View File

@ -28,11 +28,17 @@
- id: cookieLink
translation: "Weitere Informationen"
- id: cookieDismiss
translation: "OK"
- id: cookieDecline
translation: "Nicht zustimmen"
- id: backToTop
translation: "Zurück zum Anfang"
- id: links
translation: "Links"
- id: authoredBy
translation: "von"
- id: postedIn
translation: "in"

View File

@ -28,8 +28,11 @@
- id: cookieLink
translation: "Learn more."
- id: cookieDismiss
translation: "Got it!"
- id: cookieAccept
translation: "Agree"
- id: cookieDecline
translation: "Disagree"
- id: backToTop
translation: "Back to top"

View File

@ -28,7 +28,7 @@
- id: cookieLink
translation: "Leer más."
- id: cookieDismiss
- id: cookieAccept
translation: "Comprendido!"
- id: backToTop

View File

@ -28,7 +28,7 @@
- id: cookieLink
translation: ".بیشتر بدانید"
- id: cookieDismiss
- id: cookieAccept
translation: "!متوجه شدم"
- id: backToTop

View File

@ -28,7 +28,7 @@
- id: cookieLink
translation: "En savoir plus."
- id: cookieDismiss
- id: cookieAccept
translation: "J'ai compris !"
- id: backToTop

View File

@ -28,7 +28,7 @@
- id: cookieLink
translation: "Pelajari"
- id: cookieDismiss
- id: cookieAccept
translation: "Paham!"
- id: backToTop

View File

@ -28,7 +28,7 @@
- id: cookieLink
translation: "Lees hier meer"
- id: cookieDismiss
- id: cookieAccept
translation: "OK"
- id: backToTop

View File

@ -28,7 +28,7 @@
- id: cookieLink
translation: "Lær mer."
- id: cookieDismiss
- id: cookieAccept
translation: "Greit!"
- id: backToTop

View File

@ -28,5 +28,5 @@
- id: cookieLink
translation: "Saiba mais."
- id: cookieDismiss
- id: cookieAccept
translation: "Ok!"

View File

@ -28,7 +28,7 @@
- id: cookieLink
translation: "進一步瞭解。"
- id: cookieDismiss
- id: cookieAccept
translation: "知道了!"
- id: backToTop

View File

@ -31,9 +31,7 @@
{{ printf `<link rel="%s" type="%s" href="%s" title="%s" />` .Rel .MediaType.Type .Permalink $.Site.Title | safeHTML }}
{{ end -}}
{{ template "_internal/google_analytics_async.html" . }}
{{ if .Site.Params.cookie_consent_info_url }}
{{ if .Site.GoogleAnalytics }}
{{ partial "cookie-consent.html" . }}
{{ end }}

View File

@ -3,7 +3,7 @@
<article class="blog-post">
<header>
<h2 class="blog-post-title" dir="auto"><a href="{{ .Permalink }}">{{ .Title | markdownify }}</a></h2>
<p class="blog-post-meta"><time datetime="{{ .Date.Format "2006-01-02T15:04:05Z07:00" }}">{{ .Date.Format $dateFormat }}</time> {{ i18n "authoredBy" }} {{ .Params.author | default .Site.Params.author }}{{ if or (.Params.categories) (.Params.tags) }} {{ i18n "postedIn" }} {{ partial "meta-terms.html" . }}{{ end }}</p>
<p class="blog-post-meta"><time {{ .Date.Format "2006-01-02T15:04:05Z07:00" | printf "datetime=%q" | safeHTMLAttr }}>{{ .Date.Format $dateFormat }}</time> {{ i18n "authoredBy" }} {{ .Params.author | default .Site.Params.author }}{{ if or (.Params.categories) (.Params.tags) }} {{ i18n "postedIn" }} {{ partial "meta-terms.html" . }}{{ end }}</p>
</header>
{{ .Content }}
</article> <!-- /.blog-post -->

View File

@ -4,21 +4,22 @@
"@context": "http://schema.org",
"@type": "Blog",
{{- /* Google recommends the headline be no more than 110 characters */}}
"headline": "{{ substr .Site.Title 0 110 }}",
"url" : "{{ printf "%s" .Permalink }}",
"headline": {{ substr .Site.Title 0 110 }},
"url" : {{ printf "%s" .Permalink }},
"author": {
"@type": "Person",
"name": "{{ .Site.Params.author }}"
"name": {{ .Site.Params.author }}
},
{{- $ISO8601 := "2006-01-02T15:04:05-07:00" }}
{{- if not .Date.IsZero }}
"dateModified": {{ .Date.Format $ISO8601 }},
{{- end }}
{{- /* all of the site's categories/tags, from Hugo's tpl/template_embedded.go */}}
"keywords": "{{ range $plural, $terms := .Site.Taxonomies }}{{ range $term, $val := $terms }}{{ printf "%s," $term }}{{ end }}{{ end }}"
{{- $keywords := slice }}{{ range $plural, $terms := .Site.Taxonomies }}{{ range $term, $val := $terms }}{{ $keywords = $keywords | append $term }}{{ end }}{{ end }}
"keywords": {{ delimit $keywords ", " }}
{{- with .Site.Params.description -}}
,
"description": "{{- . -}}"
"description": {{- . -}}
{{- end }}
}
</script>

View File

@ -6,22 +6,32 @@
"@context": "http://schema.org",
"@type": "BlogPosting",
{{- /* Google recommends the headline be no more than 110 characters */}}
"headline": "{{ substr .Title 0 110 }}",
{{- with .Params.images -}}{{ range first 1 . }}
"headline": {{ substr .Title 0 110 }},
{{- with .Params.images -}}{{- range first 1 . -}}
{{/* try to get the image from the page bundle */}}
{{- with $.Page.Resources.GetMatch (printf "*%s*" .) }}
"image": {
"@type": "ImageObject",
"url": "{{ . | absURL }}"
"url": {{ .Permalink }},
"height": "{{ .Height }}",
"width": "{{ .Width }}"
{{/* otherwise, get the image from static */}}
{{- else }}
"image": {
"@type": "ImageObject",
{{- $image := . -}}
{{- /* Don't try to get imageConfig if image param is not local */ -}}
{{- if not (or (hasPrefix . "http://") (hasPrefix . "https://")) -}}
{{- with (imageConfig (printf "/static/%s" .)) -}}
,
{{- with (imageConfig (printf "/static/%s" .)) }}
"url": {{ $image | absURL }},
"height": "{{ .Height }}",
"width": "{{ .Width }}"
{{- end -}}
{{ end }}
{{- end -}}
{{ end }}
},
{{- end -}}{{ end }}
"url": "{{ printf "%s" .Permalink }}",
"url": {{ printf "%s" .Permalink }},
"wordCount": "{{ .WordCount }}",
{{- $ISO8601 := "2006-01-02T15:04:05-07:00" }}
{{- if not .PublishDate.IsZero }}
@ -34,16 +44,16 @@
{{- end }}
"author": {
"@type": "Person",
"name": "{{ .Params.author | default .Site.Params.author }}"
"name": {{ .Params.author | default .Site.Params.author }}
}
{{- if or (.Params.keywords) (or (.Params.categories) (.Params.tags)) -}}
,
"keywords": "{{ delimit (union .Params.keywords (union .Params.categories .Params.tags)) ", " }}"
"keywords": {{ delimit (union .Params.keywords (union .Params.categories .Params.tags)) ", " }}
{{- end }}
{{- with .Params.description -}}
,
"description": "{{ . }}"
"description": {{ . }}
{{- end }}
}
</script>
@ -56,7 +66,9 @@
<article class="blog-post">
<header>
<h2 class="blog-post-title" dir="auto"><a href="{{ .Permalink }}">{{ .Title | markdownify }}</a></h2>
<p class="blog-post-meta"><time datetime="{{ .Date.Format "2006-01-02T15:04:05Z07:00" }}">{{ .Date.Format $dateFormat }}</time> {{ i18n "authoredBy" }} {{ .Params.author | default .Site.Params.author }}{{ if or (.Params.categories) (.Params.tags) }} {{ i18n "postedIn" }} {{ partial "meta-terms.html" . }}{{ end }}</p>
<p class="blog-post-meta">
{{ if not .PublishDate.IsZero }}<time {{ .Date.Format "2006-01-02T15:04:05Z07:00" | printf "datetime=%q" | safeHTMLAttr }}>{{ .Date.Format $dateFormat }}</time>{{ end }}
{{ if or (.Params.categories) (.Params.tags) }} {{ i18n "postedIn" }} {{ partial "meta-terms.html" . }}{{ end }}</p>
</header>
{{ .Content }}

View File

@ -3,7 +3,7 @@
<article class="blog-post">
<header>
<h2 class="blog-post-title" dir="auto"><a href="{{ .Permalink }}">{{ .Title | markdownify }}</a></h2>
<p class="blog-post-meta"><time datetime="{{ .Date.Format "2006-01-02T15:04:05Z07:00" }}">{{ .Date.Format $dateFormat }}</time> {{ i18n "authoredBy" }} {{ .Params.author | default .Site.Params.author }}{{ if or (.Params.categories) (.Params.tags) }} {{ i18n "postedIn" }} {{ partial "meta-terms.html" . }}{{ end }}</p>
<p class="blog-post-meta"><time {{ .Date.Format "2006-01-02T15:04:05Z07:00" | printf "datetime=%q" | safeHTMLAttr }}>{{ .Date.Format $dateFormat }}</time> {{ i18n "authoredBy" }} {{ .Params.author | default .Site.Params.author }}{{ if or (.Params.categories) (.Params.tags) }} {{ i18n "postedIn" }} {{ partial "meta-terms.html" . }}{{ end }}</p>
</header>
{{ .Summary }}
<a href='{{ .Permalink }}'>{{ i18n "readMore" }}</a>

View File

@ -1,28 +1,40 @@
{{ $cookieConsentStyle := resources.Get "css/cookieconsent.min.css" | resources.Fingerprint }}
<link href="{{ $cookieConsentStyle.Permalink }}" rel="stylesheet" type="text/css"{{ if not .Site.Params.disable_sri }} integrity="{{ $cookieConsentStyle.Data.Integrity }}" crossorigin="anonymous"{{ end }}>
{{ $cookieConsentScript := resources.Get "js/cookieconsent.min.js" | resources.Fingerprint }}
<script src="{{ $cookieConsentScript.Permalink }}"{{ if not .Site.Params.disable_sri }} integrity="{{ $cookieConsentScript.Data.Integrity }}" crossorigin="anonymous"{{ end }} async></script>
{{ $cookieConsentScript := resources.Get "js/haven.umd.min.js" | resources.Fingerprint }}
<script src="{{ $cookieConsentScript.Permalink }}"{{ if not .Site.Params.disable_sri }} integrity="{{ $cookieConsentScript.Data.Integrity }}" crossorigin="anonymous"{{ end }}></script>
<script>
window.addEventListener("load", function(){
window.cookieconsent.initialise({
"palette": {
"popup": {
"background": "#428bca",
"text": "#ffffff"
},
"button": {
"background": "#f71559"
}
Haven.create({
notification: {
{{ with .Site.Params.cookie_consent_info_url -}}
policyUrl: {{ . | absURL }},
{{- end }}
styles: {
background: '#428bca',
textColor: '#ffffff',
buttonBackgroundColor: '#f71559',
buttonTextColor: '#ffffff',
},
},
"content": {
"message": '{{ i18n "cookieMessage" }}',
"dismiss": '{{ i18n "cookieDismiss" }}',
"link": '{{ i18n "cookieLink" }}',
"href": "{{ .Site.Params.cookie_consent_info_url | absURL}}"
translations: {
{{ .Lang }}: {
notification: {
policy: '{{ i18n "cookieLink" }}',
message: '{{ i18n "cookieMessage" }}',
accept: '{{ i18n "cookieAccept" }}',
decline: '{{ i18n "cookieDecline" }}',
}
},
},
"position": "bottom-right"
})});
services: [
{
name: 'google-analytics',
options: {
id: {{ .Site.GoogleAnalytics }},
},
purposes: ['analytics'],
inject: true,
}
]
});
</script>
{{- /* vim: set ts=2 sw=2 et: */}}

View File

@ -1,8 +1,8 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
{{ template "_internal/opengraph.html" . }}
{{ template "_internal/twitter_cards.html" . }}
{{ partial "opengraph.html" . }}
{{ partial "twitter_cards.html" . }}
{{- with .Site.Params.google_verify_meta -}}
<meta name="google-site-verification" content="{{ . }}" />

View File

@ -0,0 +1,73 @@
<!--
Import Hugo's internal twitter_cards.html template to add support for resolving
images in page bundles and with falling back to the default of looking in the
static assets directory.
See: tpl/tplimpl/embedded/templates/opengraph.html
See: https://github.com/gohugoio/hugo/issues/5078
-->
<meta property="og:title" content="{{ .Title }}" />
<meta property="og:description" content="{{ with .Description }}{{ . }}{{ else }}{{if .IsPage}}{{ .Summary }}{{ else }}{{ with .Site.Params.description }}{{ . }}{{ end }}{{ end }}{{ end }}" />
<meta property="og:type" content="{{ if .IsPage }}article{{ else }}website{{ end }}" />
<meta property="og:url" content="{{ .Permalink }}" />
{{ with $.Params.images }}{{ range first 6 . -}}
{{/* try to get the image from the page bundle */}}
{{- with $.Page.Resources.GetMatch (printf "*%s*" .) -}}
<meta property="og:image" content="{{ .Permalink }}" />
{{/* otherwise, get the image from /static */}}
{{- else -}}
<meta property="og:image" content="{{ . | absURL }}" />
{{- end }}
{{ end }}{{ else -}}
{{- $images := $.Resources.ByType "image" -}}
{{- $featured := $images.GetMatch "*feature*" -}}
{{- if not $featured }}{{ $featured = $images.GetMatch "{*cover*,*thumbnail*}" }}{{ end -}}
{{- with $featured -}}
<meta property="og:image" content="{{ $featured.Permalink }}"/>
{{ else -}}
{{- with $.Site.Params.images -}}
<meta property="og:image" content="{{ index . 0 | absURL }}"/>
{{ end }}{{ end }}{{ end }}
{{- $iso8601 := "2006-01-02T15:04:05-07:00" -}}
{{- if .IsPage }}
{{- if not .PublishDate.IsZero }}<meta property="article:published_time" {{ .PublishDate.Format $iso8601 | printf "content=%q" | safeHTMLAttr }} />
{{ else if not .Date.IsZero }}<meta property="article:published_time" {{ .Date.Format $iso8601 | printf "content=%q" | safeHTMLAttr }} />
{{ end }}
{{- if not .Lastmod.IsZero }}<meta property="article:modified_time" {{ .Lastmod.Format $iso8601 | printf "content=%q" | safeHTMLAttr }} />{{ end }}
{{- else }}
{{- if not .Date.IsZero }}<meta property="og:updated_time" {{ .Lastmod.Format $iso8601 | printf "content=%q" | safeHTMLAttr }} />
{{- end }}
{{- end }}{{/* .IsPage */}}
{{- with .Params.audio }}<meta property="og:audio" content="{{ . }}" />{{ end }}
{{- with .Params.locale }}<meta property="og:locale" content="{{ . }}" />{{ end }}
{{- with .Site.Params.title }}<meta property="og:site_name" content="{{ . }}" />{{ end }}
{{- with .Params.videos }}
{{- range . }}
<meta property="og:video" content="{{ . | absURL }}" />
{{ end }}{{ end }}
{{- /* If it is part of a series, link to related articles */}}
{{- $permalink := .Permalink }}
{{- $siteSeries := .Site.Taxonomies.series }}{{ with .Params.series }}
{{- range $name := . }}
{{- $series := index $siteSeries $name }}
{{- range $page := first 6 $series.Pages }}
{{- if ne $page.Permalink $permalink }}<meta property="og:see_also" content="{{ $page.Permalink }}" />{{ end }}
{{- end }}
{{ end }}{{ end }}
{{- if .IsPage }}
{{- range .Site.Authors }}{{ with .Social.facebook }}
<meta property="article:author" content="https://www.facebook.com/{{ . }}" />{{ end }}{{ with .Site.Social.facebook }}
<meta property="article:publisher" content="https://www.facebook.com/{{ . }}" />{{ end }}
<meta property="article:section" content="{{ .Section }}" />
{{- with .Params.tags }}{{ range first 6 . }}
<meta property="article:tag" content="{{ . }}" />{{ end }}{{ end }}
{{- end }}{{ end }}
{{- /* Facebook Page Admin ID for Domain Insights */}}
{{- with .Site.Social.facebook_admin }}<meta property="fb:admins" content="{{ . }}" />{{ end }}

View File

@ -0,0 +1,42 @@
<!--
Import Hugo's internal twitter_cards.html template to add support for resolving
images in page bundles and with falling back to the default of looking in the
static assets directory.
See: tpl/tplimpl/embedded/templates/twitter_cards.html
See: https://github.com/gohugoio/hugo/issues/5078
-->
{{- with $.Params.images -}}
<meta name="twitter:card" content="summary_large_image"/>
{{/* try to get the image from the page bundle */}}
{{- with $.Page.Resources.GetMatch (printf "*%s*" .) -}}
<meta name="twitter:image" content="{{ .Permalink }}"/>
{{- else -}}
<meta name="twitter:image" content="{{ index . 0 | absURL }}"/>
{{- end -}}
{{ else -}}
{{- $images := $.Resources.ByType "image" -}}
{{- $featured := $images.GetMatch "*feature*" -}}
{{- if not $featured }}{{ $featured = $images.GetMatch "{*cover*,*thumbnail*}" }}{{ end -}}
{{- with $featured -}}
<meta name="twitter:card" content="summary_large_image"/>
<meta name="twitter:image" content="{{ $featured.Permalink }}"/>
{{- else -}}
{{- with $.Site.Params.images -}}
<meta name="twitter:card" content="summary_large_image"/>
<meta name="twitter:image" content="{{ index . 0 | absURL }}"/>
{{ else -}}
<meta name="twitter:card" content="summary"/>
{{- end -}}
{{- end -}}
{{- end }}
<meta name="twitter:title" content="{{ .Title }}"/>
<meta name="twitter:description" content="{{ with .Description }}{{ . }}{{ else }}{{if .IsPage}}{{ .Summary }}{{ else }}{{ with .Site.Params.description }}{{ . }}{{ end }}{{ end }}{{ end -}}"/>
{{ with .Site.Social.twitter -}}
<meta name="twitter:site" content="@{{ . }}"/>
{{ end -}}
{{ range .Site.Authors }}
{{ with .twitter -}}
<meta name="twitter:creator" content="@{{ . }}"/>
{{ end -}}
{{ end -}}

View File

@ -0,0 +1,92 @@
{{/*
figure with auto-resizing and srcset v2020-11-30
Drop-in replacement for Hugo's figure shortcode as of 2020-05-02 that uses img srcset
to enable browsers to download only the resolution that they need.
The resizing and srcset magic only works for images that are part of the page
bundle. It will fall back to stock Hugo figure behaviour otherwise.
Improvements that were initially out of reach of my Hugo template programming "skills"
but have now been taken care of:
- [x] gracefully handle images that are not in page bundle, i.e. no image processing available
- [x] use a single configurable sizes array, and derive everything from there
See https://cpbotha.net/2020/05/02/drop-in-replacement-for-hugo-figure-shortcode-with-img-srcset-support/
- original srcset img shortcode from: https://laurakalbag.com/processing-responsive-images-with-hugo/
- original hugo figure shortcode from: https://github.com/gohugoio/hugo/blob/master/tpl/tplimpl/embedded/templates/shortcodes/figure.html
- no unnecessary resizes and more nudges by Stéfan van der Walt https://mentat.za.net/
- mashing together and srcset logic fixes by Charl P. Botha https://cpbotha.net/
Changes:
- 2020-11-30 handle images that are rotated 90 degrees (should handle more eventually)
- 2020-05-10 fall back to stock Hugo behaviour when no page bundle found
- 2020-05-04 no unnecessary resizes, sizes in array
- 2020-05-02 initial release
*/}}
{{/* hugo will resize to all of these sizes that are smaller than your original. configure if you like! */}}
{{ $sizes := (slice "480" "800" "1200" "1500") }}
{{/* get file that matches the filename as specified as src="" in shortcode */}}
{{ $src := .Page.Resources.GetMatch (printf "*%s*" (.Get "src")) }}
<figure{{ with .Get "class" }} class="{{ . }}"{{ end }}>
{{- if .Get "link" -}}
<a href="{{ .Get "link" }}"{{ with .Get "target" }} target="{{ . }}"{{ end }}{{ with .Get "rel" }} rel="{{ . }}"{{ end }}>
{{- end }}
<img
{{ if $src }}
sizes="(min-width: 35em) 1200px, 100vw"
{{/* only srcset images smaller than or equal to the src (original) image size, as Hugo will upscale small images */}}
srcset='
{{ range $sizes }}
{{ $size := . }}
{{/* https://discourse.gohugo.io/t/image-exif-orientation/22902/7 */}}
{{/* set orientation to 1 just in case it doesnt exist in Exif */}}
{{ $orientation := 1 }}
{{ with $src.Exif }}
{{ $orientation := .Tags.Orientation }}
{{ if and (ge $src.Width $size) (eq $orientation 8) }}
{{ ($src.Resize (printf "%sx r90" $size)).Permalink }} {{ (printf "%sw" $size) }},
{{ else if ge $src.Width $size }}{{ ($src.Resize (printf "%sx" $size)).Permalink }} {{ (printf "%sw" $size) }},{{ end }}
{{ end }}
{{ end }}'
{{/* when no support for srcset (old browsers, RSS), we load small (800px) */}}
{{/* if image smaller than 800, then load the image itself */}}
{{ if ge $src.Width "800" }}src="{{ ($src.Resize "800x").Permalink }}"
{{ else }}src="{{ $src.Permalink }}"
{{ end }}
{{ else }}
{{/* fall back to stock hugo behaviour when image is not available in bundle */}}
src="{{ .Get "src" }}"
{{ end }}
{{- if or (.Get "alt") (.Get "caption") }}
alt="{{ with .Get "alt" }}{{ . }}{{ else }}{{ .Get "caption" | markdownify| plainify }}{{ end }}"
{{- end -}}
{{- with .Get "width" }} width="{{ . }}"{{ end -}}
{{- with .Get "height" }} height="{{ . }}"{{ end -}}
/> <!-- Closing img tag -->
{{- if .Get "link" }}</a>{{ end -}}
{{- if or (or (.Get "title") (.Get "caption")) (.Get "attr") -}}
<figcaption>
{{ with (.Get "title") -}}
<h4>{{ . }}</h4>
{{- end -}}
{{- if or (.Get "caption") (.Get "attr") -}}<p>
{{- .Get "caption" | markdownify -}}
{{- with .Get "attrlink" }}
<a href="{{ . }}">
{{- end -}}
{{- .Get "attr" | markdownify -}}
{{- if .Get "attrlink" }}</a>{{ end }}</p>
{{- end }}
</figcaption>
{{- end }}
</figure>

7700
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,32 +1,31 @@
{
"name": "hugo-theme-bootstrap4-blog",
"version": "1.3.3",
"version": "1.6.0",
"description": "A Bootstrap v4 theme for the Hugo static site generator.",
"repository": {
"type": "git",
"url": "https://github.com/alanorth/hugo-theme-bootstrap4-blog.git"
},
"scripts": {
"build:css": "node-sass --output-style expanded --precision 6 source/scss/style.scss assets/css/style.css.tmp && cleancss --level 1 assets/css/style.css.tmp -o assets/css/style.css",
"build:rtlcss": "rtlcss -s assets/css/style.css.tmp assets/css/style.rtl.css.tmp && cleancss --level 1 assets/css/style.rtl.css.tmp -o assets/css/style.rtl.css",
"build:cookieconsent": "cp node_modules/cookieconsent/build/cookieconsent.min.css assets/css && cp node_modules/cookieconsent/build/cookieconsent.min.js assets/js",
"build:css": "sass --style expanded source/scss/style.scss assets/css/style.css.tmp && cleancss -O1 assets/css/style.css.tmp -o assets/css/style.css",
"build:rtlcss": "rtlcss -s assets/css/style.css.tmp assets/css/style.rtl.css.tmp && cleancss -O1 assets/css/style.rtl.css.tmp -o assets/css/style.rtl.css",
"build:cookieconsent": "cp node_modules/@chiiya/haven/dist/haven.umd.min.js assets/js",
"build:js": "webpack",
"build": "npm run build:css && npm run build:rtlcss && npm run build:js && npm run build:cookieconsent && npm run clean",
"clean": "rm assets/css/style.css.tmp assets/css/style.rtl.css.tmp"
"clean": "rm assets/css/style.css.tmp assets/css/style.css.tmp.map assets/css/style.rtl.css.tmp"
},
"keywords": "hugo",
"author": "Alan Orth",
"license": "CC-BY-3.0",
"devDependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.26",
"@fortawesome/free-brands-svg-icons": "^5.12.0",
"@fortawesome/free-solid-svg-icons": "^5.12.0",
"bootstrap": "~4.4.1",
"clean-css-cli": "^4.3.0",
"cookieconsent": "3.0.4",
"node-sass": "^4.13.1",
"rtlcss": "^2.4.1",
"webpack": "^4.41.5",
"webpack-cli": "^3.3.10"
"@chiiya/haven": "^0.7.0",
"@fortawesome/fontawesome-svg-core": "^1.2.34",
"@fortawesome/free-brands-svg-icons": "^5.15.2",
"@fortawesome/free-solid-svg-icons": "^5.15.2",
"bootstrap": "^4.6.0",
"clean-css-cli": "^5.4.1",
"rtlcss": "^3.3.0",
"sass": "^1.43.2",
"webpack-cli": "^4.9.1"
}
}

View File

@ -1,44 +1,44 @@
/*!
* Bootstrap v4.4.1 (https://getbootstrap.com/)
* Copyright 2011-2019 The Bootstrap Authors
* Copyright 2011-2019 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Bootstrap v4.6.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
@import "node_modules/bootstrap/scss/functions";
@import "node_modules/bootstrap/scss/variables";
@import "node_modules/bootstrap/scss/mixins";
//@import "node_modules/bootstrap/scss/root";
@import "node_modules/bootstrap/scss/reboot";
@import "node_modules/bootstrap/scss/type";
@import "node_modules/bootstrap/scss/images";
@import "node_modules/bootstrap/scss/code";
@import "node_modules/bootstrap/scss/grid";
//@import "node_modules/bootstrap/scss/tables";
@import "node_modules/bootstrap/scss/forms";
@import "node_modules/bootstrap/scss/buttons";
//@import "node_modules/bootstrap/scss/transitions";
//@import "node_modules/bootstrap/scss/dropdown";
//@import "node_modules/bootstrap/scss/button-group";
//@import "node_modules/bootstrap/scss/input-group";
//@import "node_modules/bootstrap/scss/custom-forms";
@import "node_modules/bootstrap/scss/nav";
@import "node_modules/bootstrap/scss/navbar";
//@import "node_modules/bootstrap/scss/card";
//@import "node_modules/bootstrap/scss/breadcrumb";
@import "node_modules/bootstrap/scss/pagination";
//@import "node_modules/bootstrap/scss/badge";
//@import "node_modules/bootstrap/scss/jumbotron";
//@import "node_modules/bootstrap/scss/alert";
//@import "node_modules/bootstrap/scss/progress";
//@import "node_modules/bootstrap/scss/media";
//@import "node_modules/bootstrap/scss/list-group";
//@import "node_modules/bootstrap/scss/close";
//@import "node_modules/bootstrap/scss/toasts";
//@import "node_modules/bootstrap/scss/modal";
//@import "node_modules/bootstrap/scss/tooltip";
//@import "node_modules/bootstrap/scss/popover";
//@import "node_modules/bootstrap/scss/carousel";
//@import "node_modules/bootstrap/scss/spinners";
@import "node_modules/bootstrap/scss/utilities";
@import "node_modules/bootstrap/scss/print";
@import "../../node_modules/bootstrap/scss/functions";
@import "../../node_modules/bootstrap/scss/variables";
@import "../../node_modules/bootstrap/scss/mixins";
@import "../../node_modules/bootstrap/scss/root";
@import "../../node_modules/bootstrap/scss/reboot";
@import "../../node_modules/bootstrap/scss/type";
@import "../../node_modules/bootstrap/scss/images";
@import "../../node_modules/bootstrap/scss/code";
@import "../../node_modules/bootstrap/scss/grid";
@import "../../node_modules/bootstrap/scss/tables";
@import "../../node_modules/bootstrap/scss/forms";
@import "../../node_modules/bootstrap/scss/buttons";
//@import "../../node_modules/bootstrap/scss/transitions";
//@import "../../node_modules/bootstrap/scss/dropdown";
//@import "../../node_modules/bootstrap/scss/button-group";
//@import "../../node_modules/bootstrap/scss/input-group";
//@import "../../node_modules/bootstrap/scss/custom-forms";
@import "../../node_modules/bootstrap/scss/nav";
@import "../../node_modules/bootstrap/scss/navbar";
//@import "../../node_modules/bootstrap/scss/card";
//@import "../../node_modules/bootstrap/scss/breadcrumb";
@import "../../node_modules/bootstrap/scss/pagination";
//@import "../../node_modules/bootstrap/scss/badge";
//@import "../../node_modules/bootstrap/scss/jumbotron";
//@import "../../node_modules/bootstrap/scss/alert";
//@import "../../node_modules/bootstrap/scss/progress";
//@import "../../node_modules/bootstrap/scss/media";
//@import "../../node_modules/bootstrap/scss/list-group";
//@import "../../node_modules/bootstrap/scss/close";
//@import "../../node_modules/bootstrap/scss/toasts";
//@import "../../node_modules/bootstrap/scss/modal";
//@import "../../node_modules/bootstrap/scss/tooltip";
//@import "../../node_modules/bootstrap/scss/popover";
//@import "../../node_modules/bootstrap/scss/carousel";
//@import "../../node_modules/bootstrap/scss/spinners";
@import "../../node_modules/bootstrap/scss/utilities";
@import "../../node_modules/bootstrap/scss/print";

View File

@ -1,6 +1,6 @@
// selectively import components we need from bootstrap
// see: node_modules/bootstrap/scss/bootstrap.scss
@import 'source/scss/bootstrap';
@import 'bootstrap';
// local style overrides
@import 'source/scss/main';
@import 'main';

View File

@ -3,13 +3,14 @@ license = "CC-BY-3.0"
licenselink = "https://github.com/alanorth/hugo-theme-bootstrap4-blog/blob/master/LICENSE.txt"
description = "A simple Hugo theme based on the Bootstrap v4 blog example."
homepage = "https://github.com/alanorth/hugo-theme-bootstrap4-blog"
demosite = "https://picturingjordan.com"
tags = ["bootstrap", "blog", "font awesome"]
features = ["responsive", "blog"]
min_version = 0.55
[author]
name = "Alan Orth"
homepage = "https://englishbulgaria.net"
homepage = "https://picturingjordan.com"
[original]
author = "mdo"