Skip to content

Conversation

srgg
Copy link
Contributor

@srgg srgg commented Sep 8, 2025

Purpose

Add support for string per-side spacing values and enhance Hugo Blox spacing to handle all padding formats consistently at both block and page levels.

Changes:

  • Add support for string per-side values: spacing: "2rem 0 0 0"
  • Implement unified block-to-page spacing fallback logic

Documentation

The Spacing section at Build your pages with blocks: no-code
required!
needs to be updated with alternative string array
format examples:

# New supported formats:
design:
  spacing: "2rem 0 0 0"  # Per-side string format

# OR
design:
  spacing:
    padding: ["2rem", "0", "0", "0"]  # Nested array format

Copy link

netlify bot commented Sep 8, 2025

Deploy Preview for academic-demo ready!

Name Link
🔨 Latest commit 82766a9
🔍 Latest deploy log https://app.netlify.com/projects/academic-demo/deploys/68c40ce95314fb000857906f
😎 Deploy Preview https://deploy-preview-3249--academic-demo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

  Add support for string per-side values and nested array formats:
  - spacing: "2rem 0 0 0"
  - spacing: { padding: ["2rem", "0", "0", "0"] }
  - unified block-to-page spacing fallback logic
@srgg srgg force-pushed the feature/support-padding-string-array-in-block-spacing branch from 1fd4d5e to 82766a9 Compare September 12, 2025 12:07
@gcushen
Copy link
Collaborator

gcushen commented Sep 15, 2025

@srgg users tend to get confused when there are multiple ways to perform the same action. Let's evaluate the most intuitive structure and stick with it rather than giving users options to use different data structures (string vs array).

@srgg
Copy link
Contributor Author

srgg commented Sep 15, 2025

@gcushen IMHO, spacing: "2rem 0 0 0" per-side string format feels more in line with the style of Hugo Blox than spacing: padding: ["2rem", "0", "0", "0"].

If I’m not mistaken, Hugo Blox already supports the simpler spacing: "2rem" (non-array syntax). To me, the per-side string format feels more intuitive and closer to native CSS.

Please let me know which direction you’d prefer. I’m happy to adjust accordingly, or feel free to close this PR if you’d rather stick with the array notation.

@gcushen
Copy link
Collaborator

gcushen commented Sep 15, 2025

@srgg so, the spacing param originates from the old Bootstrap version of Hugo Blox. With the newer Tailwind styled Hugo Blox, let's migrate from spacing to padding to align with web best practices and accept a responsive Tailwind style string instead of REMs (REMs can still be included via Tailwind bracket syntax anyway).

Example front matter:

padding: "pt-8 md:pt-16 pb-0"

Example code:

{{- /* layouts/partials/ui/padding_classes.html */ -}}
{{- $p := . -}}
{{- $val := $p.Params.padding -}}
{{- $out := "" -}}

{{- if (isa $val "string") -}}
  {{- $out = strings.TrimSpace $val -}}
{{- else if (reflect.IsSlice $val) -}}
  {{- /* Accept list of strings as convenience, but don't document it */ -}}
  {{- $out = delimit $val " " | strings.TrimSpace -}}
{{- else if $val -}}
  {{- $where := cond ($p.File) $p.File.Path "unknown" -}}
  {{- warnf "Hugo Blox: `padding` must be a string (or list of strings) in %q. Got: %T" $where $val -}}
{{- end -}}

