···342342 w.WriteHeader(http.StatusOK)
343343}
344344345345+// resolveOwnerHandle returns a human-readable handle for the owner string.
346346+// If the owner is already a handle, it is returned as-is. If it is a DID,
347347+// the feed index profile cache is consulted to resolve it to a handle.
348348+func (h *Handler) resolveOwnerHandle(ctx context.Context, owner string) string {
349349+ if !strings.HasPrefix(owner, "did:") {
350350+ return owner
351351+ }
352352+ if h.feedIndex != nil {
353353+ if profile, err := h.feedIndex.GetProfile(ctx, owner); err == nil && profile.Handle != "" {
354354+ return profile.Handle
355355+ }
356356+ }
357357+ return owner
358358+}
359359+345360// populateOGFields sets the standard OG metadata fields for an entity page.
346346-// The description follows the pattern "{type} from {owner} on arabica.social".
347347-func populateOGFields(layoutData *components.LayoutData, title, recordType, owner, baseURL, shareURL string) {
348348- layoutData.OGTitle = title
361361+// The title follows the pattern "{type} from {owner} on arabica.social".
362362+// The subtitle (OG description) shows record-specific detail like the bean name.
363363+func populateOGFields(layoutData *components.LayoutData, subtitle, recordType, owner, baseURL, shareURL string) {
349364 layoutData.OGType = "article"
350365351366 if owner != "" {
352352- layoutData.OGDescription = fmt.Sprintf("%s from %s on arabica.social", recordType, owner)
367367+ layoutData.OGTitle = fmt.Sprintf("%s from %s on arabica.social", recordType, owner)
353368 } else {
354354- layoutData.OGDescription = fmt.Sprintf("%s on arabica.social", recordType)
369369+ layoutData.OGTitle = fmt.Sprintf("%s on arabica.social", recordType)
355370 }
371371+372372+ layoutData.OGDescription = subtitle
356373357374 if baseURL != "" && shareURL != "" {
358375 layoutData.OGUrl = baseURL + shareURL