├Ś
Startseite RSS-Feed Info
Den Inhalt von Open Graph Meta-Tags selber festlegen.

Hugo - angepasste Open Graph Integration

Customized Open Graph integration

Open Graph ist ein Protokoll, mit dem sich beeinflussen l├Ąsst wie eine Webseite dargestellt wird, wenn sie auf Social Media geteilt wird. ├ťber Meta Eintr├Ąge im Head jeder Webseite kann man selber beeinflussen welche Daten daf├╝r benutzt werden. In diesem Artikel beschreibe ich meine in einem Partial zusammengefassten Open Graph Meta-Tags.

Allgemeine Informationen zu Open Graph

Urspr├╝nglich wurde Open Graph von Facebook entwickelt. Seither wurde es aber auch von anderen Social-Media-Kan├Ąlen wie Twitter, Pinterest und LinkedIn ├╝bernommen.

Die meisten Inhalte werden als URL auf Facebook und anderen (Open Graph Protokoll) OGP-unterst├╝tzenden Websites geteilt. Aus diesem Grund kann es nur positiv sein, wenn die eigene Website mit Open Graph Meta-Tags ausgestattet ist. Nur so hat man die Kontrolle, welche Inhalte dort angezeigt werden.

Da ich verstehen m├Âchte was zu einer entsprechenden Ausgabe im Sourcecode f├╝hrt und was f├╝r M├Âglichkeiten es gibt, habe ich mir unter anderem die folgenden Webseiten angeschaut:

Hugo Open Graph Template

Hugo stellt ein Template f├╝r die Integration der Open Graph Meta-Tags zur Verf├╝gung. Das Template wird im Head aufgerufen und integriert die Meta-Tags. Wenn Sie das Template benutzen m├Âchten reicht der folgende Aufruf:

{{ template "_internal/opengraph.html" . }}

F├╝r ein besseres Verst├Ąndnis was das Template so macht, gibt es eine Hugo Doku und einen Link zum Template Sourcecode:

Mein Partial ogData.html

Das Hugo Template ist f├╝r viele Einsatzzwecke konzipiert. Da ich nur die f├╝r meine Website angepassten Inhalte ausgeben m├Âchte, habe ich Teile des Templates ├╝bernommen bzw. neu geschrieben. Dazu weiter unten mehr.

Das Partial ogData.html habe ich wie folgt im head-Tag meiner baseof.html eingebunden:

{{ partial "ogData" . }}

Der Sourcecode des Partials themes/tekki/layouts/partials/ogData.html sieht wie folgt aus:

<meta property="og:title" content="{{ if .IsHome }}{{ .Site.Title }}{{ else }}{{ .Title }} &middot; {{ .Site.Title }}{{ end }}">
<meta property="og:type" content="{{ if .IsPage }}article{{ else }}website{{ end }}">
<meta property="og:description" content="{{ if .Description }}{{ .Description }}{{ else }}{{ .Site.Params.description }}{{ end }}">
<meta property="og:site_name" content="{{ .Site.Title }}">
<meta property="og:url" content="{{ .Permalink }}">
{{ if eq .Site.Language.Lang "de" }}
  <meta property="og:locale" content="de_DE">
  <meta property="og:locale:alternate" content="en_GB">
{{ else }}
  <meta property="og:locale" content="en_GB">
  <meta property="og:locale:alternate" content="de_DE">
{{ end }}
{{ if and (.IsPage) (ne .Section "") }}<meta property="article:section" content="{{ .Section }}">{{ end }}
{{ $iso8601 := "2006-01-02T15:04:05-07:00" }}
{{ with .PublishDate }}<meta property="article:published_time" {{ .Format $iso8601 | printf "content=%q" | safeHTMLAttr }}>{{ end }}
{{ with .Lastmod }}<meta property="article:modified_time" {{ .Format $iso8601 | printf "content=%q" | safeHTMLAttr }}>{{ end }}
{{ $image := .Resources.GetMatch "featured" }}
{{ with $image }}
  <meta property="og:image" content="{{ .Permalink }}">
  <meta property="og:image:secure_url" content="{{ .Permalink }}">
  <meta property="og:image:type" content="{{ .MediaType }}">
  <meta property="og:image:width" content="{{ .Width }}">
  <meta property="og:image:height" content="{{ .Height }}">
  <meta property="og:image:alt" content="{{ .Title }}">
{{ else }}
  {{ $ogimage := resources.Get "tekki-tipps-og.png" }}
  {{ with $ogimage }}
    <meta property="og:image" content="{{ .Permalink }}">
    <meta property="og:image:secure_url" content="{{ .Permalink }}">
    <meta property="og:image:type" content="{{ .MediaType }}">
    <meta property="og:image:width" content="{{ .Width }}">
    <meta property="og:image:height" content="{{ .Height }}">
    <meta property="og:image:alt" content="Blog about Hugo, web design, CSS/SCSS, SEO, Tools">
  {{ end}}
{{ end }}

