Shortcodes Proposal: Open Graph card (code inside)

Here is a proposal of a shortcode for Open Graph. Following Facebook Platform - Wikipedia

This code will create a card like the following:

In case of fallback, will show a short banner.

The code of layouts\shortcodes\og-card.html:

{{/* layouts/shortcodes/og-card.html */}}

{{/* Provide the URL to fetch Open Graph data from */}}
{{ $url := .Get "url" | default (.Get 0) }}

{{/* Multiple additional parameters */}}
{{ $add_link := .Get "add_link" | default (.Get 1) | default true }}
{{ $add_margin_bottom := .Get "add_margin_bottom" | default (.Get 2) | default true }}
{{ $add_image := .Get "add_image" | default (.Get 3) | default true }}
{{ $only_text := .Get "only_text" | default (.Get 4) | default false }}

{{ $ogTitle := "" }}
{{ $ogDesc := "" }}
{{ $ogImage := "" }}

{{/* Regex (más tolerantes y reutilizables) */}}
{{ $reOgImage := `(?i)<meta[^>]+(?:property|name)=["'](?:og:image|twitter:image)["'][^>]+content=["']([^"']+)["']` }}
{{ $reOgTitle := `(?i)<meta[^>]+property=["']og:title["'][^>]+content=["']([^"']+)["']` }}
{{ $reOgDesc  := `(?i)<meta[^>]+property=["']og:description["'][^>]+content=["']([^"']+)["']` }}
{{ $reTitleTag := `(?i)<title>(.*?)</title>` }}

{{/* Parse del URL para host/scheme */}}
{{ $u := urls.Parse $url }}
{{ $host := "" }}
{{ with $u }}{{ $host = .Host }}{{ end }}

{{/* Configuración de la petición */}}
{{ $opts := dict "headers" (dict
  "User-Agent" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
  "Accept" "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
  "Accept-Language" "en-US,en;q=0.5"
  "Referer" "https://www.google.com/"
  "Upgrade-Insecure-Requests" "1"
  "Sec-Ch-Ua" "\"Not_A Brand\";v=\"8\", \"Chromium\";v=\"120\", \"Google Chrome\";v=\"120\""
  "Sec-Ch-Ua-Mobile" "?0"
  "Sec-Ch-Ua-Platform" "\"Windows\""
  "Sec-Fetch-Dest" "document"
  "Sec-Fetch-Mode" "navigate"
  "Sec-Fetch-Site" "none"
  "Sec-Fetch-User" "?1"
) }}

{{/* Recurso remoto. NOTA: Para activar el fallback en caso de error (403/404), agrega ignoreErrors = ["error-remote-get"] en hugo.toml */}}
{{ $resource := resources.GetRemote $url $opts }}

{{ $add_margin_bottom_class := cond $add_margin_bottom " mb-6" "" }}

{{ if and $resource (not $only_text) }}
  {{ $content := $resource.Content }}

  {{/* 1 IMAGEN */}}
  {{ if $add_image }}
    {{ with (findRE $reOgImage $content 1) }}
      {{ $ogImage = index . 0 | replaceRE $reOgImage "$1" }}
    {{ end }}

    {{/* Normaliza og:image relativo -> absoluto */}}
    {{ if and $ogImage $u }}
      {{ if hasPrefix $ogImage "//" }}
        {{ $ogImage = printf "%s:%s" $u.Scheme $ogImage }}
      {{ else if hasPrefix $ogImage "/" }}
        {{ $ogImage = printf "%s://%s%s" $u.Scheme $u.Host $ogImage }}
      {{ end }}
    {{ end }}
  {{ end }}

  {{/* 2 TÍTULO */}}
  {{ with (findRE $reOgTitle $content 1) }}
    {{ $ogTitle = index . 0 | replaceRE $reOgTitle "$1" }}
  {{ else }}
    {{ with (findRE $reTitleTag $content 1) }}
      {{ $ogTitle = index . 0 | replaceRE $reTitleTag "$1" }}
    {{ end }}
  {{ end }}

  {{/* 3 DESCRIPCIÓN */}}
  {{ with (findRE $reOgDesc $content 1) }}
    {{ $ogDesc = index . 0 | replaceRE $reOgDesc "$1" }}
  {{ end }}

  {{ if $add_link }}
    {{ $content := printf (i18n "external_reference_text.add_link") $url }}
    <p>{{- $content | markdownify -}}</p>
  {{ end }}

  <div class="my-6 w-full max-w-prose mx-auto{{ $add_margin_bottom_class }}">
    <a href="{{ $url }}" target="_blank" rel="noopener noreferrer" class="not-prose block group relative overflow-hidden rounded-2xl bg-neutral-100 dark:bg-neutral-800 hover:shadow-xl transition-all duration-300 border border-neutral-200 dark:border-neutral-700/50">

      {{ if $ogImage }}
        <div class="aspect-video w-full overflow-hidden relative bg-neutral-200 dark:bg-neutral-700">
          <img src="{{ $ogImage | safeURL }}" alt="{{ ($ogTitle | default "Preview") | htmlUnescape }}" class="h-full w-full object-cover transition-transform duration-500 group-hover:scale-105" loading="lazy" />
        </div>
      {{ end }}

      <div class="p-5">
        <h3 class="text-lg font-bold text-neutral-900 dark:text-neutral-100 group-hover:text-primary-600 dark:group-hover:text-primary-400 leading-tight mb-2">
          {{ $ogTitle | default $url | htmlUnescape }}
        </h3>

        {{ if $ogDesc }}
          <p class="text-sm text-neutral-600 dark:text-neutral-400 line-clamp-2 mb-3">
            {{ $ogDesc | htmlUnescape | truncate 140 }}
          </p>
        {{ end }}

        <div class="flex items-center gap-2 mt-2 pt-2 border-t border-neutral-200 dark:border-neutral-700/50">
          <img src="https://www.google.com/s2/favicons?domain={{ $host | default $url }}&sz=32" alt="" class="w-4 h-4 opacity-70" />
          <div class="text-xs font-mono text-neutral-500">
            {{ $host | default ($url | replaceRE `^https?://(www\.)?([^/]+).*` "$2") }} ↗
          </div>
        </div>
      </div>
    </a>
  </div>

{{ else }}
  <div class="my-6{{ $add_margin_bottom_class }}">
    {{ partial "components/alert.html" (dict
      "icon" "link"
      "content" (printf (i18n "external_reference_text.alternative") $url)
    ) }}
  </div>
{{ end }}

What is needed at i18n: i18n\en.yaml :slight_smile:

global:
  language: "EN"

external_reference_text: 
  add_link: "More information at the [link](%s) 👇"
  alternative: "More in the following [external reference](%s)."

To use the shortcode:

{{< og-card url="http://www.sqlalchemy.org" add_link=true >}}

Please, open to suggestions about this idea.

Theme classes is based on https://blowfish.page/