Zobrazení fotogalerie

Rudolf Svátek 2016-07-29 08:08

Pokud si chceš stáhnout aplikaci po dnešní kapitole, můžeš: kapitola22.zip.

Jestli si vzpomínáš, tak v administraci jsme už fotogalerie dělali. Textové stránky také mají možnost při editaci vybrat jednu či více galerií a přiřadit je ke stránce. No tak teď už jen uživatelům zobrazíme galerii v detailu stránky. Je asi zbytečné dělat nový presentar, který by zobrazoval galerie a jejich obrázky. Svěříme to PagePresenteru. U zobrazené stránky se prostě zobrazí i galerie, pokud nějaké stránka má. A co bys asi tak řekl? No bude to zase pomocí komponenty :-)

Komponenta Fotogalerie

Komponena opět nedělá nic složitého. V konstruktoru získá závislosti, v metodě render() najde galerie k zobrazené stránce a v určené šabloně je zobrazí.

<?php

namespace App\FrontModule\Controls;

use App\Model\GalleriesRepository;
use App\Model\PagesEntity;
use Nette\Application\UI;

class GalleriesControl extends UI\Control
{

	/** @var GalleriesRepository */
	private $galleriesRepository;

	/** @var PagesEntity */
	private $page;

	/**
	 * @param PagesRepository $galleriesRepository
	 */
	public function __construct(GalleriesRepository $galleriesRepository) {
		parent::__construct();
		$this->galleriesRepository = $galleriesRepository;
	}

	/**
	 * @param $page
	 */
	public function setPage(PagesEntity $page) {
		$this->page = $page;
	}

	public function render() {
		$this->getTemplate()->galleries = $this->galleriesRepository->getAllGalleriesWithPicturesForPage($this->page);
		$this->getTemplate()->setFile(__DIR__ . '/GalleriesControl.latte');
		$this->getTemplate()->render();
	}

}

Komponenta se musí nějak dozvědět jaká stránka je zobrazena, aby našla galerie jen pro ni. Proto je tam ta funkce setPage. Šablona komponenty prochází pole galerií a pro gaždou z nich ještě pole jejích obrázků a vypisuje je. Já se ještě rozhodl, že využiji bootstrap a lightbox, takže moje šablona vypadá takto:

<div class="galleries row">
	<h2>Fotogalerie</h2>
	{foreach $galleries as $gallery}
		<div class="col-lg-12">
			<h3 class="page-header">{$gallery['gallery']['name']}</h3>
		</div>
		<div n:if="$gallery['pictures']" n:foreach="$gallery['pictures'] as $picture" class="col-lg-3 col-md-4 col-xs-6 thumb">
			<a href="{$picture->file}" data-toggle="lightbox" data-gallery="{$gallery['gallery']['name']}">
				<img alt="{$picture->description}" src="{$picture->file}" class="thumbnail img-responsive">
			</a>
		</div>
	{/foreach}
</div>

Úprava Mapperu a Repository

Možná vidíš, že komponenta volá metodu getAllGalleriesWithPicturesForPage($this->page), která v repositáři zatím není. Takže v app\model\Galleries\GalleriesRepository.php takovou metodu vytvoříme:

	/**
	 * @param PagesEntity $page
	 */
	public function getAllGalleriesWithPicturesForPage(PagesEntity $page) {
		$galleries = [];
		$rows = $this->mapper->getAllGalleriesWithPicturesForPage($page);
		if($rows)
			foreach($rows as $row) {
				$galleries[$row['gallery_id']]['gallery'] = ['name' => $row['galleryName'], 'description' => $row['galleryDescription']];
				$galleries[$row['gallery_id']]['pictures'][] = $row;
			}
		return $galleries;
	}

Metoda zavolá mapper a chce po něm všechny galerie s jejich obrázky. Jelikož výsledek přijde jako sada řádků, tak ho ještě zpracuje do vícerozměrného pole. V mapperu samozřejmě také musíme metodu doplnit:

	/**
	 * @param PagesEntity $page
	 */
	public function getAllGalleriesWithPicturesForPage(PagesEntity $page) {
		return $this->db->select('g.name AS galleryName, g.description AS galleryDescription, p.*')
						->from($this->tableName)->as('g')
						->innerJoin('pictures')->as('p')->on('p.gallery_id = g.id')
						->where('g.id IN %in', json_decode($page->galleryIds()))
						->orderBy('g.id');
	}

Úprava PagePresenteru

V PagePresenteru musíme dodat závislosti na službě fotogalerie a budeme vytvářet tu komponentu.Uprav tedy začátek presenteru takto:

<?php

namespace App\FrontModule\Presenters;

use App\FrontModule\Controls\CommentsControl;
use App\FrontModule\Controls\GalleriesControl;
use App\Model\CommentsRepository;
use App\Model\GalleriesRepository;

class PagesPresenter extends BasePresenter
{

	/** @var GalleriesRepository @inject */
	public $galleriesRepository;

A pak už stačí jen přidat metodu, která vytvoří tu komponentu:

	/**
	 * @return GalleriesControl
	 */
	public function createComponentGalleries() {
		$control = new GalleriesControl($this->galleriesRepository);
		$control->setPage($this->page);
		return $control;
	}

Vidíš, že se po vytvoření objektu volá jeho metoda setPage(), aby komponenta věděla o jakou stránku jde.

Zbývá teda už jediná věc a to je úprava šablony pro zobrazení stránky. Stačí někam na vhodné místo (třeba pod zobrazený text) vložit příkaz pro vykreslení komponenty:

{control galleries}

A tohle doopravdy stačí. Předpokládám, že nějakou textovou stránku už máš. Možná máš i galerii s obrázky. Pokud ne, vytvoř ji a nějaké obrázky do ní dej. Pak textové stránce tuto galerii přiděl. Pokud máš galerií více, klidně jich stránce přiděl víc, nebo i všechny. Jakmile stránku zobrazíš jako uživatel, měl bys pod jejím textem vidět výpis obrázků. Po kliknutí by se měly zobrazit v lightboxu a v rámci každé galerie mezi nimi listovat.

Dnes to bylo krátké, ale snad zábavné. Příště si předvedeme jak se dá využít toho, že máme v administraci možnost nastavení.

Pokud si chceš stáhnout aplikaci po dnešní kapitole, můžeš: kapitola22.zip.

Redakční systém RS::RS Předchozí kapitola

Vyhledávání na webu

Redakční systém RS::RS Celý seriál

Vývoj redakčního systému v PHP

Redakční systém RS::RS Následující kapitola

Využití modulu Settings

Komentáře (0)

Přidej svůj komentář

O mně

Jmenuji se Rudolf Svátek. Jsem lektor výpočetní techniky a PHP programátor. Stavím firemní stránky a eshopy. Aby se mi to dělalo pohodlně, vytvořil jsem redakční systém RS::RS, který ti tu nabízím k použití.

Rychlý kontakt na mně

  • Rudolf Svátek
  • Telefon:
    +420 777 828 353
  • Email:
  • Adresa:
    Josefa Hory 1097/5
    736 01 Havířov
    ČR



Tyto stránky používají Cookies. Používáním stránek s tím souhlasíte Další informace