Zum besseren Verst├Ąndnis werde ich jedes Meta-Tag einzelnd beschreiben.

meta property=“og:title”

<meta property="og:title" content="{{ if .IsHome }}{{ .Site.Title }}{{ else }}{{ .Title }} &middot; {{ .Site.Title }}{{ end }}">

Wenn die aktuelle Webseite die Startseite ist, wird der title aus der hugo.toml ├╝bernommen. Ansonsten, also f├╝r alle anderen Webseiten, wird der title dem Front Matter Eintrag der aktuellen Webseite entnommen. Ein Bindestrich eingef├╝gt und der title aus der hugo.toml angef├╝gt.

Die Eintr├Ąge der hugo.toml f├╝r deutsch und englisch sehen wie folgt aus:

[languages]
  [languages.de]
    languageName = "Deutsch"
    weight = 1
    title = "tekki-tipps.de ­čçę­čç¬"
    description = "Blog ├╝ber Hugo, Webdesign, CSS/SCSS, SEO, Tools"
..
..
  [languages.en]
    languageName = "English"
    weight = 2
    title = "tekki-tipps.de/en ­čçČ­čçž"
    description = "Blog about Hugo, web design, CSS/SCSS, SEO, Tools"

meta property=“og:type”

<meta property="og:type" content="{{ if .IsPage }}article{{ else }}website{{ end }}">

Auf meiner Website wird der og:type website f├╝r die Startseite, die Tag-Cloud und auf Tag-Listen angezeigt. Also auf allen ├ťbersichtslisten. Alle anderen Webseiten erhalten den og:type article.

meta property=“og:description”

<meta property="og:description" content="{{ if .Description }}{{ .Description }}{{ else }}{{ .Site.Params.description }}{{ end }}">

Wenn die aktuelle Webseite im Front Matter eine description hat, wird diese durch .Description ├╝bernommen. Ansonsten wird die description der hugo.toml benutzt.

meta property=“og:site_name”

<meta property="og:site_name" content="{{ .Site.Title }}">

Der Title aus der hugo.toml.

meta property=“og:url”

<meta property="og:url" content="{{ .Permalink }}">

Die permanente URL der aktuellen Webseite.

meta property=“og:locale” und “og:locale:alternate”

{{ if eq .Site.Language.Lang "de" }}
  <meta property="og:locale" content="de_DE">
  <meta property="og:locale:alternate" content="en_GB">
{{ else }}
  <meta property="og:locale" content="en_GB">
  <meta property="og:locale:alternate" content="de_DE">
{{ end }}

og:locale definiert die Sprache der aktuellen Webseite. og:locale:alternate teilt mit, dass f├╝r die aktuelle Webseite eine ├ťbersetzung in einer alternativen Sprache vorhanden ist.

meta property=“article:section”

{{ if and (.IsPage) (ne .Section "") }}<meta property="article:section" content="{{ .Section }}">{{ end }}

Wenn die aktuelle Webseite eine Page ist und die .Section kein leerer String ist, dann soll das Meta-Tag in den Head geschrieben werden. Auf meiner Website gibt es nur die Section blog. Damit bei Webseiten die keine Section haben das Meta-Tag nicht in den Head geschrieben wird, erfolgt die Abfrage ob der String in .Section leer ist.

meta property=“article:published_time” und article:modified_time

{{ $iso8601 := "2006-01-02T15:04:05-07:00" }}
{{ with .PublishDate }}<meta property="article:published_time" {{ .Format $iso8601 | printf "content=%q" | safeHTMLAttr }}>{{ end }}
{{ with .Lastmod }}<meta property="article:modified_time" {{ .Format $iso8601 | printf "content=%q" | safeHTMLAttr }}>{{ end }}

Die ├ťbersichtsseiten - Startseite, Tag-Cloud und Tag-Listen - habe kein .PublishDate deshalb die Abfrage. Alle anderen Webseiten haben eventuell noch kein .Lastmod.

meta property=“og:image”

{{ $image := .Resources.GetMatch "featured" }}
{{ with $image }}
  <meta property="og:image" content="{{ .Permalink }}">
  <meta property="og:image:secure_url" content="{{ .Permalink }}">
  <meta property="og:image:type" content="{{ .MediaType }}">
  <meta property="og:image:width" content="{{ .Width }}">
  <meta property="og:image:height" content="{{ .Height }}">
  <meta property="og:image:alt" content="{{ .Title }}">
{{ else }}
  {{ $ogimage := resources.Get "tekki-tipps-og.png" }}
  {{ with $ogimage }}
    <meta property="og:image" content="{{ .Permalink }}">
    <meta property="og:image:secure_url" content="{{ .Permalink }}">
    <meta property="og:image:type" content="{{ .MediaType }}">
    <meta property="og:image:width" content="{{ .Width }}">
    <meta property="og:image:height" content="{{ .Height }}">
    <meta property="og:image:alt" content="Blog about Hugo, web design, CSS/SCSS, SEO, Tools">
  {{ end}}
{{ end }}

