From 649cecfa36454147382a264b3be6e48a53bbe999 Mon Sep 17 00:00:00 2001 From: Dendy Faist Date: Thu, 4 Sep 2025 17:08:37 +0200 Subject: [PATCH] feat: Implement individual kanji view with niceties --- src/Controller/KanjiController.php | 32 ++++++++++-- src/Service/CharListService.php | 23 ++++++++- src/Twig/Extension/AppExtension.php | 28 +++++++++++ src/Twig/Runtime/AppExtensionRuntime.php | 18 +++++++ src/Utils/Number.php | 6 +++ templates/base.html.twig | 62 ++++++++++++++++++++++++ templates/kanji/grid.html.twig | 28 +++++++---- templates/kanji/view.html.twig | 60 +++++++++++++++++++++++ 8 files changed, 243 insertions(+), 14 deletions(-) create mode 100644 src/Twig/Extension/AppExtension.php create mode 100644 src/Twig/Runtime/AppExtensionRuntime.php create mode 100644 templates/kanji/view.html.twig diff --git a/src/Controller/KanjiController.php b/src/Controller/KanjiController.php index b807f35..a528e89 100644 --- a/src/Controller/KanjiController.php +++ b/src/Controller/KanjiController.php @@ -5,6 +5,7 @@ namespace App\Controller; use App\Entity\UnicodeNote; use App\Service\AnkiService; use App\Service\CharListService; +use App\Utils\Japanese; use App\Utils\Number; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; @@ -79,10 +80,6 @@ class KanjiController extends AbstractController string $end, Request $request, ): Response { - $jiten = json_decode(file_get_contents( - "{$this->getParameter('kernel.project_dir')}/data/kanken-links.json", - ), true); - $charInfo = $this->getCharInfo(force: $request->isNoCache()); $chars = []; @@ -115,4 +112,31 @@ class KanjiController extends AbstractController return new Response(); } + + #[Route('/{char}/view', 'view', methods: 'GET')] + public function view(string $char): Response + { + $charStr = ctype_xdigit($char) ? Number::parseCodepoint($char) : $char; + $codepoint = ctype_xdigit($char) ? $char : dechex(mb_ord($char)); + + $charInfo = $this->getCharInfo()[$charStr] ?? []; + //$listTitles = $this->charList->getTitles(); + + $jiten = json_decode(file_get_contents( + "{$this->getParameter('kernel.project_dir')}/data/kanken-links.json", + ), true); + + + $ebookRef = require "$this->varBasepath/ebook-ref.php"; + + return $this->render(self::tmpl('view'), [ + 'char' => $charStr, + 'codepoint' => $codepoint, + 'info' => $charInfo, + 'ref' => $ebookRef[$charStr] ?? [], + 'jiten_href' => key_exists($charStr, $jiten) + ? "https://kanji.jitenon.jp/kanji{$jiten[$charStr]}" + : null + ]); + } } diff --git a/src/Service/CharListService.php b/src/Service/CharListService.php index 8f9423f..5e6737d 100644 --- a/src/Service/CharListService.php +++ b/src/Service/CharListService.php @@ -3,6 +3,8 @@ namespace App\Service; use App\Utils\Japanese; +use DirectoryIterator; +use Symfony\Component\Filesystem\Filesystem; class CharListService { @@ -15,7 +17,7 @@ class CharListService * * @return array|array>> */ - function getList(string $name): array + public function getList(string $name): array { if (!ctype_alnum($name)) throw new \Exception(sprintf( 'Invalid name for list "%s". Only alphanumeric characters allowed', @@ -68,6 +70,25 @@ class CharListService return $ret; } + /** @return array */ + public function getTitles(): array + { + $ret = []; + + $dirIter = new DirectoryIterator($this->basepath); + foreach ($dirIter as $entry) { + if ( + $entry->isDot() or + !str_ends_with($entry->getFilename(), ".list") + ) continue; + + $file = $entry->openFile(); + $ret[$entry->getBasename('.list')] = $file->fgets(); + } + + return $ret; + } + /** * Returns array on success, true on non-block * diff --git a/src/Twig/Extension/AppExtension.php b/src/Twig/Extension/AppExtension.php new file mode 100644 index 0000000..c73f93d --- /dev/null +++ b/src/Twig/Extension/AppExtension.php @@ -0,0 +1,28 @@ + ['html']] + // Reference: https://twig.symfony.com/doc/3.x/advanced.html#automatic-escaping + new TwigFilter('basename', basename(...)), + ]; + } + + public function getFunctions(): array + { + return [ + //new TwigFunction('function_name', [AppExtensionRuntime::class, 'doSomething']), + ]; + } +} diff --git a/src/Twig/Runtime/AppExtensionRuntime.php b/src/Twig/Runtime/AppExtensionRuntime.php new file mode 100644 index 0000000..eb9e189 --- /dev/null +++ b/src/Twig/Runtime/AppExtensionRuntime.php @@ -0,0 +1,18 @@ + {% block body %}{% endblock %} + + + diff --git a/templates/kanji/grid.html.twig b/templates/kanji/grid.html.twig index 07f5cf7..37c9c34 100644 --- a/templates/kanji/grid.html.twig +++ b/templates/kanji/grid.html.twig @@ -45,7 +45,12 @@

{{ block('title') }}

-
+
{% for char in characters %}
-
- {% if char.jiten_href != null %} +
+ {#{% if char.jiten_href != null %} {{- char.str -}} - {% else %} + {% else %}#} {{- char.str -}} - {% endif %} + {#{% endif %}#} +
-
+
{% if char.lists.unicode is not defined %} + +
+

Appeareances

+ {% for refname, refcount in ref %} +
{{ refname|basename }}: {{ refcount }}
+ {% endfor %} +
+