{{- with $p.Params.spacing -}}
  {{- $where := cond ($p.File) $p.File.Path "unknown" -}}
  {{- warnf "Hugo Blox: `spacing` is deprecated in %q. Convert to Tailwind `padding` (e.g., `pt-8 md:py-12`). Found: %v" $where . -}}
  {{- /* Optional fallback: map CSS-like spacing tokens to Tailwind arbitrary classes */ -}}
  {{- $tok := slice -}}
  {{- if (isa . "string") -}}{{ $tok = (split . " ") | complement (slice "") }}
  {{- else if (reflect.IsSlice .) -}}{{ range . }}{{ $tok = $tok | append (printf "%v" .) }}{{ end }}{{ end -}}
  {{- if gt (len $tok) 0 -}}
    {{- $t := index $tok 0 -}}
    {{- $r := cond (ge (len $tok) 2) (index $tok 1) $t -}}
    {{- $b := cond (ge (len $tok) 3) (index $tok 2) $t -}}
    {{- $l := cond (ge (len $tok) 4) (index $tok 3) $r -}}
    {{- $emit := func (side string, v string) -}}
      {{- $zero := in (slice "0" "0px" "0rem") (strings.TrimSpace v) -}}
      {{- $suf := cond $zero "0" (printf "[%s]" v) -}}
      {{- $out = print $out " " (printf "%s-%s" side $suf) | strings.TrimSpace -}}
    {{- end -}}
    {{- if and (eq $t $r) (eq $r $b) (eq $b $l) -}}
      {{- $emit "p" $t -}}
    {{- else if and (eq $t $b) (eq $r $l) -}}
      {{- $emit "py" $t -}}{{- $emit "px" $r -}}
    {{- else -}}
      {{- $emit "pt" $t -}}{{- $emit "pr" $r -}}{{- $emit "pb" $b -}}{{- $emit "pl" $l -}}
    {{- end -}}
  {{- end -}}
{{- end -}}

{{- return $out -}}

template example:

{{ $pad := partial "ui/padding_classes.html" . }}
<section class="{{ $pad }}">
  …
</section>

Tailwind v4 should discover the classes via the dynamically generated hugo_stats.json

@gcushen
Copy link
Collaborator

gcushen commented Sep 15, 2025

To simplify the code, we might consider leaving out the Optional fallback part especially if it's not robust to all use cases users might have in their sites.

@srgg
Copy link
Contributor Author

srgg commented Sep 15, 2025

@gcushen I see now — thank you for providing the details.

If I understood you correctly, you’re considering removing spacing: "2rem". That’s fine with me, though it would be a breaking change.

Just my consideration: an average user who wants to experiment with these things is more likely to adjust layouts and paddings directly in DevTools rather than work with Tailwind styles, since the latter requires a deeper level of involvement.

Anyway, handling padding without nesting it under spacing feels much more logical to me personally — whether it’s a string, a string array, or an array of strings.

@gcushen
Copy link
Collaborator

gcushen commented Sep 16, 2025

@gcushen I see now — thank you for providing the details.

If I understood you correctly, you’re considering removing spacing: "2rem". That’s fine with me, though it would be a breaking change.

Just my consideration: an average user who wants to experiment with these things is more likely to adjust layouts and paddings directly in DevTools rather than work with Tailwind styles, since the latter requires a deeper level of involvement.

Anyway, handling padding without nesting it under spacing feels much more logical to me personally — whether it’s a string, a string array, or an array of strings.

@srgg Sure, different developers will have experience working with different style frameworks or direct with plain CSS. However, since this is a Tailwind framework for Hugo, let's fully align the code with the overarching principle - a user can still enter Tailwind padding classes via DevTools or enter REM/px/etc values via DevTools using Tailwind bracket notation.

It would eventually become a breaking change, however, it would still be supported for now, just with a deprecation warning in the terminal.

Here's the updated example code for you to consider basing the PR on:

layouts/_partials/functions/ui/padding.html

{{- /*
  Hugo Blox — Padding helper (Tailwind-first, legacy fallback)

  INPUT (dict):
    pg   : the page context (usually ".")
    sec  : the current section map (e.g., one item from .Params.sections)
    idx  : (optional) numeric index for clearer warnings

  OUTPUT (dict):
    class : Tailwind class string (preferred path)
    style : inline CSS "padding: ..." (legacy fallback ONLY when class is empty)

  Resolution order:
    1) Section Tailwind   : sec.design.padding             (string of classes)
    2) Page Tailwind      : pg.Params.design.padding       (string of classes)  [page default]
    3) Legacy section     : sec.design.spacing.padding     (array like [0,0,0,0]) → inline CSS
    4) Legacy page        : pg.Params.design.spacing       (string like "6rem") → inline CSS (vertical)

  Notes:
    - We intentionally accept only **string** for Tailwind to keep one canonical format.
    - Legacy code paths are unchanged, including array handling for section spacing.
    - We emit concise warnf messages including the content filename and section pointer.
*/ -}}