Nun wird es etwas komplizierter. Deshalb muss ich etwas mehr erkl├Ąren. Meine Webseiten sind multilingual in zwei Sprachen. Ich benutze PageBundles wegen der ├ťbersichtlichkeit - alles f├╝r eine Webseite, in einem Verzeichnis. Die jeweiligen Bilder werden innerhalb des PageBundle Verzeichnis im img-Verzeichnis gespeichert. Meine Blogbeitragsseiten haben ein Artikelbild und ein als featured bezeichnetes Bild. Alle anderen Webseiten haben kein als featured bezeichnetes Bild.

Im Front Matter f├╝r diese Webseite sehen die Eintr├Ąge wie folgt aus:

resources:
- name: featured
  src: img/featured.png
  title: Customized Open Graph integration
- name: article-img
  src: img/open-graph.png
  title: Customized Open Graph integration

Mit .Resources.GetMatch hole ich das als featured bezeichnete Bild aus dem PageBundle und speicher es in der Variablen $image. Wenn ein featured Bild vorhanden ist, gebe ich die entsprechenden Meta-Tags f├╝r dieses Bild aus.

Wenn kein featured Bild vorhanden ist, suche ich mit resources.Get nach dem Bild tekki-tipps-og.png und speicher es in der Variablen $ogimage. Das Bild habe ich im static Verzeichnis auf der obersten Ebene gespeichert.

Die Bilder sollten eine Aufl├Âsung von 1200px X 600px haben, damit auch auf hochaufl├Âsenden Bildschirmen ein gutes Bild angezeigt wird. Siehe dazu auch den oben genannten Facebook Link.

meta property=“og:image:secure_url”

Heutzutage gibt es ja kaum noch Websites die kein SSL-Zertifikat haben. Das Meta-Tag kommt noch aus einer anderen Zeit. Muss aber angegeben werden. Auch hier ├╝bergebe ich den .Permalink des Bildes.

meta property=“og:image:type”

Ich benutze Bilddateien vom Typ png und jpg. png sind von der Gr├Â├če her kleiner, wenn ein gro├čer Teil des Bildes die gleichen Farbanteile enth├Ąlt. Der Typ wird durch .MediaType automatisch festgestellt.

meta property=“og:image:width”

Mit .Width wird die Breite des Bildes festgestellt.

meta property=“og:image:height”

Mit .Height wird die H├Âhe des Bildes festgestellt.

meta property=“og:image:alt”

Bei den Blogbeitr├Ągen entnehme ich den alternativen Text des Bildes aus dem Resource Title. F├╝r alle anderen Webseiten, mit dem allgemeinen Bild, speicher ich meinen alt-Text manuell.

Kontrolle der Open Graph Parameter

Im head des HTML-Sourcecodes kann man die entsprechenden Meta-Tags anschauen. Da ich die Open Graph Meta-Tags erst im nachhinein erstellt habe, ist es sehr aufw├Ąndig dies f├╝r jeden Beitrag und jeder Sprache zu kontrollieren.

Auch daf├╝r gibt es eine L├Âsung - Browser Extensions. F├╝r Safari habe ich gar keine Extension gefunden. F├╝r Edge gibt eine Textl├Âsung, aber der relevante Teil muss gescrollt werden. Da kann man sich dann auch den HTML-Sourcecode anschauen.

F├╝r Firefox und Chrome gibt es entsprechende Extension. Das f├╝r Firefox finde ich h├╝bscher und setze es auch ein:

Open Graph blog post extension
Firefox Browser Extension - Anzeige f├╝r diesen Blogbeitrag.
Open Graph website extension
Firefox Browser Extension - Anzeige f├╝r alle anderen Webseiten au├čer Blogbeitr├Ągen.

Fazit

Ich habe keinen Facebook Account und kann deshalb die Weitergabe von Links innerhalb von Facebook nicht kontrollieren. Die Weitergabe meiner Kontaktadressen ist mir zu wertvoll um sie gezwungenerma├čen mit Facebook zu teilen. Andere sehen dies anders und f├╝r diese Menschen habe ich die OG Meta-Tags integriert.

Linkliste zu diesem Beitrag

Update:  |
8 Minuten Lesezeit
0
Dieser Beitrag wurde mit der Hugo-Version 0.111.3 erstellt.

Kommentare werden bei deutscher Spracheinstellung nicht in der englischen Variante der Webseite angezeigt und umgekehrt.

© 2023 - Frank Kunert  -  Ich ├╝ber mich
Ein Service von webdienste-kunert.de