From cb9bec2b26be1f4099b9330b70f7e019f2465b90 Mon Sep 17 00:00:00 2001 From: Joe Mooring Date: Tue, 31 Dec 2024 17:43:35 -0500 Subject: [PATCH] tpl/images: Add images.QR function Closes #13205 --- content/en/content-management/shortcodes.md | 102 ++++++++++++++++- content/en/functions/images/QR.md | 115 ++++++++++++++++++++ data/embedded_template_urls.toml | 9 +- 3 files changed, 221 insertions(+), 5 deletions(-) create mode 100644 content/en/functions/images/QR.md diff --git a/content/en/content-management/shortcodes.md b/content/en/content-management/shortcodes.md index 47e4f94ed..afe84e79b 100644 --- a/content/en/content-management/shortcodes.md +++ b/content/en/content-management/shortcodes.md @@ -121,7 +121,7 @@ Hugo renders this to: ``` -The details shortcode accepts these named arguments: +The `details` shortcode accepts these named arguments: summary : (`string`) The content of the child `summary` element rendered from Markdown to HTML. Default is `Details`. @@ -333,6 +333,106 @@ Access nested values by [chaining] the [identifiers]: {{}} ``` +### qr + +{{% note %}} +To override Hugo's embedded `qr` shortcode, copy the [source code] to a file with the same name in the layouts/shortcodes directory. + +[source code]: {{% eturl qr %}} +{{% /note %}} + +The `qr` shortcode encodes the given text into a [QR code] using the specified options and renders the resulting image. + +[QR code]: https://en.wikipedia.org/wiki/QR_code + +Use the self-closing syntax to pass the text as an argument: + +```text +{{}} +``` + +Or insert the text between the opening and closing tags: + +```text +{{}} +https://gohugo.io +{{}} +``` + +Both of the above produce this image: + +{{< qr text="https://gohugo.io" class="qrcode" />}} + +To create a QR code for a phone number: + +```text +{{}} +``` + +{{< qr text="tel:+12065550101" class="qrcode" />}} + +To create a QR code containing contact information in the [vCard] format: + +[vCard]: https://en.wikipedia.org/wiki/VCard + +```text +{{}} +BEGIN:VCARD +VERSION:2.1 +N;CHARSET=UTF-8:Smith;John;R.;Dr.;PhD +FN;CHARSET=UTF-8:Dr. John R. Smith, PhD. +ORG;CHARSET=UTF-8:ABC Widgets +TITLE;CHARSET=UTF-8:Vice President Engineering +TEL;TYPE=WORK:+12065550101 +EMAIL;TYPE=WORK:jsmith@example.org +END:VCARD +{{}} +``` + +{{< qr level="low" scale=2 alt="QR code of vCard for John Smith" class="qrcode" >}} +BEGIN:VCARD +VERSION:2.1 +N;CHARSET=UTF-8:Smith;John;R.;Dr.;PhD +FN;CHARSET=UTF-8:Dr. John R. Smith, PhD. +ORG;CHARSET=UTF-8:ABC Widgets +TITLE;CHARSET=UTF-8:Vice President Engineering +TEL;TYPE=WORK:+12065550101 +EMAIL;TYPE=WORK:jsmith@example.org +END:VCARD +{{< /qr >}} + +Internally this shortcode calls the `images.QR` function. Please read the [related documentation] for implementation details and guidance. + +[related documentation]: /functions/images/qr/ + +The `qr` shortcode accepts these named arguments: + +text +: (`string`) The text to encode, falling back to the text between the opening and closing shortcode tags. + +level +: (`string`) The error correction level to use when encoding the text, one of `low`, `medium`, `quartile`, or `high`. Default is `medium`. + +scale +: (`int`) The number of image pixels per QR code module. Must be greater than or equal to 2. Default is `4`. + +targetDir +: (`string`) The subdirectory within the [`publishDir`] where Hugo will place the generated image. + +[`publishDir`]: /getting-started/configuration/#publishdir + +alt +: (`string`) The `alt` attribute of the `img` element. + +class +: (`string`) The `class` attribute of the `img` element. + +id +: (`string`) The `id` attribute of the `img` element. + +title +: (`string`) The `title` attribute of the `img` element. + ### ref {{% note %}} diff --git a/content/en/functions/images/QR.md b/content/en/functions/images/QR.md new file mode 100644 index 000000000..c1b8fb465 --- /dev/null +++ b/content/en/functions/images/QR.md @@ -0,0 +1,115 @@ +--- +title: images.QR +description: Encodes the given text into a QR code using the specified options, returning an image resource. +keywords: [] +action: + aliases: [] + related: [] + returnType: images.ImageResource + signatures: ['images.QR OPTIONS'] +toc: true +math: true +--- + +{{< new-in 0.141.0 >}} + +The `images.QR` function encodes the given text into a [QR code] using the specified options, returning an image resource. The size of the generated image depends on three factors: + +- Data length: Longer text necessitates a larger image to accommodate the increased information density. +- Error correction level: Higher error correction levels enhance the QR code's resistance to damage, but this typically results in a slightly larger image size to maintain readability. +- Pixels per module: The number of image pixels assigned to each individual module (the smallest unit of the QR code) directly impacts the overall image size. A higher pixel count per module leads to a larger, higher-resolution image. + +Although the default option values are sufficient for most applications, you should test the rendered QR code both on-screen and in print. + +[QR code]: https://en.wikipedia.org/wiki/QR_code + +## Options + +text +: (`string`) The text to encode. + +level +: (`string`) The error correction level to use when encoding the text, one of `low`, `medium`, `quartile`, or `high`. Default is `medium`. + +Error correction level|Redundancy +:--|:--|:-- +low|20% +medium|38% +quartile|55% +high|65% + +scale +: (`int`) The number of image pixels per QR code module. Must be greater than or equal to `2`. Default is `4`. + +targetDir +: (`string`) The subdirectory within the [`publishDir`] where Hugo will place the generated image. Use Unix-style slashes (`/`) to separarate path segments. If empty or not provided, the image is placed directly in the `publishDir` root. Hugo automatically creates the necessary subdirectories if they don't exist. + +[`publishDir`]: /getting-started/configuration/#publishdir + +## Examples + +To create a QR code using the default values for `level` and `scale`: + +```go-html-template +{{ $opts := dict "text" "https://gohugo.io" }} +{{ with images.QR $opts }} + +{{ end }} +``` + +{{< qr text="https://gohugo.io" class="qrcode" />}} + +Specify `level`, `scale`, and `targetDir` as needed to achieve the desired result: + +```go-html-template +{{ $opts := dict + "text" "https://gohugo.io" + "level" "high" + "scale" 3 + "targetDir" "codes" +}} +{{ with images.QR $opts }} + +{{ end }} +``` + +{{< qr text="https://gohugo.io" level="high" scale=3 targetDir="codes" class="qrcode" />}} + +## Scale + +As you decrease the size of a QR code, the maximum distance at which it can be reliably scanned by a device also decreases. + +In the example above, we set the `scale` to `2`, resulting in a QR code where each module consists of 2x2 pixels. While this might be sufficient for on-screen display, it's likely to be problematic when printed at 600 dpi. + +\[ \frac{2\:px}{module} \times \frac{1\:inch}{600\:px} \times \frac{25.4\:mm}{1\:inch} = \frac{0.085\:mm}{module} \] + +This module size is half of the commonly recommended minimum of 0.170 mm.\ +If the QR code will be printed, use the default `scale` value of `4` pixels per module. + +Avoid using Hugo's image processing methods to resize QR codes. Resizing can introduce blurring due to anti-aliasing when a QR code module occupies a fractional number of pixels. + +{{% note %}} +Always test the rendered QR code both on-screen and in print. +{{% /note %}} + +## Shortcode + +Call the `qr` shortcode to insert a QR code into your content. + +Use the self-closing syntax to pass the text as an argument: + +```text +{{}} +``` + +Or insert the text between the opening and closing tags: + +```text +{{}} +https://gohugo.io +{{}} +``` + +The `qr` shortcode accepts several arguments including `level` and `scale`. See the [related documentation] for details. + +[related documentation]: /content-management/shortcodes/#qr diff --git a/data/embedded_template_urls.toml b/data/embedded_template_urls.toml index b7247f272..359105e60 100644 --- a/data/embedded_template_urls.toml +++ b/data/embedded_template_urls.toml @@ -10,18 +10,18 @@ 'google_analytics' = 'google_analytics.html' 'opengraph' = 'opengraph.html' 'pagination' = 'pagination.html' -'schema' = 'schema.html' -'twitter_cards' = 'twitter_cards.html' - 'robots' = '_default/robots.txt' 'rss' = '_default/rss.xml' +'schema' = 'schema.html' 'sitemap' = '_default/sitemap.xml' 'sitemapindex' = '_default/sitemapindex.xml' +'twitter_cards' = 'twitter_cards.html' # Render hooks +'render-codeblock-goat' = '_default/_markup/render-codeblock-goat.html' 'render-image' = '_default/_markup/render-image.html' 'render-link' = '_default/_markup/render-link.html' -'render-codeblock-goat' = '_default/_markup/render-codeblock-goat.html' +'render-table' = '_default/_markup/render-table.html' # Shortcodes 'comment' = 'shortcodes/comment.html' @@ -31,6 +31,7 @@ 'highlight' = 'shortcodes/highlight.html' 'instagram' = 'shortcodes/instagram.html' 'param' = 'shortcodes/param.html' +'qr' = 'shortcodes/qr.html' 'ref' = 'shortcodes/ref.html' 'relref' = 'shortcodes/relref.html' 'twitter' = 'shortcodes/twitter.html'