You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
169 lines
7.4 KiB
169 lines
7.4 KiB
{% extends 'base.html.twig' %} |
|
|
|
{% block title %}{{ article.title|trim }} — {{ website_name }}{% endblock %} |
|
|
|
{% block meta_description %} |
|
{% set _desc = article.summary|default('')|striptags|u.truncate(159, '…') %} |
|
<meta name="description" content="{{ _desc|e('html_attr') }}"> |
|
{% endblock %} |
|
|
|
{% block ogtags %} |
|
{# Upstream main only outputs og:image when article.image is set — unfurlers often show a blank card. Always set an absolute image + JSON-LD. #} |
|
{% set _img = article.image|default('')|trim %} |
|
{% if _img == '' %} |
|
{% set _og_image = absolute_url(asset('og-image.jpg')) %} |
|
{% set _og_default_dims = true %} |
|
{% elseif _img starts with '//' %} |
|
{% set _og_image = 'https:' ~ _img %} |
|
{% set _og_default_dims = false %} |
|
{% else %} |
|
{% set _og_image = absolute_url(_img) %} |
|
{% set _og_default_dims = false %} |
|
{% endif %} |
|
{% set _desc = article.summary|default('')|striptags|u.truncate(159, '…') %} |
|
{% set _canonical = url('article', { npub: npub|default(npub_from_hex(article.pubkey)), slug: article.slug }) %} |
|
{% set _author_name = '' %} |
|
{% if author is defined and author %} |
|
{% set _author_name = attribute(author, 'name')|default(attribute(author, 'display_name')|default('')) %} |
|
{% endif %} |
|
<meta property="og:title" content="{{ article.title|e('html_attr') }}"> |
|
<meta property="og:type" content="article"> |
|
<meta property="og:url" content="{{ _canonical|e('html_attr') }}"> |
|
<meta property="og:image" content="{{ _og_image|e('html_attr') }}"> |
|
{% if _og_image starts with 'https://' %} |
|
<meta property="og:image:secure_url" content="{{ _og_image|e('html_attr') }}"> |
|
{% endif %} |
|
{% if _og_default_dims %} |
|
<meta property="og:image:width" content="1200"> |
|
<meta property="og:image:height" content="630"> |
|
{% endif %} |
|
<meta property="og:description" content="{{ _desc|e('html_attr') }}"> |
|
<meta property="og:site_name" content="{{ website_name|e('html_attr') }}"> |
|
<link rel="canonical" href="{{ _canonical|e('html_attr') }}"> |
|
<meta name="twitter:card" content="summary_large_image"> |
|
<meta name="twitter:title" content="{{ article.title|e('html_attr') }}"> |
|
<meta name="twitter:description" content="{{ _desc|e('html_attr') }}"> |
|
<meta name="twitter:image" content="{{ _og_image|e('html_attr') }}"> |
|
<script type="application/ld+json">{{ { |
|
'@context': 'https://schema.org', |
|
'@type': 'BlogPosting', |
|
'headline': article.title, |
|
'description': _desc, |
|
'image': _og_image, |
|
'url': _canonical, |
|
'datePublished': article.displayDateTime|date('c'), |
|
'mainEntityOfPage': {'@type': 'WebPage', '@id': _canonical}, |
|
'publisher': {'@type': 'Organization', 'name': website_name}, |
|
'author': {'@type': 'Person', 'name': _author_name != '' ? _author_name : (npub|default('Author'))} |
|
}|json_encode|raw }}</script> |
|
{% endblock %} |
|
|
|
{% block body %} |
|
<div |
|
data-controller="article-highlight" |
|
class="article-page-root" |
|
data-action="click@window->article-highlight#closeOnOutside keydown@window->article-highlight#onKeydown" |
|
> |
|
|
|
{% if is_granted('ROLE_ADMIN') %} |
|
<button class="btn btn-primary" onclick="navigator.clipboard.writeText('30023:{{ article.pubkey }}:{{ article.slug }}')"> |
|
Copy coordinates |
|
</button> |
|
{% endif %} |
|
|
|
<div class="card"> |
|
<div class="card-header card-header--article"> |
|
<h1 class="card-title">{{ article.title }}</h1> |
|
{% set _art_share = nostr_event_share(article) %} |
|
{% if _art_share %}{% include 'components/Molecules/NostrShareMenu.html.twig' with { share: _art_share, event_menu: true } only %}{% endif %} |
|
</div> |
|
{% if author %} |
|
<div class="byline"> |
|
<span class="byline__author"> |
|
{{ 'text.byline'|trans }} |
|
<twig:Molecules:UserFromNpub ident="{{ article.pubkey }}" /> |
|
</span> |
|
<span> |
|
{% if article.displayDateTime %} |
|
<small>{{ article.displayDateTime|date('F j, Y') }}</small> |
|
{% endif %} |
|
</span> |
|
</div> |
|
{% endif %} |
|
</div> |
|
<div class="card-body"> |
|
<div class="lede"> |
|
{{ article.summary }} |
|
</div> |
|
|
|
{% if article.image %} |
|
<div class="article__image"> |
|
<img src="{{ article.image }}" alt="{{ article.title }}"> |
|
</div> |
|
{% endif %} |
|
|
|
<div class="article-main" data-article-highlight-target="article"> |
|
{{ content|raw }} |
|
</div> |
|
|
|
{% if article.topics|length > 0 %} |
|
<hr class="divider" /> |
|
<div class="tags"> |
|
{% for tag in article.topics %} |
|
<a class="tag" href="{{ path('topic', { topic: tag }) }}">{{ tag }}</a> |
|
{% endfor %} |
|
</div> |
|
{% endif %} |
|
|
|
</div> |
|
|
|
{% if article_highlights_client_json|default('')|trim != '' %} |
|
<script type="application/json" id="article-highlights-client-json" data-article-highlight-target="meta">{{ article_highlights_client_json|raw }}</script> |
|
{% endif %} |
|
<div |
|
class="article-body-highlight__popover" |
|
data-article-highlight-target="popover" |
|
data-article-highlight-turbo-permanent |
|
hidden |
|
role="dialog" |
|
aria-label="{{ 'highlight.popover'|trans }}" |
|
> |
|
<button type="button" class="article-body-highlight__close" data-action="article-highlight#closePopover" aria-label="{{ 'highlight.close'|trans }}">×</button> |
|
<div class="article-body-highlight__inner" data-article-highlight-target="popoverInner"></div> |
|
</div> |
|
|
|
<hr class="divider" /> |
|
|
|
{# <pre>#} |
|
{# {{ article.content }}#} |
|
{# </pre>#} |
|
{% set article_coordinate = (article.kind ? article.kind.value : 30023) ~ ':' ~ article.pubkey ~ ':' ~ article.slug %} |
|
{% set comments_query = { coordinate: article_coordinate, title: article.title|default('') }|merge(article.eventId ? { e: article.eventId } : {}) %} |
|
{% set _reply_ctx = comments_data.comment_reply_context|default(comment_reply_context|default(null)) %} |
|
{% include 'components/Molecules/ArticleReplyComposer.html.twig' with { comment_reply_context: _reply_ctx } only %} |
|
<section class="article-comments-async" id="article-comments" aria-label="Comments"> |
|
<div |
|
data-controller="article-comments" |
|
data-article-comments-wrapper |
|
data-article-comments-url-value="{{ path('article_comments_fragment', comments_query)|e('html_attr') }}" |
|
data-article-comments-preloaded-value="{{ (comments_preloaded|default(false)) ? 'true' : 'false' }}" |
|
> |
|
<div |
|
data-article-comments-target="container" |
|
class="comments {{ comments_preloaded|default(false) ? 'comments--from-cache' : 'comments--pending' }}" |
|
> |
|
{% if comments_preloaded|default(false) and comments_data is defined and comments_data is not null %} |
|
{% include 'components/Organisms/Comments.html.twig' with comments_data %} |
|
{% else %} |
|
<p class="text-subtle">Loading comments…</p> |
|
{% endif %} |
|
</div> |
|
</div> |
|
</section> |
|
</div> |
|
{% endblock %} |
|
|
|
{% block aside %} |
|
{# <h1>Suggestions</h1>#} |
|
{# <twig:Organisms:CardList :list="suggestions" />#} |
|
{% endblock %}
|
|
|