diff --git a/assets/styles/app.css b/assets/styles/app.css index 135a567..14c02d7 100644 --- a/assets/styles/app.css +++ b/assets/styles/app.css @@ -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 { diff --git a/assets/styles/layout.css b/assets/styles/layout.css index 333a9a6..29820cc 100644 --- a/assets/styles/layout.css +++ b/assets/styles/layout.css @@ -9,6 +9,10 @@ * - Footer (footer) **/ +body { + position: relative; +} + /* Layout Container */ .layout { max-width: 100%; @@ -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; diff --git a/src/Controller/ArticleController.php b/src/Controller/ArticleController.php index bd70cbf..b9c7200 100644 --- a/src/Controller/ArticleController.php +++ b/src/Controller/ArticleController.php @@ -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 ]); } diff --git a/src/Controller/DefaultController.php b/src/Controller/DefaultController.php index 96c028d..310aa2e 100644 --- a/src/Controller/DefaultController.php +++ b/src/Controller/DefaultController.php @@ -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 ]); } + + /** + * @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 */ diff --git a/src/Twig/Components/Molecules/Card.php b/src/Twig/Components/Molecules/Card.php index 5673a6d..d196d19 100644 --- a/src/Twig/Components/Molecules/Card.php +++ b/src/Twig/Components/Molecules/Card.php @@ -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]; + } } } diff --git a/src/Twig/Components/Organisms/CardList.php b/src/Twig/Components/Organisms/CardList.php index fb671de..a415d78 100644 --- a/src/Twig/Components/Organisms/CardList.php +++ b/src/Twig/Components/Organisms/CardList.php @@ -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) } diff --git a/src/Twig/Components/Organisms/FeaturedList.php b/src/Twig/Components/Organisms/FeaturedList.php index 01cd6a8..a130d50 100644 --- a/src/Twig/Components/Organisms/FeaturedList.php +++ b/src/Twig/Components/Organisms/FeaturedList.php @@ -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 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); diff --git a/templates/components/Molecules/Card.html.twig b/templates/components/Molecules/Card.html.twig index e6904d0..c817b78 100644 --- a/templates/components/Molecules/Card.html.twig +++ b/templates/components/Molecules/Card.html.twig @@ -1,18 +1,17 @@ {% if article is defined %}
diff --git a/templates/magazine/magazine-front.html.twig b/templates/magazine/magazine-front.html.twig
index ff14dc6..c02f7b9 100644
--- a/templates/magazine/magazine-front.html.twig
+++ b/templates/magazine/magazine-front.html.twig
@@ -16,7 +16,7 @@