{{- $pg := .pg -}}
{{- $sec := .sec | default dict -}}
{{- $idx := .idx | default -1 -}}

{{- $class := "" -}}
{{- $style := "" -}}

{{/* File path for warnings */}}
{{- $where := "unknown" -}}
{{- with $pg.File }}{{ $where = .Path }}{{ end -}}

{{/* Section label for warnings: index, id, or block key */}}
{{- $secLabel := cond (ge $idx 0) (printf "sections[%d]" $idx) "section" -}}
{{- with $sec.id }}{{ $secLabel = printf "%s (id=%q)" $secLabel . }}{{ end -}}
{{- if and (not (in $secLabel "id=")) $sec.block }}{{ $secLabel = printf "%s (block=%q)" $secLabel $sec.block }}{{ end -}}

{{/* --- 1) SECTION TAILWIND: design.padding (string) --- */}}
{{- with $sec.design.padding -}}
  {{- if (eq (printf "%T" .) "string") -}}
    {{- $class = strings.TrimSpace . -}}
  {{- else -}}
    {{- warnf "Hugo Blox: `design.padding` must be a string in %q → %s.design.padding. Got: %T" $where $secLabel . -}}
  {{- end -}}
{{- end -}}

{{/* --- 2) PAGE TAILWIND DEFAULT: page.Params.design.padding (string) --- */}}
{{- if eq $class "" -}}
  {{- with $pg.Params.design.padding -}}
    {{- if (eq (printf "%T" .) "string") -}}
      {{- $class = strings.TrimSpace . -}}
    {{- else -}}
      {{- warnf "Hugo Blox: page-level `design.padding` must be a string in %q. Got: %T" $where . -}}
    {{- end -}}
  {{- end -}}
{{- end -}}

{{/* --- 3) LEGACY SECTION: design.spacing.padding (array) → inline CSS --- */}}
{{- if eq $class "" -}}
  {{- with $sec.design.spacing.padding -}}
    {{- warnf "Hugo Blox: `design.spacing.padding` is deprecated in %q → %s.design.spacing.padding. Use Tailwind `design.padding` (e.g., `pt-8 md:py-12`). Found: %v" $where $secLabel . -}}
    {{- /* Legacy semantics: expect array; join exactly like existing code */ -}}
    {{- $style_pad := printf "padding: %s;" (delimit . " ") -}}
    {{- $style = print $style $style_pad -}}
  {{- end -}}
{{- end -}}

{{/* --- 4) LEGACY PAGE: page.Params.design.spacing (string) → inline vertical CSS --- */}}
{{- if and (eq $class "") (eq $style "") -}}
  {{- with $pg.Params.design.spacing -}}
    {{- if (eq (printf "%T" .) "string") -}}
      {{- warnf "Hugo Blox: page-level `design.spacing` is deprecated in %q. Set per-section Tailwind `design.padding` instead. Found: %v" $where . -}}
      {{- $v := strings.TrimSpace . -}}
      {{- if ne $v "" -}}
        {{- $style = printf "padding: %s 0 %s 0;" $v $v -}}
      {{- end -}}
    {{- else -}}
      {{- warnf "Hugo Blox: expected string for legacy page-level `design.spacing` in %q; got: %T" $where . -}}
    {{- end -}}
  {{- end -}}
{{- end -}}

{{- return (dict "class" $class "style" $style) -}}

And then call it in the following form (may need to also add Hugo's safeCSS like we do in the current code):

{{ range $i, $sec := .Params.sections }}
  {{/* Get Tailwind classes or legacy inline style for padding */}}
  {{ $pad := partial "functions/ui/padding.html" (dict "pg" . "sec" $sec "idx" $i) }}

  <section class="{{ $pad.class }}"{{ with $pad.style }} style="{{ . }}"{{ end }}>
    <!-- block rendering -->
  </section>
{{ end }}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants