Skip to content

Instantly share code, notes, and snippets.

@loic-roux-404
Last active December 31, 2020 02:36
Show Gist options
  • Save loic-roux-404/5659fd145e26d7b7c0997197427f2d35 to your computer and use it in GitHub Desktop.
Save loic-roux-404/5659fd145e26d7b7c0997197427f2d35 to your computer and use it in GitHub Desktop.
hugo partials : Deep merge with combination for map and slices

Hugo Map / slice combine

Example usage

Data are converted in json for readability, use go maps in hugo html templates

Base object :
{
"toto": 1,  
"fields":
  [
    "import fields title",
    "import fields enable",
    {
      "label": "Layout",
      "name": "design",
      "options":
        [
          {"label": "Hero Area","value":"hero-area"},
          {"label": "Page title","value":"page-title"},
          {"label": "Section","value":"section"}
        ],
      "required": true, "widget": "select"
    },
    {
      "extend": {"label": "Parallax enable","name": "parallax"}
    },
    "import fields enable"
 ]
}

Second, the combining map

{ 
"fields":
  [
    {"import": "fields title"},
    {"import": "fields enable"},
    {
      "options":
        [
          {"label": "Hero parallax","value":"hero-parallax"},
        ],
    }
 ]
}

So with : {{ partial "map-combine.html" (dict "one" $map1 "two" $map2) }}

Gives :

Replace on slice index and map key recursively If data type isn't the same, we keep old value

{
"toto": 1,  
"fields":
  [
    "import fields title",
    "import fields enable",
    {
      "label": "Layout",
      "name": "design",
      "options":
        [
          {"label": "Hero parallax","value":"hero-parallax"},
          {"label": "Page title","value":"page-title"},
          {"label": "Section","value":"section"}
        ],
      "required": true, "widget": "select"
    },
    {
      "extend": {"label": "Parallax enable","name": "parallax"}
    },
    "import": "fields enable"
 ]
}
{{/*
deep merge with replace only same map keys
with the second map
Value don't changes with incorrect
type match between one and two
@author @loic-roux-404
@context .one .two Two dict / map to merge
@return Map
@example - Go Template
{{ with partialCached "utils/combine-dict" (dict "one" $one "two" $two) }}
{{ end }}
*/}}
{{ $return := (.one | default dict) }}
{{ $two := .two | default dict }}
{{ if and (reflect.IsMap .two) (reflect.IsMap .one) }}
{{ range $key, $value := .one }}
{{ $entering := (dict $key $value)}}
{{ with index $two $key }}
{{ $entering = (dict $key .) }}
{{ $toComb := (dict "one" $value "two" .) }}
{{ if (reflect.IsMap .) }}
{{/* Entering dict */}}
{{ with partialCached "utils/combine-dict" $toComb $toComb }}
{{ $entering = (dict $key .) }}
{{ end }}
{{ else if (reflect.IsSlice .) }}
{{/* Entering slice */}}
{{ with partialCached "utils/combine-slice" $toComb $toComb }}
{{ $entering = (dict $key .) }}
{{ end }}
{{ end }}
{{ end }}
{{ $return = merge $return $entering }}
{{ end }}
{{ end }}
{{ return $return }}
{{/*
deep merge with replace only same slice indexes
with the second slice
Value don't changes with incorrect
type match between one and two
@author @loic-roux-404
@context .one .two Two object to merge
@return Slice
@example - Go Template
{{ with partialCached "utils/combine-slice" (dict "one" $one "two" $two) }}
{{ end }}
*/}}
{{ $return := .one }}
{{ $two := .two }}
{{ if and (reflect.IsSlice .two) (reflect.IsSlice .one) }}
{{ $return = slice }}
{{/* i: int, value: Any */}}
{{ range $i, $value := .one }}
{{ $entering := $value }}
{{/* Override here if isset index */}}
{{ with index $two $i }}
{{ $toComb := (dict "one" $value "two" .) }}
{{ if and (reflect.IsMap $value) (reflect.IsMap .) }}
{{ $entering = partialCached "utils/combine-dict" $toComb $toComb }}
{{ else if and (reflect.IsSlice $value) (reflect.IsSlice .) }}
{{ $entering = partialCached "utils/combine-slice" $toComb $toComb }}
{{ else }}
{{ $entering = . }}
{{ end }}
{{ end }}
{{ $return = $return | append $entering }}
{{ end }}
{{ end }}
{{ return $return }}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment