Browse Source

Translations, author pages

imwald
Nuša Pukšič 1 year ago
parent
commit
4f00582995
  1. 1
      assets/icons/symfony.svg
  2. 2
      composer.json
  3. 185
      composer.lock
  4. 1
      config/bundles.php
  5. 7
      config/packages/translation.yaml
  6. 12
      src/Controller/ArticleController.php
  7. 28
      src/Controller/AuthorController.php
  8. 6
      src/Controller/DefaultController.php
  9. 10
      src/Repository/UserEntityRepository.php
  10. 1
      src/Service/NostrClient.php
  11. 2
      src/Twig/Components/Organisms/CardList.php
  12. 25
      symfony.lock
  13. 9
      templates/components/Atoms/NameOrNpub.html.twig
  14. 11
      templates/pages/article.html.twig
  15. 12
      templates/pages/author.html.twig
  16. 0
      translations/.gitignore
  17. 2
      translations/messages.en.yaml

1
assets/icons/symfony.svg

@ -0,0 +1 @@ @@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 257"><circle cx="128" cy="128.827" r="128" fill="#1a171b"/><path fill="#fff" d="M183.706 48.124c-12.986.453-24.32 7.61-32.757 17.51c-9.342 10.855-15.557 23.73-20.035 36.872c-8.01-6.565-14.19-15.064-27.041-18.77c-9.933-2.852-20.366-1.674-29.96 5.474c-4.545 3.395-7.676 8.527-9.165 13.351c-3.855 12.537 4.053 23.694 7.645 27.7l7.853 8.416c1.619 1.65 5.518 5.955 3.612 12.127c-2.06 6.71-10.15 11.055-18.448 8.495c-3.706-1.13-9.03-3.891-7.838-7.779c.493-1.59 1.631-2.78 2.241-4.155c.56-1.181.827-2.067.997-2.587c1.516-4.95-.555-11.39-5.857-13.025c-4.946-1.516-10.007-.315-11.969 6.054c-2.225 7.235 1.237 20.366 19.783 26.084c21.729 6.676 40.11-5.155 42.717-20.586c1.642-9.665-2.722-16.845-10.717-26.08l-6.514-7.204c-3.946-3.942-5.301-10.661-1.217-15.825c3.446-4.356 8.354-6.215 16.392-4.029c11.733 3.186 16.963 11.327 25.69 17.893c-3.603 11.819-5.958 23.682-8.09 34.32l-1.299 7.931c-6.238 32.721-11 50.688-23.375 61.003c-2.493 1.773-6.057 4.427-11.429 4.612c-2.816.087-3.726-1.85-3.765-2.694c-.067-1.977 1.599-2.883 2.706-3.773c1.654-.902 4.155-2.398 3.985-7.191c-.18-5.664-4.872-10.575-11.654-10.35c-5.08.173-12.823 4.954-12.532 13.705c.303 9.039 8.728 15.813 21.43 15.384c6.79-.233 21.952-2.997 36.895-20.76c17.392-20.362 22.256-43.705 25.915-60.79l4.084-22.556c2.269.272 4.695.453 7.334.516c21.661.457 32.496-10.763 32.657-18.924c.107-4.939-3.241-9.799-7.928-9.689c-3.355.095-7.57 2.328-8.582 6.968c-.988 4.552 6.893 8.66.733 12.65c-4.376 2.832-12.221 4.828-23.269 3.206l2.009-11.103c4.1-21.055 9.157-46.954 28.341-47.584c1.398-.071 6.514.063 6.633 3.446c.035 1.13-.245 1.418-1.568 4.005c-1.347 2.017-1.855 3.734-1.792 5.707c.185 5.376 4.273 8.909 10.185 8.696c7.916-.256 10.193-7.963 10.063-11.921c-.32-9.3-10.122-15.175-23.1-14.75"/></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

2
composer.json

@ -34,7 +34,9 @@ @@ -34,7 +34,9 @@
"symfony/security-bundle": "7.1.*",
"symfony/serializer": "7.1.*",
"symfony/stimulus-bundle": "^2.22",
"symfony/translation": "7.1.*",
"symfony/twig-bundle": "7.1.*",
"symfony/ux-icons": "^2.22",
"symfony/ux-live-component": "^2.21",
"symfony/yaml": "7.1.*",
"twig/extra-bundle": "^2.12|^3.0",

