Browse Source

Revise routing, part 4

imwald
Nuša Pukšič 4 months ago
parent
commit
d537a900e0
  1. 4
      assets/styles/app.css
  2. 12
      assets/styles/layout.css
  3. 3
      src/Controller/ArticleController.php
  4. 68
      src/Controller/DefaultController.php
  5. 17
      src/Twig/Components/Molecules/Card.php
  6. 3
      src/Twig/Components/Organisms/CardList.php
  7. 5
      src/Twig/Components/Organisms/FeaturedList.php
  8. 11
      templates/components/Molecules/Card.html.twig
  9. 2
      templates/components/Organisms/CardList.html.twig
  10. 4
      templates/components/Organisms/FeaturedList.html.twig
  11. 2
      templates/magazine/magazine-front.html.twig
  12. 10
      templates/pages/article.html.twig
  13. 10
      templates/pages/category.html.twig
  14. 6
      templates/pages/latest.html.twig
  15. 21
      templates/pages/magazine.html.twig
  16. 7
      templates/pages/newsstand.html.twig

4
assets/styles/app.css

@ -283,10 +283,6 @@ div:nth-child(odd) .featured-list { @@ -283,10 +283,6 @@ div:nth-child(odd) .featured-list {
.header .container {
display: flex;
flex-direction: column;
align-items: start;
width: 100%;
max-width: 1200px;
padding: 0 20px;
}
.header__categories ul {

12
assets/styles/layout.css

@ -9,6 +9,10 @@ @@ -9,6 +9,10 @@
* - Footer (footer)
**/
body {
position: relative;
}
/* Layout Container */
.layout {
max-width: 100%;
@ -31,18 +35,12 @@ nav { @@ -31,18 +35,12 @@ nav {
header {
position: fixed;
width: 100vw;
width: 100%;
min-height: 60px;
top: 0;
left: 0;
}
.header__logo {
display: flex;
width: 100%;
margin-left: 10px;
}
nav ul {
list-style-type: none;
padding: 0;

3
src/Controller/ArticleController.php

@ -121,12 +121,15 @@ class ArticleController extends AbstractController @@ -121,12 +121,15 @@ class ArticleController extends AbstractController
}
}
$canonical = $this->generateUrl('article-slug', ['slug' => $article->getSlug()], 0);
return $this->render('pages/article.html.twig', [
'article' => $article,
'author' => $author,
'npub' => $npub,
'content' => $cacheItem->get(),
'canEdit' => $canEdit,
'canonical' => $canonical
]);
}

68
src/Controller/DefaultController.php

@ -4,16 +4,20 @@ declare(strict_types=1); @@ -4,16 +4,20 @@ declare(strict_types=1);
namespace App\Controller;
use App\Entity\Article;
use App\Entity\Event;
use App\Enum\KindsEnum;
use App\Service\RedisCacheService;
use App\Util\CommonMark\Converter;
use Doctrine\ORM\EntityManagerInterface;
use Elastica\Collapse;
use Elastica\Query;
use Elastica\Query\Terms;
use Exception;
use FOS\ElasticaBundle\Finder\FinderInterface;
use Psr\Cache\CacheItemPoolInterface;
use Psr\Cache\InvalidArgumentException;
use swentel\nostr\Key\Key;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
@ -218,6 +222,70 @@ class DefaultController extends AbstractController @@ -218,6 +222,70 @@ class DefaultController extends AbstractController
]);
}
/**
* @throws InvalidArgumentException
*/
#[Route('/mag/{mag}/cat/{cat}/d/{slug}', name: 'magazine-category-article')]
public function magArticle($mag, $cat, $slug,
RedisCacheService $redisCacheService,
CacheItemPoolInterface $articlesCache,
EntityManagerInterface $entityManager,
Converter $converter,
LoggerInterface $logger): Response
{
$magazine = $redisCacheService->getMagazineIndex($mag);
$article = null;
// check if an item with same eventId already exists in the db
$repository = $entityManager->getRepository(Article::class);
// slug might be url encoded, decode it
$slug = urldecode($slug);
$articles = $repository->findBy(['slug' => $slug]);
$revisions = count($articles);
if ($revisions === 0) {
throw $this->createNotFoundException('The article could not be found');
}
if ($revisions > 1) {
// sort articles by created at date
usort($articles, function ($a, $b) {
return $b->getCreatedAt() <=> $a->getCreatedAt();
});
}
$article = $articles[0];
$cacheKey = 'article_' . $article->getEventId();
$cacheItem = $articlesCache->getItem($cacheKey);
if (!$cacheItem->isHit()) {
$cacheItem->set($converter->convertToHTML($article->getContent()));
$articlesCache->save($cacheItem);
}
$key = new Key();
$npub = $key->convertPublicKeyToBech32($article->getPubkey());
$author = $redisCacheService->getMetadata($npub);
// set canonical url to this article as article-slug path
$canonical = $this->generateUrl('article-slug', [
'slug' => $article->getSlug()
], 0);
return $this->render('pages/article.html.twig', [
'magazine' => $magazine,
'mag' => $mag,
'article' => $article,
'author' => $author,
'npub' => $npub,
'content' => $cacheItem->get(),
'canEdit' => false,
'canonical' => $canonical
]);
}
/**
* @throws InvalidArgumentException
*/

17
src/Twig/Components/Molecules/Card.php

@ -2,19 +2,26 @@ @@ -2,19 +2,26 @@
namespace App\Twig\Components\Molecules;
use App\Entity\User;
use App\Service\NostrClient;
use Doctrine\ORM\EntityManagerInterface;
use swentel\nostr\Event\Event;
use Symfony\UX\TwigComponent\Attribute\AsTwigComponent;
#[AsTwigComponent]
final class Card
{
public string $category = '';
public ?Event $category = null; // category index passed from parent (optional)
public ?string $cat = "abc"; // computed category slug from $category (optional)
public ?string $mag = null; // magazine slug passed from parent (optional)
public object $article;
public function __construct()
public function mount($category)
{
if ($category) {
$tags = $category->getTags();
$dTag = array_filter($tags, function($tag) {
return ($tag[0] === 'd');
});
$this->cat = array_pop($dTag)[1];
}
}
}

3
src/Twig/Components/Organisms/CardList.php

@ -2,10 +2,13 @@ @@ -2,10 +2,13 @@
namespace App\Twig\Components\Organisms;
use swentel\nostr\Event\Event;
use Symfony\UX\TwigComponent\Attribute\AsTwigComponent;
#[AsTwigComponent]
final class CardList
{
public array $list;
public ?string $mag = null; // magazine slug passed from parent (optional)
public ?Event $category = null; // category index passed from parent (optional)
}

5
src/Twig/Components/Organisms/FeaturedList.php

@ -13,7 +13,9 @@ use Symfony\UX\TwigComponent\Attribute\AsTwigComponent; @@ -13,7 +13,9 @@ use Symfony\UX\TwigComponent\Attribute\AsTwigComponent;
#[AsTwigComponent]
final class FeaturedList
{
public string $mag;
public string $category;
public string $catSlug;
public string $title;
public array $list = [];
@ -40,6 +42,9 @@ final class FeaturedList @@ -40,6 +42,9 @@ final class FeaturedList
if ($tag[0] === 'title') {
$this->title = $tag[1];
}
if ($tag[0] === 'd') {
$this->catSlug = $tag[1];
}
if ($tag[0] === 'a') {
$parts = explode(':', $tag[1], 3);
$slugs[] = end($parts);

11
templates/components/Molecules/Card.html.twig

@ -1,18 +1,17 @@ @@ -1,18 +1,17 @@
{% if article is defined %}
<div class="card">
<div class="metadata">
{% if category %}
<small>{{ category }}</small>
{% else %}
{% if not is_author_profile %}
<p>by <twig:Molecules:UserFromNpub ident="{{ article.pubkey }}" /></p>
{% endif %}
<small>{{ article.createdAt|date('F j Y') }}</small>
{% endif %}
</div>
<a href="{{ path('article-slug', {slug: article.slug}) }}">
{% set link = path('article-slug', {slug: article.slug}) %}
{% if cat and mag %}
{% set link = path('magazine-category-article', {slug: article.slug, cat: cat, mag: mag}) %}
{% endif %}
<a href="{{ link }}">
<div class="card-header">
{% if category %}<small class="text-uppercase">{{ category }}</small>{% endif %}
{% if article.image %}
<img src="{{ article.image }}" alt="Cover image for {{ article.title }}" onerror="this.style.display='none';" >
{% endif %}

2
templates/components/Organisms/CardList.html.twig

@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
{% set is_author_profile = is_author_profile|default(false) %}
{% for item in list %}
{% if item.slug is not empty and item.title is not empty %}
<twig:Molecules:Card :article="item" :is_author_profile="is_author_profile"></twig:Molecules:Card>
<twig:Molecules:Card :article="item" :is_author_profile="is_author_profile" :category="category" :mag="mag"></twig:Molecules:Card>
{% endif %}
{% endfor %}
</div>

4
templates/components/Organisms/FeaturedList.html.twig

@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
<div>
{% set feature = list[0] %}
<div class="card">
<a href="{{ path('article-slug', {slug: feature.slug}) }}">
<a href="{{ path('magazine-category-article', {slug: feature.slug, cat: catSlug, mag: mag}) }}">
<div class="card-header">
{% if feature.image %}
<img src="{{ feature.image }}" alt="Cover image for {{ feature.title }}">
@ -26,7 +26,7 @@ @@ -26,7 +26,7 @@
{% for item in list %}
{% if item != feature %}
<div class="card">
<a href="{{ path('article-slug', {slug: item.slug}) }}">
<a href="{{ path('magazine-category-article', {slug: feature.slug, cat: catSlug, mag: mag}) }}">
<div class="card-body">
<h2 class="card-title">{{ item.title }}</h2>
<p class="lede truncate">

2
templates/magazine/magazine-front.html.twig

@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
<section class="mb-5">
{% if categoryTags is not empty %}
{% for cat in categoryTags %}
<twig:Organisms:FeaturedList category="{{ cat }}" class="featured-list"/>
<twig:Organisms:FeaturedList :mag="mag" category="{{ cat }}" class="featured-list"/>
{% endfor %}
{% endif %}
</section>

10
templates/pages/article.html.twig

@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
{% block ogtags %}
<meta property="og:title" content="{{ article.title }}">
<meta property="og:type" content="article">
<meta property="og:url" content="{{ app.request.uri }}">
<meta property="og:url" content="{{ canonical }}">
{% if article.image %}
<meta property="og:image" content="{{ article.image }}">
{% endif %}
@ -12,6 +12,9 @@ @@ -12,6 +12,9 @@
{% endblock %}
{% block body %}
{% if magazine is defined %}
<twig:Organisms:MagazineHero :mag="mag" :magazine="magazine" />
{% endif %}
<div class="article-actions">
{% if canEdit %}
@ -25,6 +28,7 @@ @@ -25,6 +28,7 @@
{% endif %}
</div>
<div class="w-container">
<div class="card">
<div class="card-header">
<h1 class="card-title">{{ article.title }}</h1>
@ -76,10 +80,8 @@ @@ -76,10 +80,8 @@
<hr class="divider" />
{# <pre>#}
{# {{ article.content }}#}
{# </pre>#}
<twig:Organisms:Comments current="30023:{{ article.pubkey }}:{{ article.slug|e }}"></twig:Organisms:Comments>
</div>
{% endblock %}
{% block aside %}

10
templates/pages/category.html.twig

@ -8,16 +8,8 @@ @@ -8,16 +8,8 @@
<meta property="og:site_name" content="Newsroom">
{% endblock %}
{% block nav %}
{% endblock %}
{% block body %}
<twig:Organisms:MagazineHero :mag="mag" :magazine="magazine" />
<twig:Organisms:CardList :list="list" class="article-list" />
{% endblock %}
{% block aside %}
{# <h6>Magazines</h6>#}
{# <twig:Organisms:ZineList />#}
<twig:Organisms:CardList :list="list" :category="index" :mag="mag" class="article-list" />
{% endblock %}

6
templates/pages/latest.html.twig

@ -1,6 +1,12 @@ @@ -1,6 +1,12 @@
{% extends 'layout.html.twig' %}
{% block body %}
<section class="d-flex gap-3 center ln-section--newsstand mb-3">
<div class="container mt-5 mb-5">
<h1>Hot</h1>
<p class="eyebrow">off the presses</p>
</div>
</section>
<div class="w-container">
<twig:Organisms:CardList :list="latest" />
</div>

21
templates/pages/magazine.html.twig

@ -1,21 +0,0 @@ @@ -1,21 +0,0 @@
{% extends 'layout.html.twig' %}
{% block ogtags %}
<meta property="og:title" content="{{ magazine.title }}">
<meta property="og:type" content="website">
<meta property="og:url" content="{{ app.request.uri }}">
<meta property="og:description" content="{{ magazine.summary }}">
<meta property="og:site_name" content="Newsroom">
{% endblock %}
{% block nav %}
{% endblock %}
{% block body %}
{# hero #}
<twig:Organisms:MagazineHero :magazine="magazine" class="mb-4"/>
{# content #}
{% for item in indices %}
<twig:Organisms:FeaturedList :category="item" class="featured-list"/>
{% endfor %}
{% endblock %}

7
templates/pages/newsstand.html.twig

@ -10,6 +10,13 @@ @@ -10,6 +10,13 @@
<section class="mb-5">
<twig:Organisms:ZineList />
</section>
<section class="d-flex gap-3 center ln-section--newsroom">
<div class="container mt-5 mb-5">
<h1>More magazines soon</h1>
<p class="eyebrow">this is only the beginning</p>
</div>
</section>
{% endblock %}
{% block aside %}

Loading…
Cancel
Save