schema.org things.

This commit is contained in:
fiatjaf
2024-06-10 23:41:57 -03:00
parent 899dbf8441
commit aeb98ca535
7 changed files with 136 additions and 102 deletions

View File

@@ -38,16 +38,21 @@ on load get [navigator.userAgent.includes('Safari'), navigator.userAgent.include
}
templ authorHeaderTemplate(metadata Metadata) {
<header class="mb-4 max-w-full">
<a class="flex items-center" href={ templ.URL("/" + metadata.Npub()) }>
<header
itemprop="author"
itemscope
itemtype="https://schema.org/Person"
class="mb-4 max-w-full"
>
<a class="flex items-center" itemprop="url" href={ templ.URL("/" + metadata.Npub()) }>
<div class="print:basis-1-12 imgclip mr-2 flex-shrink-0 basis-1/6 overflow-hidden sm:mr-4">
<img class="block h-auto w-full" src={ metadata.Picture }/>
<img itemprop="image" class="block h-auto w-full" src={ metadata.Picture }/>
</div>
<div class="block print:text-base grow">
<div class="leading-4 sm:text-2xl">
{ metadata.Name }
<span itemprop="name">{ metadata.Name }</span>
if metadata.Name != metadata.DisplayName {
<span class="text-stone-400 sm:text-xl">/ { metadata.DisplayName } </span>
<span class="text-stone-400 sm:text-xl" itemprop="alternateName">/ { metadata.DisplayName } </span>
}
</div>
<div class="text-sm leading-4 text-stone-400 sm:text-base">
@@ -57,25 +62,3 @@ templ authorHeaderTemplate(metadata Metadata) {
</a>
</header>
}
templ lastNotesTemplate(lastNotes []EnhancedEvent) {
<aside>
<div class="-ml-4 mb-6 h-1.5 w-1/3 bg-zinc-100 dark:bg-zinc-700 sm:-ml-2.5"></div>
<nav class="mb-6 leading-5">
<h2 class="text-2xl text-strongpink">Last Notes</h2>
for _, ee := range lastNotes {
<a class="my-8 block no-underline hover:-ml-6 hover:border-l-05rem hover:border-solid hover:border-l-gray-100 hover:pl-4 dark:hover:border-l-zinc-700" href={ templ.URL("/" + ee.Nevent()) }>
<div class="-ml-2.5 mb-1.5 flex flex-row flex-wrap border-b-4 border-solid border-b-gray-100 pb-1 pl-2.5 dark:border-b-neutral-800">
<div class="text-sm text-strongpink">{ ee.CreatedAtStr() }</div>
if ee.isReply() {
<div class="ml-2 text-sm text-gray-300 dark:text-gray-400">- reply</div>
}
</div>
<div class="mt-0.5 max-h-40 basis-full overflow-hidden hover:text-strongpink" _="on load if my scrollHeight > my offsetHeight add .gradient" dir="auto">
@templ.Raw(ee.Preview())
</div>
</a>
}
</nav>
</aside>
}

View File

@@ -19,17 +19,21 @@ templ eventPageTemplate(
<body class="mb-16 bg-white text-gray-600 dark:bg-neutral-900 dark:text-neutral-50 print:text-black">
@topTemplate(head)
<div class="mx-auto px-4 sm:flex sm:items-center sm:justify-center sm:px-0">
<div class="w-full max-w-screen-2xl justify-between gap-10 overflow-visible print:w-full sm:flex sm:w-11/12 sm:px-4 md:w-10/12 lg:w-9/12 lg:gap-48vw">
<div
itemscope
itemtype="https://schema.org/SocialMediaPosting"
class="w-full max-w-screen-2xl justify-between gap-10 overflow-visible print:w-full sm:flex sm:w-11/12 sm:px-4 md:w-10/12 lg:w-9/12 lg:gap-48vw"
>
<div class="w-full break-words print:w-full sm:w-3/4">
@authorHeaderTemplate(author)
<div class="w-full text-right text-sm text-stone-400">
<div itemprop="dateCreated" class="w-full text-right text-sm text-stone-400">
{ event.CreatedAtStr() }
</div>
<div class="w-full text-right text-sm text-stone-400">
if nevent := event.getParentNevent(); nevent != "" {
in reply to
<span class="text-strongpink">
@templ.Raw(replaceNostrURLsWithHTMLTags(nostrNoteNeventMatcher, "nostr:" + nevent))
@templ.Raw(replaceNostrURLsWithHTMLTags(nostrNoteNeventMatcher, "nostr:"+nevent))
</span>
}
</div>

View File

@@ -12,17 +12,17 @@ templ noteTemplate(params NotePageParams) {
params.Event,
) {
if params.Subject != "" {
<h1 class="text-2xl">{ params.Subject }</h1>
<h1 class="text-2xl" itemprop="headline">{ params.Subject }</h1>
} else {
<h1 class="hidden">
{ params.Metadata.ShortName() } on Nostr: { params.TitleizedContent }
</h1>
}
if params.Cover != "" {
<img src={ params.Cover } alt={ params.Alt } class="mt-1" />
<img src={ params.Cover } alt={ params.Alt } class="mt-1"/>
}
<!-- main content -->
<div dir="auto" class="leading-5">
<div dir="auto" class="leading-5" itemprop="articleBody">
@templ.Raw(params.Content)
</div>
}

View File

@@ -39,7 +39,11 @@ templ profileTemplate(params ProfilePageParams) {
</head>
<body class="mb-16 bg-white text-gray-600 print:text-black dark:bg-neutral-900 dark:text-neutral-50">
@topTemplate(params.HeadParams)
<div class="mx-auto px-4 sm:flex sm:items-center sm:justify-center sm:px-0">
<div
itemscope
itemtype="https://schema.org/Person"
class="mx-auto px-4 sm:flex sm:items-center sm:justify-center sm:px-0"
>
<div class="w-full max-w-screen-2xl justify-between gap-10 overflow-visible print:w-full sm:flex sm:w-11/12 sm:px-4 md:w-10/12 lg:w-9/12 lg:gap-48vw">
<header
class="relative top-auto flex basis-1/5 sm:max-w-[20%] items-center self-start sm:sticky sm:top-8 sm:mt-8 sm:block sm:items-start"
@@ -49,9 +53,9 @@ templ profileTemplate(params ProfilePageParams) {
_="on load or scroll from window or resize from window get #profile_name then measure its top, height then if top is less than height / -2 or height is 0 remove .hidden otherwise add .hidden"
>
<div class="mb-3 sm:text-center">
<div class="text-2xl break-words">{ params.Metadata.Name }</div>
<div class="text-2xl break-words" itemprop="name">{ params.Metadata.Name }</div>
if params.Metadata.Name != params.Metadata.DisplayName {
<div class="text-base text-stone-400 break-words">
<div class="text-base text-stone-400 break-words" itemprop="alternateName">
{ params.Metadata.DisplayName }
</div>
}
@@ -60,7 +64,7 @@ templ profileTemplate(params ProfilePageParams) {
<div
class="imgclip max-w-[40%] basis-2/5 overflow-hidden sm:max-w-full sm:basis-auto"
>
<img class="block h-auto w-full" src={ params.Metadata.Picture }/>
<img class="block h-auto w-full" src={ params.Metadata.Picture } itemprop="image"/>
</div>
</header>
<div class="w-full flex-1 break-words print:w-full sm:w-1/2">
@@ -78,6 +82,7 @@ templ profileTemplate(params ProfilePageParams) {
if params.Metadata.Website != "" {
<div class="mb-6 leading-5">
<a
itemprop="sameAs"
class="border-b-2 border-b-gray-300 pb-0.5 hover:text-strongpink"
href={ templ.URL(params.NormalizedAuthorWebsiteURL) }
>{ params.Metadata.Website }</a>
@@ -87,6 +92,7 @@ templ profileTemplate(params ProfilePageParams) {
<div
class="prose mb-6 leading-5 dark:prose-invert prose-headings:font-light sm:prose-a:text-justify"
dir="auto"
itemprop="description"
>
@templ.Raw(params.RenderedAuthorAboutText)
</div>
@@ -96,12 +102,12 @@ templ profileTemplate(params ProfilePageParams) {
}
<div class="mb-6 leading-5">
<div class="text-sm text-strongpink">Public Key</div>
{ params.Metadata.Npub() }
<span itemprop="identifier">{ params.Metadata.Npub() }</span>
</div>
<div class="mb-6 leading-5">
if params.Metadata.NIP05 != "" {
<div class="text-sm text-strongpink">NIP-05 Address</div>
{ params.Metadata.NIP05 }
<span itemprop="alternateName">{ params.Metadata.NIP05 }</span>
}
</div>
<div class="mb-6 leading-5">
@@ -118,40 +124,72 @@ templ profileTemplate(params ProfilePageParams) {
<div class="mb-6 leading-5">
<div class="text-sm text-strongpink">Publishing to</div>
for _, relay := range params.AuthorRelays {
<a
href={ templ.URL("/r/" + relay) }
class="mr-1 mt-2 inline-block max-w-full rounded-lg border border-slate-300 px-2 py-0.5 hover:border hover:border-solid hover:border-strongpink hover:bg-strongpink hover:text-white"
<div
itemprop="affiliation"
itemscope
itemtype="https://schema.org/Organization"
>
{ relay }
</a>
<span class="hidden" itemprop="name identifier">{ relay }</span>
<a
itemprop="url"
href={ templ.URL("/r/" + relay) }
class="mr-1 mt-2 inline-block max-w-full rounded-lg border border-slate-300 px-2 py-0.5 hover:border hover:border-solid hover:border-strongpink hover:bg-strongpink hover:text-white"
>
{ relay }
</a>
</div>
}
</div>
}
@detailsTemplate(params.Details)
<div
_="init if navigator's userAgent contains 'Googlebot' or
navigator's userAgent contains 'bingbot' or
navigator's userAgent contains 'DuckDuckBot' or
navigator's userAgent contains 'Baiduspider'
// It is not necessary to provide search engines with a preview of the notes
else
fetch '?just-last-notes=true' then put the result into me end
end"
>
if len(params.LastNotes) != 0 {
<aside>
<div class="-ml-4 mb-6 h-1.5 w-1/3 bg-zinc-100 sm:-ml-2.5 dark:bg-zinc-700"></div>
<nav class="mb-6 leading-5">
<h2 class="text-2xl text-strongpink">Last Notes</h2>
for _, ee := range params.LastNotes {
<a class="my-8 block no-underline hover:-ml-6 hover:border-l-05rem hover:border-solid hover:border-l-gray-100 hover:pl-4 dark:hover:border-l-zinc-700" href={ templ.URL("/" + ee.Nevent()) }>
{ ee.Nevent() }
</a>
}
</nav>
</aside>
}
</div>
if len(params.LastNotes) != 0 {
<aside>
<div class="-ml-4 mb-6 h-1.5 w-1/3 bg-zinc-100 sm:-ml-2.5 dark:bg-zinc-700"></div>
<nav class="mb-6 leading-5">
<h2 class="text-2xl text-strongpink">Last Notes</h2>
for _, ee := range params.LastNotes {
<div
itemscope
itemtype="https://schema.org/SocialMediaPosting"
class="my-8 block no-underline hover:-ml-6 hover:border-l-05rem hover:border-solid hover:border-l-gray-100 hover:pl-4 dark:hover:border-l-zinc-700"
>
<div class="hidden" itemprop="author" itemscope itemtype="https://schema.org/Person">
<a href={ templ.SafeURL("/" + params.Metadata.Npub()) } itemprop="url"></a>
<span itemprop="identifier">{ params.Metadata.Npub() }</span>
<span itemprop="name">{ params.Metadata.ShortName() }</span>
</div>
<div class="-ml-2.5 mb-1.5 flex flex-row flex-wrap border-b-4 border-solid border-b-gray-100 pb-1 pl-2.5 dark:border-b-neutral-800">
<a
itemprop="url"
href={ templ.URL("/" + ee.Nevent()) }
>
<span
itemprop="dateCreated"
datetime={ ee.CreatedAtStr() }
class="text-sm text-strongpink"
>
{ ee.CreatedAtStr() }
</span>
</a>
if ee.isReply() {
<div class="ml-2 text-sm text-gray-300 dark:text-gray-400">- reply</div>
}
</div>
<span
class="mt-0.5 max-h-40 basis-full overflow-hidden hover:text-strongpink cursor-pointer"
_="on load if my scrollHeight > my offsetHeight add .gradient end
on click halt the event then set the window's location to @loc"
loc={ "/" + ee.Nevent() }
dir="auto"
itemprop="articleBody"
>
@templ.Raw(ee.Preview())
</span>
</div>
}
</nav>
</aside>
}
<div class="-ml-4 mb-6 h-1.5 w-1/3 bg-zinc-100 sm:-ml-2.5 dark:bg-zinc-700"></div>
</div>
@clientsTemplate(params.Clients)

View File

@@ -36,7 +36,12 @@ templ relayTemplate(params RelayPageParams) {
class="mb-16 bg-white text-gray-600 dark:bg-neutral-900 dark:text-neutral-50 print:text-black"
>
@topTemplate(params.HeadParams)
<div class="mx-auto px-4 sm:flex sm:items-center sm:justify-center sm:px-0">
<div
itemscope
itemtype="https://schema.org/Organization"
class="mx-auto px-4 sm:flex sm:items-center sm:justify-center sm:px-0"
>
<span class="hidden" itemprop="identifier name">{ params.Hostname }</span>
<div
class="w-full max-w-screen-2xl justify-between gap-10 overflow-visible px-4 print:w-full sm:flex md:w-10/12 lg:w-9/12 lg:gap-48vw"
>
@@ -46,11 +51,13 @@ templ relayTemplate(params RelayPageParams) {
<div
class="hidden items-center overflow-hidden text-left text-2xl sm:break-word sm:text-center sm:basis-full"
_="on load or scroll from window or resize from window get #relay_name then measure its top, height then if top is less than height / -2 or height is 0 add .flex then remove .hidden otherwise remove .flex then add .hidden"
itemprop="alternateName"
>
{ params.Info.Name }
</div>
<div
class="imgclip max-w-full basis-2/5 overflow-hidden sm:basis-full"
itemprop="image logo"
>
<img class="block h-auto w-full" src={ params.Info.Icon }/>
</div>
@@ -67,6 +74,7 @@ templ relayTemplate(params RelayPageParams) {
<div class="mb-6 leading-5">
<a
class="border-b-2 border-b-gray-300 pb-0.5 hover:text-strongpink"
itemprop="url"
href={ templ.URL("https://" + params.Hostname) }
target="_blank"
_="on mouseenter set my innerText to my.innerText.replace('wss://', 'https://')
@@ -76,6 +84,7 @@ templ relayTemplate(params RelayPageParams) {
<div
class="prose mb-6 leading-5 dark:prose-invert prose-headings:font-light sm:prose-a:text-justify"
dir="auto"
itemprop="description"
>
{ params.Info.Description }
</div>
@@ -102,41 +111,53 @@ templ relayTemplate(params RelayPageParams) {
<div class="mb-6 leading-5">
<h2 class="text-2xl text-strongpink">Last Notes</h2>
for _, ee := range params.LastNotes {
<a
<div
itemscope
itemtype="https://schema.org/SocialMediaPosting"
class="my-8 block no-underline hover:-ml-6 hover:border-l-05rem hover:border-solid hover:border-l-gray-100 hover:pl-4 dark:hover:border-l-zinc-700"
href={ templ.URL("/" + ee.Nevent()) }
>
<div
class="-ml-2.5 mb-1.5 flex flex-row border-b-4 border-solid border-b-gray-100 pb-1 pl-2.5 dark:border-b-neutral-800"
>
<div class="text-sm text-strongpink">
{ ee.CreatedAtStr() }
</div>
<br/>
<div class="-ml-2.5 mb-1.5 flex flex-row border-b-4 border-solid border-b-gray-100 pb-1 pl-2.5 dark:border-b-neutral-800">
<a
itemprop="url"
href={ templ.URL("/" + ee.Nevent()) }
>
<span class="text-sm text-strongpink" itemprop="dateCreated">
{ ee.CreatedAtStr() }
</span>
</a>
if ee.isReply() {
<div class="ml-2 text-xs text-gray-300 dark:text-gray-400">
- reply
</div>
}
<div class="ml-auto text-xs text-zinc-700 dark:text-neutral-50">
<span
class="ml-auto text-xs text-zinc-700 dark:text-neutral-50"
itemprop="author"
itemscope
itemtype="https://schema.org/Person"
>
<span class="hidden" itemprop="identifier">{ ee.Npub() }</span>
by
<span
<a
itemprop="url"
class="rounded bg-lavender px-1 hover:bg-strongpink hover:text-white dark:bg-garnet dark:hover:bg-strongpink"
_="on click halt the event then set the window's location to @loc"
loc={ templ.EscapeString("/" + ee.Npub()) }
href={ templ.SafeURL("/" + ee.Npub()) }
>
{ ee.NpubShort() }
</span>
</div>
</a>
</span>
</div>
<div
class="mt-0.5 max-h-40 basis-full overflow-hidden hover:text-strongpink"
_="on load if my scrollHeight > my offsetHeight add .gradient"
class="mt-0.5 max-h-40 basis-full overflow-hidden hover:text-strongpink cursor-pointer"
_="on load if my scrollHeight > my offsetHeight add .gradient end
on click halt the event then set the window's location to @loc"
loc={ "/" + ee.Nevent() }
dir="auto"
itemprop="articleBody"
>
@templ.Raw(ee.Preview())
</div>
</a>
</div>
}
</div>
</aside>

View File

@@ -23,11 +23,6 @@ func renderProfile(w http.ResponseWriter, r *http.Request, code string) {
isRSS = true
}
isLastNotes := false
if r.URL.Query().Get("just-last-notes") == "true" {
isLastNotes = true
}
data, err := grabData(r.Context(), code, isSitemap)
if err != nil {
w.Header().Set("Cache-Control", "max-age=60")
@@ -55,12 +50,6 @@ func renderProfile(w http.ResponseWriter, r *http.Request, code string) {
Metadata: data.metadata,
LastNotes: data.renderableLastNotes,
})
} else if isLastNotes {
w.Header().Add("content-type", "text/html")
if len(data.renderableLastNotes) != 0 {
w.Header().Set("Cache-Control", "max-age=3600")
}
err = lastNotesTemplate(data.renderableLastNotes).Render(r.Context(), w)
} else {
w.Header().Add("content-type", "text/html")
w.Header().Set("Cache-Control", "max-age=86400")

View File

@@ -7,11 +7,10 @@ import (
"math/rand"
"net/http"
"regexp"
"slices"
"strings"
"time"
"slices"
"github.com/microcosm-cc/bluemonday"
"mvdan.cc/xurls/v2"
@@ -241,9 +240,9 @@ func replaceNostrURLsWithHTMLTags(matcher *regexp.Regexp, input string) string {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*4)
defer cancel()
name, _ := getNameFromNip19(ctx, nip19)
return fmt.Sprintf(`<a href="/%s" class="bg-lavender dark:prose:text-neutral-50 dark:text-neutral-50 dark:bg-garnet px-1"><span>%s</span> (<span class="italic">%s</span>)</a>`, nip19, name, firstChars+"…"+lastChars)
return fmt.Sprintf(`<span itemprop="mentions" itemscope itemtype="https://schema.org/Person"><a itemprop="url" href="/%s" class="bg-lavender dark:prose:text-neutral-50 dark:text-neutral-50 dark:bg-garnet px-1"><span>%s</span> (<span class="italic">%s</span>)</a></span>`, nip19, name, firstChars+"…"+lastChars)
} else {
return fmt.Sprintf(`<a href="/%s" class="bg-lavender dark:prose:text-neutral-50 dark:text-neutral-50 dark:bg-garnet px-1">%s</a>`, nip19, firstChars+"…"+lastChars)
return fmt.Sprintf(`<span itemprop="mentions" itemscope itemtype="https://schema.org/SocialMediaPosting"><a itemprop="url" href="/%s" class="bg-lavender dark:prose:text-neutral-50 dark:text-neutral-50 dark:bg-garnet px-1">%s</a></span>`, nip19, firstChars+"…"+lastChars)
}
})
}