185
composer.lock generated

@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "3f6c3be0f4791878aa1abbfb292b0c01",
"content-hash": "897e77674e1fcdc323faccc51cf19c34",
"packages": [
{
"name": "bitwasp/bech32",
@ -6760,6 +6760,100 @@ @@ -6760,6 +6760,100 @@
],
"time": "2024-11-13T13:31:21+00:00"
},
{
"name": "symfony/translation",
"version": "v7.1.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/translation.git",
"reference": "b9f72ab14efdb6b772f85041fa12f820dee8d55f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/translation/zipball/b9f72ab14efdb6b772f85041fa12f820dee8d55f",
"reference": "b9f72ab14efdb6b772f85041fa12f820dee8d55f",
"shasum": ""
},
"require": {
"php": ">=8.2",
"symfony/polyfill-mbstring": "~1.0",
"symfony/translation-contracts": "^2.5|^3.0"
},
"conflict": {
"symfony/config": "<6.4",
"symfony/console": "<6.4",
"symfony/dependency-injection": "<6.4",
"symfony/http-client-contracts": "<2.5",
"symfony/http-kernel": "<6.4",
"symfony/service-contracts": "<2.5",
"symfony/twig-bundle": "<6.4",
"symfony/yaml": "<6.4"
},
"provide": {
"symfony/translation-implementation": "2.3|3.0"
},
"require-dev": {
"nikic/php-parser": "^4.18|^5.0",
"psr/log": "^1|^2|^3",
"symfony/config": "^6.4|^7.0",
"symfony/console": "^6.4|^7.0",
"symfony/dependency-injection": "^6.4|^7.0",
"symfony/finder": "^6.4|^7.0",
"symfony/http-client-contracts": "^2.5|^3.0",
"symfony/http-kernel": "^6.4|^7.0",
"symfony/intl": "^6.4|^7.0",
"symfony/polyfill-intl-icu": "^1.21",
"symfony/routing": "^6.4|^7.0",
"symfony/service-contracts": "^2.5|^3",
"symfony/yaml": "^6.4|^7.0"
},
"type": "library",
"autoload": {
"files": [
"Resources/functions.php"
],
"psr-4": {
"Symfony\\Component\\Translation\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Provides tools to internationalize your application",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/translation/tree/v7.1.6"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2024-09-28T12:35:13+00:00"
},
{
"name": "symfony/translation-contracts",
"version": "v3.5.1",
@ -7113,6 +7207,95 @@ @@ -7113,6 +7207,95 @@
],
"time": "2024-11-07T15:49:33+00:00"
},
{
"name": "symfony/ux-icons",
"version": "v2.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/ux-icons.git",
"reference": "3a6fd4293fc200530b09960c41941a71354bc5fc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/ux-icons/zipball/3a6fd4293fc200530b09960c41941a71354bc5fc",
"reference": "3a6fd4293fc200530b09960c41941a71354bc5fc",
"shasum": ""
},
"require": {
"php": ">=8.1",
"symfony/framework-bundle": "^6.4|^7.0",
"symfony/twig-bundle": "^6.4|^7.0"
},
"conflict": {
"symfony/flex": "<1.13",
"symfony/ux-twig-component": "<2.21"
},
"require-dev": {
"psr/log": "^2|^3",
"symfony/asset-mapper": "^6.4|^7.0",
"symfony/console": "^6.4|^7.0",
"symfony/http-client": "6.4|^7.0",
"symfony/phpunit-bridge": "^6.3|^7.0",
"symfony/ux-twig-component": "^2.14",
"zenstruck/console-test": "^1.5"
},
"type": "symfony-bundle",
"extra": {
"thanks": {
"url": "https://github.com/symfony/ux",
"name": "symfony/ux"
}
},
"autoload": {
"psr-4": {
"Symfony\\UX\\Icons\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Kevin Bond",
"email": "kevinbond@gmail.com"
},
{
"name": "Simon André",
"email": "smn.andre@gmail.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Renders local and remote SVG icons in your Twig templates.",
"homepage": "https://symfony.com",
"keywords": [
"icons",
"svg",
"symfony-ux",
"twig"
],
"support": {
"source": "https://github.com/symfony/ux-icons/tree/v2.22.1"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2024-12-04T11:34:13+00:00"
},
{
"name": "symfony/ux-live-component",
"version": "v2.22.0",

1
config/bundles.php

@ -13,4 +13,5 @@ return [ @@ -13,4 +13,5 @@ return [
Symfony\Bundle\MakerBundle\MakerBundle::class => ['all' => true, 'prod' => false],
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['all' => true, 'prod' => false],
Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
Symfony\UX\Icons\UXIconsBundle::class => ['all' => true],
];

7
config/packages/translation.yaml

@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
framework:
default_locale: en
translator:
default_path: '%kernel.project_dir%/translations'
fallbacks:
- en
providers:

12
src/Controller/ArticleController.php

@ -4,8 +4,11 @@ namespace App\Controller; @@ -4,8 +4,11 @@ namespace App\Controller;
use App\Entity\Article;
use App\Entity\User;
use App\Service\NostrClient;
use App\Util\CommonMark\Converter;
use Doctrine\ORM\EntityManagerInterface;
use League\CommonMark\Exception\CommonMarkException;
use PHPUnit\Exception;
use Psr\Cache\CacheItemPoolInterface;
use Psr\Cache\InvalidArgumentException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
@ -15,11 +18,11 @@ use Symfony\Component\Routing\Attribute\Route; @@ -15,11 +18,11 @@ use Symfony\Component\Routing\Attribute\Route;
class ArticleController extends AbstractController
{
/**
* @throws InvalidArgumentException
* @throws InvalidArgumentException|CommonMarkException
*/
#[Route('/article/d/{slug}', name: 'article-slug')]
public function article(EntityManagerInterface $entityManager, CacheItemPoolInterface $articlesCache,
Converter $converter, $slug): Response
NostrClient $nostrClient, Converter $converter, $slug): Response
{
$article = null;
// check if an item with same eventId already exists in the db
@ -50,6 +53,11 @@ class ArticleController extends AbstractController @@ -50,6 +53,11 @@ class ArticleController extends AbstractController
}
// find user by npub
try {
$nostrClient->getMetadata([$article->getPubkey()]);
} catch (\Exception) {
// eh
}
$author = $entityManager->getRepository(User::class)->findOneBy(['npub' => $article->getPubkey()]);
return $this->render('Pages/article.html.twig', [

28
src/Controller/AuthorController.php

@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace App\Controller;
use App\Entity\Article;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class AuthorController extends AbstractController
{
#[Route('/p/{npub}', name: 'author-profile')]
public function index($npub, EntityManagerInterface $entityManager): Response
{
$author = $entityManager->getRepository(User::class)->findOneBy(['npub' => $npub]);
$articles = $entityManager->getRepository(Article::class)->findBy(['pubkey' => $npub], ['createdAt' => 'DESC']);
return $this->render('Pages/author.html.twig', [
'author' => $author,
'articles' => $articles
]);
}
}

6
src/Controller/DefaultController.php

@ -24,7 +24,11 @@ class DefaultController extends AbstractController @@ -24,7 +24,11 @@ class DefaultController extends AbstractController
#[Route('/', name: 'default')]
public function index(): Response
{
$list = $this->entityManager->getRepository(Article::class)->findBy([], ['createdAt' => 'DESC'], 10);
$original = $this->entityManager->getRepository(Article::class)->findBy([], ['createdAt' => 'DESC'], 10);
$list = array_filter($original, function ($obj) {
return !empty($obj->getSlug());
});
$npubs = array_map(function($obj) {
return $obj->getPubkey();

10
src/Repository/UserEntityRepository.php

@ -4,11 +4,12 @@ namespace App\Repository; @@ -4,11 +4,12 @@ namespace App\Repository;
use App\Entity\User;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Persistence\ManagerRegistry;
class UserEntityRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
public function __construct(ManagerRegistry $registry, private readonly EntityManagerInterface $entityManager)
{
parent::__construct($registry, User::class);
}
@ -16,10 +17,11 @@ class UserEntityRepository extends ServiceEntityRepository @@ -16,10 +17,11 @@ class UserEntityRepository extends ServiceEntityRepository
{
$entity = $this->findOneBy(['npub' => $user->getNpub()]);
if (!$entity) {
$this->_em->persist($user);
if ($entity) {
$user->setId($entity->getId());
}
$this->entityManager->persist($user);
return $entity;
return $user;
}
}

1
src/Service/NostrClient.php

@ -77,6 +77,7 @@ class NostrClient @@ -77,6 +77,7 @@ class NostrClient
// TODO make relays configurable
$relays = new RelaySet();
$relays->addRelay(new Relay('wss://purplepag.es')); // default metadata aggregator
$relays->addRelay(new Relay('wss://nos.lol')); // default metadata aggregator
$request = new Request($relays, $requestMessage);

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

@ -7,5 +7,5 @@ use Symfony\UX\TwigComponent\Attribute\AsTwigComponent; @@ -7,5 +7,5 @@ use Symfony\UX\TwigComponent\Attribute\AsTwigComponent;
#[AsTwigComponent]
final class CardList
{
public array $list;
public array $list;
}

25
symfony.lock

@ -174,6 +174,19 @@ @@ -174,6 +174,19 @@
"./assets/controllers/hello_controller.js"
]
},
"symfony/translation": {
"version": "7.1",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "6.3",
"ref": "e28e27f53663cc34f0be2837aba18e3a1bef8e7b"
},
"files": [
"config/packages/translation.yaml",
"translations/.gitignore"
]
},
"symfony/twig-bundle": {
"version": "7.1",
"recipe": {
@ -187,6 +200,18 @@ @@ -187,6 +200,18 @@
"./templates/base.html.twig"
]
},
"symfony/ux-icons": {
"version": "2.22",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "2.17",
"ref": "803a3bbd5893f9584969ab8670290cdfb6a0a5b5"
},
"files": [
"assets/icons/symfony.svg"
]
},
"symfony/ux-live-component": {
"version": "2.21",
"recipe": {

9
templates/components/Atoms/NameOrNpub.html.twig

@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
<span>
{% if author.displayName %}
{{ author.displayName }}
{% elseif author.name %}
{{ author.name }}
{% else %}
{{ author.npub }}
{% endif %}
</span>

11
templates/pages/article.html.twig

@ -8,13 +8,16 @@ @@ -8,13 +8,16 @@
{% if author %}
<div class="byline">
<span>
{{ 'text.byline'|trans }} <a href="{{ path('author', {'npub': author.npub}) }}">
<twig:NameOrNpub displayName="{{ author.displayName }}" name="{{ author.name }}" npub="{{ author.npub }}" />
{{ 'text.byline'|trans }} <a href="{{ path('author-profile', {'npub': author.npub}) }}">
<twig:atoms:NameOrNpub :author="author" />
</a>
</span>
<span>
<small><twig:ux:icon name="heroicons:pencil" class="icon" /> {{ article.createdAt|date('F j, Y') }}</small><br>
{% if article.publishedAt is not null %}<small>{{ article.publishedAt|date('F j, Y') }}</small>{% endif %}
{% if article.publishedAt is not null %}
<small>{{ article.publishedAt|date('F j, Y') }}</small>
{% else %}
<small><twig:ux:icon name="heroicons:pencil" class="icon" /> {{ article.createdAt|date('F j, Y') }}</small><br>
{% endif %}
</span>
</div>
{% endif %}

12
templates/pages/author.html.twig

@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1><twig:atoms:NameOrNpub :author="author"></twig:atoms:NameOrNpub></h1>
<p class="lede">
{{ author.about }}
</p>
<div>
<twig:Organisms:CardList :list="articles"></twig:Organisms:CardList>
</div>
{% endblock %}

0
translations/.gitignore vendored

2
translations/messages.en.yaml

@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
text:
byline: 'By'
Loading…
Cancel
Save