Create component system to help cut down on view duplication, see #31
Some checks reported errors
timw4mail/HummingBirdAnimeClient/pipeline/head Something is wrong with the build of this commit
Some checks reported errors
timw4mail/HummingBirdAnimeClient/pipeline/head Something is wrong with the build of this commit
This commit is contained in:
parent
2f2260e0b4
commit
386938c75f
@ -20,6 +20,7 @@ use Aura\Html\HelperLocatorFactory;
|
|||||||
use Aura\Router\RouterContainer;
|
use Aura\Router\RouterContainer;
|
||||||
use Aura\Session\SessionFactory;
|
use Aura\Session\SessionFactory;
|
||||||
use Aviat\AnimeClient\API\{Anilist, Kitsu};
|
use Aviat\AnimeClient\API\{Anilist, Kitsu};
|
||||||
|
use Aviat\AnimeClient\Component;
|
||||||
use Aviat\AnimeClient\Model;
|
use Aviat\AnimeClient\Model;
|
||||||
use Aviat\Banker\Teller;
|
use Aviat\Banker\Teller;
|
||||||
use Aviat\Ion\Config;
|
use Aviat\Ion\Config;
|
||||||
@ -31,6 +32,9 @@ use Monolog\Handler\RotatingFileHandler;
|
|||||||
use Monolog\Logger;
|
use Monolog\Logger;
|
||||||
use Psr\SimpleCache\CacheInterface;
|
use Psr\SimpleCache\CacheInterface;
|
||||||
|
|
||||||
|
define('APP_DIR', __DIR__);
|
||||||
|
define('TEMPLATE_DIR', APP_DIR . '/templates');
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Setup DI container
|
// Setup DI container
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@ -72,28 +76,45 @@ return static function (array $configArray = []): Container {
|
|||||||
// Create Aura Router Object
|
// Create Aura Router Object
|
||||||
$container->set('aura-router', fn() => new RouterContainer);
|
$container->set('aura-router', fn() => new RouterContainer);
|
||||||
|
|
||||||
// Create Html helper Object
|
// Create Html helpers
|
||||||
$container->set('html-helper', static function(ContainerInterface $container) {
|
$container->set('html-helper', static function(ContainerInterface $container) {
|
||||||
$htmlHelper = (new HelperLocatorFactory)->newInstance();
|
$htmlHelper = (new HelperLocatorFactory)->newInstance();
|
||||||
$htmlHelper->set('menu', static function() use ($container) {
|
$helpers = [
|
||||||
$menuHelper = new Helper\Menu();
|
'menu' => Helper\Menu::class,
|
||||||
$menuHelper->setContainer($container);
|
'field' => Helper\Form::class,
|
||||||
return $menuHelper;
|
'picture' => Helper\Picture::class,
|
||||||
});
|
];
|
||||||
$htmlHelper->set('field', static function() use ($container) {
|
|
||||||
$formHelper = new Helper\Form();
|
foreach ($helpers as $name => $class)
|
||||||
$formHelper->setContainer($container);
|
{
|
||||||
return $formHelper;
|
$htmlHelper->set($name, static function() use ($class, $container) {
|
||||||
});
|
$helper = new $class;
|
||||||
$htmlHelper->set('picture', static function() use ($container) {
|
$helper->setContainer($container);
|
||||||
$pictureHelper = new Helper\Picture();
|
return $helper;
|
||||||
$pictureHelper->setContainer($container);
|
});
|
||||||
return $pictureHelper;
|
}
|
||||||
});
|
|
||||||
|
|
||||||
return $htmlHelper;
|
return $htmlHelper;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Create Component helpers
|
||||||
|
$container->set('component-helper', static function () {
|
||||||
|
$helper = (new HelperLocatorFactory)->newInstance();
|
||||||
|
$components = [
|
||||||
|
'character' => Component\Character::class,
|
||||||
|
'media' => Component\Media::class,
|
||||||
|
'tabs' => Component\Tabs::class,
|
||||||
|
'verticalTabs' => Component\VerticalTabs::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($components as $name => $componentClass)
|
||||||
|
{
|
||||||
|
$helper->set($name, fn () => new $componentClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $helper;
|
||||||
|
});
|
||||||
|
|
||||||
// Create Request Object
|
// Create Request Object
|
||||||
$container->set('request', fn () => ServerRequestFactory::fromGlobals(
|
$container->set('request', fn () => ServerRequestFactory::fromGlobals(
|
||||||
$_SERVER,
|
$_SERVER,
|
||||||
|
6
app/templates/character.php
Normal file
6
app/templates/character.php
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<article class="<?= $className ?>">
|
||||||
|
<div class="name">
|
||||||
|
<a href="<?= $link ?>"><?= $name ?></a>
|
||||||
|
</div>
|
||||||
|
<a href="<?= $link ?>"><?= $picture ?></a>
|
||||||
|
</article>
|
12
app/templates/media.php
Normal file
12
app/templates/media.php
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<article class="<?= $className ?>">
|
||||||
|
<a href="<?= $link ?>"><?= $picture ?></a>
|
||||||
|
<div class="name">
|
||||||
|
<a href="<?= $link ?>">
|
||||||
|
<?= array_shift($titles) ?>
|
||||||
|
<?php foreach ($titles as $title): ?>
|
||||||
|
<br />
|
||||||
|
<small><?= $title ?></small>
|
||||||
|
<?php endforeach ?>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</article>
|
23
app/templates/tabs.php
Normal file
23
app/templates/tabs.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<div class="tabs">
|
||||||
|
<?php $i = 0; foreach ($data as $tabName => $tabData): ?>
|
||||||
|
<?php if ( ! empty($tabData)): ?>
|
||||||
|
<?php $id = "{$name}-{$i}"; ?>
|
||||||
|
<input
|
||||||
|
role='tab'
|
||||||
|
aria-controls="_<?= $id ?>"
|
||||||
|
type="radio"
|
||||||
|
name="<?= $name ?>"
|
||||||
|
id="<?= $id ?>"
|
||||||
|
<?= ($i === 0) ? 'checked="checked"' : '' ?>
|
||||||
|
/>
|
||||||
|
<label for="<?= $id ?>"><?= ucfirst($tabName) ?></label>
|
||||||
|
<section
|
||||||
|
id="_<?= $id ?>"
|
||||||
|
role="tabpanel"
|
||||||
|
class="<?= $className ?>"
|
||||||
|
>
|
||||||
|
<?= $callback($tabData, $tabName) ?>
|
||||||
|
</section>
|
||||||
|
<?php endif ?>
|
||||||
|
<?php $i++; endforeach ?>
|
||||||
|
</div>
|
25
app/templates/vertical-tabs.php
Normal file
25
app/templates/vertical-tabs.php
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<div class="vertical-tabs">
|
||||||
|
<?php $i = 0; ?>
|
||||||
|
<?php foreach ($data as $tabName => $tabData): ?>
|
||||||
|
<?php $id = "{$name}-{$i}" ?>
|
||||||
|
<div class="tab">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
role='tab'
|
||||||
|
aria-controls="_<?= $id ?>"
|
||||||
|
name="staff-roles"
|
||||||
|
id="<?= $id ?>"
|
||||||
|
<?= $i === 0 ? 'checked="checked"' : '' ?>
|
||||||
|
/>
|
||||||
|
<label for="<?= $id ?>"><?= $tabName ?></label>
|
||||||
|
<section
|
||||||
|
id='_<?= $id ?>'
|
||||||
|
role="tabpanel"
|
||||||
|
class="<?= $className ?>"
|
||||||
|
>
|
||||||
|
<?= $callback($tabData, $tabName) ?>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
<?php $i++; ?>
|
||||||
|
<?php endforeach ?>
|
||||||
|
</div>
|
@ -1,9 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Aviat\AnimeClient\API\Kitsu;
|
use Aviat\AnimeClient\API\Kitsu;
|
||||||
use function Aviat\AnimeClient\getLocalImg;
|
use function Aviat\AnimeClient\getLocalImg;
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<main class="details fixed">
|
<main class="details fixed">
|
||||||
<section class="flex">
|
<section class="flex" unselectable>
|
||||||
<aside class="info">
|
<aside class="info">
|
||||||
<?= $helper->picture("images/anime/{$data['id']}-original.webp") ?>
|
<?= $helper->picture("images/anime/{$data['id']}-original.webp") ?>
|
||||||
|
|
||||||
@ -115,81 +117,69 @@ use function Aviat\AnimeClient\getLocalImg;
|
|||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
<?php if ( ! empty($data['trailer_id'])): ?>
|
<?php if ( ! empty($data['trailer_id'])): ?>
|
||||||
<div class="responsive-iframe">
|
<div class="responsive-iframe">
|
||||||
<h4>Trailer</h4>
|
<h4>Trailer</h4>
|
||||||
<iframe
|
<iframe
|
||||||
width="560"
|
width="560"
|
||||||
height="315"
|
height="315"
|
||||||
src="https://www.youtube.com/embed/<?= $data['trailer_id'] ?>"
|
role='img'
|
||||||
frameborder="0"
|
src="https://www.youtube.com/embed/<?= $data['trailer_id'] ?>"
|
||||||
allow="autoplay; encrypted-media"
|
allow="autoplay; encrypted-media"
|
||||||
allowfullscreen
|
allowfullscreen
|
||||||
></iframe>
|
tabindex='0'
|
||||||
|
title="<?= $data['title'] ?> trailer video"
|
||||||
|
></iframe>
|
||||||
</div>
|
</div>
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
</article>
|
</article>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<?php if (count($data['characters']) > 0): ?>
|
<?php if (count($data['characters']) > 0): ?>
|
||||||
<section>
|
<section>
|
||||||
<h2>Characters</h2>
|
<h2>Characters</h2>
|
||||||
|
|
||||||
<div class="tabs">
|
<?= $component->tabs('character-types', $data['characters'], static function ($characterList, $role)
|
||||||
<?php $i = 0 ?>
|
use ($component, $url, $helper) {
|
||||||
<?php foreach ($data['characters'] as $role => $list): ?>
|
$rendered = [];
|
||||||
<input
|
foreach ($characterList as $id => $character):
|
||||||
type="radio" name="character-types"
|
if (empty($character['image']['original']))
|
||||||
id="character-types-<?= $i ?>" <?= ($i === 0) ? 'checked' : '' ?> />
|
{
|
||||||
<label for="character-types-<?= $i ?>"><?= ucfirst($role) ?></label>
|
continue;
|
||||||
<section class="content media-wrap flex flex-wrap flex-justify-start">
|
}
|
||||||
<?php foreach ($list as $id => $char): ?>
|
$rendered[] = $component->character(
|
||||||
<?php if ( ! empty($char['image']['original'])): ?>
|
$character['name'],
|
||||||
<article class="<?= $role === 'supporting' ? 'small-' : '' ?>character">
|
$url->generate('character', ['slug' => $character['slug']]),
|
||||||
<?php $link = $url->generate('character', ['slug' => $char['slug']]) ?>
|
$helper->picture("images/characters/{$id}.webp"),
|
||||||
<div class="name">
|
(strtolower($role) !== 'main') ? 'small-character' : 'character'
|
||||||
<?= $helper->a($link, $char['name']) ?>
|
);
|
||||||
</div>
|
endforeach;
|
||||||
<a href="<?= $link ?>">
|
|
||||||
<?= $helper->picture("images/characters/{$id}.webp") ?>
|
return implode('', array_map('mb_trim', $rendered));
|
||||||
</a>
|
}) ?>
|
||||||
</article>
|
</section>
|
||||||
<?php endif ?>
|
|
||||||
<?php endforeach ?>
|
|
||||||
</section>
|
|
||||||
<?php $i++; ?>
|
|
||||||
<?php endforeach ?>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
|
|
||||||
<?php if (count($data['staff']) > 0): ?>
|
<?php if (count($data['staff']) > 0): ?>
|
||||||
<section>
|
<section>
|
||||||
<h2>Staff</h2>
|
<h2>Staff</h2>
|
||||||
|
|
||||||
<div class="vertical-tabs">
|
<?= $component->verticalTabs('staff-role', $data['staff'], static function ($staffList)
|
||||||
<?php $i = 0; ?>
|
use ($component, $url, $helper) {
|
||||||
<?php foreach ($data['staff'] as $role => $people): ?>
|
$rendered = [];
|
||||||
<div class="tab">
|
foreach ($staffList as $id => $person):
|
||||||
<input type="radio" name="staff-roles" id="staff-role<?= $i ?>" <?= $i === 0 ? 'checked' : '' ?> />
|
if (empty($person['image']['original']))
|
||||||
<label for="staff-role<?= $i ?>"><?= $role ?></label>
|
{
|
||||||
<section class='content media-wrap flex flex-wrap flex-justify-start'>
|
continue;
|
||||||
<?php foreach ($people as $pid => $person): ?>
|
}
|
||||||
<article class='character small-person'>
|
$rendered[] = $component->character(
|
||||||
<?php $link = $url->generate('person', ['id' => $person['id'], 'slug' => $person['slug']]) ?>
|
$person['name'],
|
||||||
<div class="name">
|
$url->generate('person', ['id' => $person['id'], 'slug' => $person['slug']]),
|
||||||
<a href="<?= $link ?>">
|
$helper->picture(getLocalImg($person['image']['original'] ?? NULL)),
|
||||||
<?= $person['name'] ?>
|
'character small-person',
|
||||||
</a>
|
);
|
||||||
</div>
|
endforeach;
|
||||||
<a href="<?= $link ?>">
|
|
||||||
<?= $helper->picture(getLocalImg($person['image']['original'] ?? NULL)) ?>
|
return implode('', array_map('mb_trim', $rendered));
|
||||||
</a>
|
}) ?>
|
||||||
</article>
|
</section>
|
||||||
<?php endforeach ?>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
<?php $i++; ?>
|
|
||||||
<?php endforeach ?>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
</main>
|
</main>
|
@ -156,65 +156,50 @@ use Aviat\AnimeClient\API\Kitsu;
|
|||||||
<?php if ( ! empty($vas)): ?>
|
<?php if ( ! empty($vas)): ?>
|
||||||
<h4>Voice Actors</h4>
|
<h4>Voice Actors</h4>
|
||||||
|
|
||||||
<div class="tabs">
|
<?= $component->tabs('character-vas', $vas, static function ($casting) use ($url, $component, $helper) {
|
||||||
<?php $i = 0; ?>
|
$castings = [];
|
||||||
|
foreach ($casting as $id => $c):
|
||||||
|
$person = $component->character(
|
||||||
|
$c['person']['name'],
|
||||||
|
$url->generate('person', [
|
||||||
|
'id' => $c['person']['id'],
|
||||||
|
'slug' => $c['person']['slug']
|
||||||
|
]),
|
||||||
|
$helper->picture(getLocalImg($c['person']['image']))
|
||||||
|
);
|
||||||
|
$medias = array_map(fn ($series) => $component->media(
|
||||||
|
array_merge([$series['title']], $series['titles']),
|
||||||
|
$url->generate('anime.details', ['id' => $series['slug']]),
|
||||||
|
$helper->picture(getLocalImg($series['posterImage'], TRUE))
|
||||||
|
), $c['series']);
|
||||||
|
$media = implode('', array_map('mb_trim', $medias));
|
||||||
|
|
||||||
<?php foreach ($vas as $language => $casting): ?>
|
$castings[] = <<<HTML
|
||||||
<input <?= $i === 0 ? 'checked="checked"' : '' ?> type="radio" id="character-va<?= $i ?>"
|
<tr>
|
||||||
name="character-vas"
|
<td>{$person}</td>
|
||||||
/>
|
<td width="75%">
|
||||||
<label for="character-va<?= $i ?>"><?= $language ?></label>
|
<section class="align-left media-wrap-flex">
|
||||||
<section class="content">
|
{$media}
|
||||||
<table class="borderless max-table">
|
</section>
|
||||||
<tr>
|
</td>
|
||||||
<th>Cast Member</th>
|
</tr>
|
||||||
<th>Series</th>
|
HTML;
|
||||||
</tr>
|
endforeach;
|
||||||
<?php foreach ($casting as $c): ?>
|
|
||||||
<tr>
|
$languages = implode('', array_map('mb_trim', $castings));
|
||||||
<td>
|
|
||||||
<article class="character">
|
return <<<HTML
|
||||||
<?php
|
<table class="borderless max-table">
|
||||||
$link = $url->generate('person', ['id' => $c['person']['id'], 'slug' => $c['person']['slug']]);
|
<thead>
|
||||||
?>
|
<tr>
|
||||||
<a href="<?= $link ?>">
|
<th>Cast Member</th>
|
||||||
<?= $helper->picture(getLocalImg($c['person']['image'])) ?>
|
<th>Series</th>
|
||||||
<div class="name">
|
</tr>
|
||||||
<?= $c['person']['name'] ?>
|
</thead>
|
||||||
</div>
|
<tbody>{$languages}</tbody>
|
||||||
</a>
|
</table>
|
||||||
</article>
|
HTML;
|
||||||
</td>
|
}, 'content') ?>
|
||||||
<td width="75%">
|
|
||||||
<section class="align-left media-wrap-flex">
|
|
||||||
<?php foreach ($c['series'] as $series): ?>
|
|
||||||
<article class="media">
|
|
||||||
<?php
|
|
||||||
$link = $url->generate('anime.details', ['id' => $series['slug']]);
|
|
||||||
?>
|
|
||||||
<a href="<?= $link ?>">
|
|
||||||
<?= $helper->picture(getLocalImg($series['posterImage'], TRUE)) ?>
|
|
||||||
</a>
|
|
||||||
<div class="name">
|
|
||||||
<a href="<?= $link ?>">
|
|
||||||
<?= $series['title'] ?>
|
|
||||||
<?php foreach ($series['titles'] as $title): ?>
|
|
||||||
<br />
|
|
||||||
<small><?= $title ?></small>
|
|
||||||
<?php endforeach ?>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</article>
|
|
||||||
<?php endforeach ?>
|
|
||||||
</section>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<?php endforeach ?>
|
|
||||||
</table>
|
|
||||||
</section>
|
|
||||||
<?php $i++ ?>
|
|
||||||
<?php endforeach ?>
|
|
||||||
</div>
|
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
</section>
|
</section>
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body class="<?= $escape->attr($url_type) ?> list">
|
<body class="<?= $escape->attr($url_type) ?> list">
|
||||||
<?php include 'setup-check.php' ?>
|
<?php include 'setup-check.php' ?>
|
||||||
<header>
|
<header tabindex="0">
|
||||||
<?php
|
<?php
|
||||||
include 'main-menu.php';
|
include 'main-menu.php';
|
||||||
if(isset($message) && is_array($message))
|
if(isset($message) && is_array($message))
|
||||||
@ -39,5 +39,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|
||||||
</header>
|
</header>
|
3
console
3
console
@ -9,6 +9,9 @@ use ConsoleKit\Console;
|
|||||||
|
|
||||||
$_SERVER['HTTP_HOST'] = 'localhost';
|
$_SERVER['HTTP_HOST'] = 'localhost';
|
||||||
|
|
||||||
|
define('APP_DIR', __DIR__ . '/app');
|
||||||
|
define('TEMPLATE_DIR', APP_DIR . '/templates');
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Start console script
|
// Start console script
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -94,6 +94,7 @@ a:hover, a:active {
|
|||||||
iframe {
|
iframe {
|
||||||
display: block;
|
display: block;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
border: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
|
31
src/AnimeClient/Component/Character.php
Normal file
31
src/AnimeClient/Component/Character.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* Hummingbird Anime List Client
|
||||||
|
*
|
||||||
|
* An API client for Kitsu to manage anime and manga watch lists
|
||||||
|
*
|
||||||
|
* PHP version 7.4
|
||||||
|
*
|
||||||
|
* @package HummingbirdAnimeClient
|
||||||
|
* @author Timothy J. Warren <tim@timshomepage.net>
|
||||||
|
* @copyright 2015 - 2020 Timothy J. Warren
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
|
* @version 5.1
|
||||||
|
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Aviat\AnimeClient\Component;
|
||||||
|
|
||||||
|
final class Character {
|
||||||
|
use ComponentTrait;
|
||||||
|
|
||||||
|
public function __invoke(string $name, string $link, string $picture, string $className = 'character'): string
|
||||||
|
{
|
||||||
|
return $this->render('character.php', [
|
||||||
|
'name' => $name,
|
||||||
|
'link' => $link,
|
||||||
|
'picture' => $picture,
|
||||||
|
'className' => $className,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
30
src/AnimeClient/Component/ComponentTrait.php
Normal file
30
src/AnimeClient/Component/ComponentTrait.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* Hummingbird Anime List Client
|
||||||
|
*
|
||||||
|
* An API client for Kitsu to manage anime and manga watch lists
|
||||||
|
*
|
||||||
|
* PHP version 7.4
|
||||||
|
*
|
||||||
|
* @package HummingbirdAnimeClient
|
||||||
|
* @author Timothy J. Warren <tim@timshomepage.net>
|
||||||
|
* @copyright 2015 - 2020 Timothy J. Warren
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
|
* @version 5.1
|
||||||
|
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Aviat\AnimeClient\Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shared logic for component-based functionality, like Tabs
|
||||||
|
*/
|
||||||
|
trait ComponentTrait {
|
||||||
|
public function render(string $path, array $data): string
|
||||||
|
{
|
||||||
|
ob_start();
|
||||||
|
extract($data, EXTR_OVERWRITE);
|
||||||
|
include \TEMPLATE_DIR . '/' .$path;
|
||||||
|
return ob_get_clean();
|
||||||
|
}
|
||||||
|
}
|
31
src/AnimeClient/Component/Media.php
Normal file
31
src/AnimeClient/Component/Media.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* Hummingbird Anime List Client
|
||||||
|
*
|
||||||
|
* An API client for Kitsu to manage anime and manga watch lists
|
||||||
|
*
|
||||||
|
* PHP version 7.4
|
||||||
|
*
|
||||||
|
* @package HummingbirdAnimeClient
|
||||||
|
* @author Timothy J. Warren <tim@timshomepage.net>
|
||||||
|
* @copyright 2015 - 2020 Timothy J. Warren
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
|
* @version 5.1
|
||||||
|
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Aviat\AnimeClient\Component;
|
||||||
|
|
||||||
|
final class Media {
|
||||||
|
use ComponentTrait;
|
||||||
|
|
||||||
|
public function __invoke(array $titles, string $link, string $picture, string $className = 'media'): string
|
||||||
|
{
|
||||||
|
return $this->render('media.php', [
|
||||||
|
'titles' => $titles,
|
||||||
|
'link' => $link,
|
||||||
|
'picture' => $picture,
|
||||||
|
'className' => $className,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
45
src/AnimeClient/Component/Tabs.php
Normal file
45
src/AnimeClient/Component/Tabs.php
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?php declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* Hummingbird Anime List Client
|
||||||
|
*
|
||||||
|
* An API client for Kitsu to manage anime and manga watch lists
|
||||||
|
*
|
||||||
|
* PHP version 7.4
|
||||||
|
*
|
||||||
|
* @package HummingbirdAnimeClient
|
||||||
|
* @author Timothy J. Warren <tim@timshomepage.net>
|
||||||
|
* @copyright 2015 - 2020 Timothy J. Warren
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
|
* @version 5.1
|
||||||
|
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Aviat\AnimeClient\Component;
|
||||||
|
|
||||||
|
final class Tabs {
|
||||||
|
use ComponentTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a tabbed content view
|
||||||
|
*
|
||||||
|
* @param string $name the name attribute for the input[type-option] form elements
|
||||||
|
* also used to generate id attributes
|
||||||
|
* @param array $tabData The data used to create the tab content, indexed by the tab label
|
||||||
|
* @param callable $cb The function to generate the tab content
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function __invoke(
|
||||||
|
string $name,
|
||||||
|
array $tabData,
|
||||||
|
callable $cb,
|
||||||
|
string $className = 'content media-wrap flex flex-wrap flex-justify-start'
|
||||||
|
): string
|
||||||
|
{
|
||||||
|
return $this->render('tabs.php', [
|
||||||
|
'name' => $name,
|
||||||
|
'data' => $tabData,
|
||||||
|
'callback' => $cb,
|
||||||
|
'className' => $className,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
45
src/AnimeClient/Component/VerticalTabs.php
Normal file
45
src/AnimeClient/Component/VerticalTabs.php
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?php declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* Hummingbird Anime List Client
|
||||||
|
*
|
||||||
|
* An API client for Kitsu to manage anime and manga watch lists
|
||||||
|
*
|
||||||
|
* PHP version 7.4
|
||||||
|
*
|
||||||
|
* @package HummingbirdAnimeClient
|
||||||
|
* @author Timothy J. Warren <tim@timshomepage.net>
|
||||||
|
* @copyright 2015 - 2020 Timothy J. Warren
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
|
* @version 5.1
|
||||||
|
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Aviat\AnimeClient\Component;
|
||||||
|
|
||||||
|
final class VerticalTabs {
|
||||||
|
use ComponentTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a vertical tab content view
|
||||||
|
*
|
||||||
|
* @param string $name the name attribute for the input[type-option] form elements
|
||||||
|
* also used to generate id attributes
|
||||||
|
* @param array $tabData The data used to create the tab content, indexed by the tab label
|
||||||
|
* @param callable $cb The function to generate the tab content
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function __invoke(
|
||||||
|
string $name,
|
||||||
|
array $tabData,
|
||||||
|
callable $cb,
|
||||||
|
string $className='content media-wrap flex flex-wrap flex-justify-start'
|
||||||
|
): string
|
||||||
|
{
|
||||||
|
return $this->render('vertical-tabs.php', [
|
||||||
|
'name' => $name,
|
||||||
|
'data' => $tabData,
|
||||||
|
'callback' => $cb,
|
||||||
|
'className' => $className,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
@ -39,11 +39,30 @@ final class FormGenerator {
|
|||||||
* @throws ContainerException
|
* @throws ContainerException
|
||||||
* @throws NotFoundException
|
* @throws NotFoundException
|
||||||
*/
|
*/
|
||||||
public function __construct(ContainerInterface $container)
|
private function __construct(ContainerInterface $container)
|
||||||
{
|
{
|
||||||
$this->helper = $container->get('html-helper');
|
$this->helper = $container->get('html-helper');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new FormGenerator
|
||||||
|
*
|
||||||
|
* @param ContainerInterface $container
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public static function new(ContainerInterface $container): self
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return new static($container);
|
||||||
|
}
|
||||||
|
catch (\Throwable $e)
|
||||||
|
{
|
||||||
|
dump($e);
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate the html structure of the form
|
* Generate the html structure of the form
|
||||||
*
|
*
|
||||||
|
@ -35,6 +35,6 @@ final class Form {
|
|||||||
*/
|
*/
|
||||||
public function __invoke(string $name, array $form)
|
public function __invoke(string $name, array $form)
|
||||||
{
|
{
|
||||||
return (new FormGenerator($this->container))->generate($name, $form);
|
return FormGenerator::new($this->container)->generate($name, $form);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,8 +34,7 @@ final class Menu {
|
|||||||
*/
|
*/
|
||||||
public function __invoke($menuName)
|
public function __invoke($menuName)
|
||||||
{
|
{
|
||||||
$generator = new MenuGenerator($this->container);
|
return MenuGenerator::new($this->container)->generate($menuName);
|
||||||
return $generator->generate($menuName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -44,40 +44,20 @@ final class MenuGenerator extends UrlGenerator {
|
|||||||
protected RequestInterface $request;
|
protected RequestInterface $request;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MenuGenerator constructor.
|
|
||||||
*
|
|
||||||
* @param ContainerInterface $container
|
* @param ContainerInterface $container
|
||||||
* @throws ContainerException
|
* @return static
|
||||||
* @throws NotFoundException
|
|
||||||
*/
|
*/
|
||||||
public function __construct(ContainerInterface $container)
|
public static function new(ContainerInterface $container): self
|
||||||
{
|
{
|
||||||
parent::__construct($container);
|
try
|
||||||
$this->helper = $container->get('html-helper');
|
|
||||||
$this->request = $container->get('request');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate the full menu structure from the config files
|
|
||||||
*
|
|
||||||
* @param array $menus
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
protected function parseConfig(array $menus) : array
|
|
||||||
{
|
|
||||||
$parsed = [];
|
|
||||||
|
|
||||||
foreach ($menus as $name => $menu)
|
|
||||||
{
|
{
|
||||||
$parsed[$name] = [];
|
return new static($container);
|
||||||
foreach ($menu['items'] as $pathName => $partialPath)
|
}
|
||||||
{
|
catch (\Throwable $e)
|
||||||
$title = (string)StringType::from($pathName)->humanize()->titleize();
|
{
|
||||||
$parsed[$name][$title] = (string)StringType::from($menu['route_prefix'])->append($partialPath);
|
dump($e);
|
||||||
}
|
die();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $parsed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -120,5 +100,42 @@ final class MenuGenerator extends UrlGenerator {
|
|||||||
// Create the menu html
|
// Create the menu html
|
||||||
return (string) $this->helper->ul();
|
return (string) $this->helper->ul();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MenuGenerator constructor.
|
||||||
|
*
|
||||||
|
* @param ContainerInterface $container
|
||||||
|
* @throws ContainerException
|
||||||
|
* @throws NotFoundException
|
||||||
|
*/
|
||||||
|
private function __construct(ContainerInterface $container)
|
||||||
|
{
|
||||||
|
parent::__construct($container);
|
||||||
|
$this->helper = $container->get('html-helper');
|
||||||
|
$this->request = $container->get('request');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate the full menu structure from the config files
|
||||||
|
*
|
||||||
|
* @param array $menus
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function parseConfig(array $menus) : array
|
||||||
|
{
|
||||||
|
$parsed = [];
|
||||||
|
|
||||||
|
foreach ($menus as $name => $menu)
|
||||||
|
{
|
||||||
|
$parsed[$name] = [];
|
||||||
|
foreach ($menu['items'] as $pathName => $partialPath)
|
||||||
|
{
|
||||||
|
$title = (string)StringType::from($pathName)->humanize()->titleize();
|
||||||
|
$parsed[$name][$title] = (string)StringType::from($menu['route_prefix'])->append($partialPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $parsed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// End of MenuGenerator.php
|
// End of MenuGenerator.php
|
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
namespace Aviat\Ion\View;
|
namespace Aviat\Ion\View;
|
||||||
|
|
||||||
use Aura\Html\HelperLocator;
|
|
||||||
use Aviat\Ion\Di\ContainerAware;
|
use Aviat\Ion\Di\ContainerAware;
|
||||||
use Aviat\Ion\Di\ContainerInterface;
|
use Aviat\Ion\Di\ContainerInterface;
|
||||||
use Aviat\Ion\Di\Exception\ContainerException;
|
use Aviat\Ion\Di\Exception\ContainerException;
|
||||||
@ -30,13 +29,6 @@ use const EXTR_OVERWRITE;
|
|||||||
class HtmlView extends HttpView {
|
class HtmlView extends HttpView {
|
||||||
use ContainerAware;
|
use ContainerAware;
|
||||||
|
|
||||||
/**
|
|
||||||
* HTML generator/escaper helper
|
|
||||||
*
|
|
||||||
* @var HelperLocator
|
|
||||||
*/
|
|
||||||
protected HelperLocator $helper;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Response mime type
|
* Response mime type
|
||||||
*
|
*
|
||||||
@ -56,7 +48,6 @@ class HtmlView extends HttpView {
|
|||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
$this->setContainer($container);
|
$this->setContainer($container);
|
||||||
$this->helper = $container->get('html-helper');
|
|
||||||
$this->response = new HtmlResponse('');
|
$this->response = new HtmlResponse('');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,8 +60,10 @@ class HtmlView extends HttpView {
|
|||||||
*/
|
*/
|
||||||
public function renderTemplate(string $path, array $data): string
|
public function renderTemplate(string $path, array $data): string
|
||||||
{
|
{
|
||||||
$data['helper'] = $this->helper;
|
$helper = $this->container->get('html-helper');
|
||||||
$data['escape'] = $this->helper->escape();
|
$data['component'] = $this->container->get('component-helper');
|
||||||
|
$data['helper'] = $helper;
|
||||||
|
$data['escape'] = $helper->escape();
|
||||||
$data['container'] = $this->container;
|
$data['container'] = $this->container;
|
||||||
|
|
||||||
ob_start();
|
ob_start();
|
||||||
|
Loading…
Reference in New Issue
Block a user