Za formuláře hezčí

Rudolf Svátek 2016-07-20 10:16

Aplikaci, tak jak vypadá po dnešní kapitole, si můžeš tedy stáhnout: kapitola10.zip.

Editace i přidávání stránky fungují. Ale psát html kód jen do textarea není pohodlné. Podobně mít všechna políčka neformátovaná pod sebou není taky žádný vodvaz. Dnes se tedy mrknem na takovou odlehčovací tématiku a upravíme si šablony pro editaci a přidání stránky.

Editace stránek

V administraci si vyber nějakou stránku a jdi do editace. Vidíš, že to není nic moc pěkného. Tak v první řadě přidáme do šablony html editor CKEDITOR. Už jsme si ho stahovali a měl by ležet ve složce www. Přidej tedy do šablony app\AdminModule\presenters\templates\Pages\edit.latte pár řádků javascriptu:

<script src="{$basePath}/ckeditor/ckeditor.js"></script>
<script>
	var editor = CKEDITOR.replace('frm-editForm-text', {
		height: '400px'
	});
	var editor2 = CKEDITOR.replace('frm-editForm-secretText', {
		height: '400px'
	});
</script>

Načti znovu stránku s editací a pokochej se editorem textů :-).

každá stránka také může mít přiřazený ilustrační obrázek. Ten se pak může využít třeba při zobrazení stránky pro uživatele. Zadává se jako cesta k souboru, který jsi nahrál na web. Nahrát obrázek a zapamatovat si jeho cestu ale není úplně snadné. Tak proto jsme si stáhli KCFINDER a ten to zařídí za nás. Zase menší úprava šablony edit.latte - přidej další javascript:

	<script type="text/javascript">

		function openKCFinder(field) {
			window.KCFinder = {
				callBack: function (url) {
					field.value = url;
					window.KCFinder = null;
				}
			};
			window.open({$basePath} +"/kcfinder/browse.php?type=images&dir=images", 'kcfinder_textbox',
					  'status=0, toolbar=0, location=0, menubar=0, directories=0, ' +
					  'resizable=1, scrollbars=0, width=800, height=600'
			);
		}
	</script>

Přenačti si stránku s editací a zkus kliknout do řádku "Připojený obrázek". Vyskočí okno KCFinderu, které ti dovolí nahrát obrázek (pomocí šipky Upload), nebo vybrat z už nahraných normálním poklikáním:

Zkus taky kliknout na obrázek pravým myšítkem. Vyskočí nabídka akcí, ze kterých si můžeš vybrat. Jakmile uděláš dvojklik, do řádku ve formuláři se doplní cesta k obrázku a je to.

Bootstrap

Bootstrap je skvělá knihovna. Co umí s formátováním jen díky přidání nějaké třídy je úžasné. Doporučuji postudovat. Využijeme toho v editačním formuláři. Abychom to ale mohli udělat, potřebujeme mít plnou kontrolu nad vykreslovaným formulářem. Prozatím se celý formulář vykresluje pomocí makra:

{control editForm}

To musíme změnit a vykreslíme formulář ručně. Moje šablona edit.latte tedy vypadá takto:

{block content}
<div class="row">
	<div class="col-lg-12">
		<div class="panel panel-default">
			<div class="panel-heading">
				Editace stránky
			</div>
			<div class="panel-body">
				<ul class="nav nav-tabs" id="myTab">
					<li class="active"><a data-toggle="tab" aria-expanded="true" href="#podrobnosti">Podrobnosti</a></li>
					<li><a data-toggle="tab" href="#seo">SEO</a></li>
					<li><a data-toggle="tab" href="#secret">Text po přihlášení</a></li>
				</ul>
				{form editForm}
					{input id}
					<div class="tab-content">
						<div>&nbsp;</div>
						<div id="podrobnosti" class="tab-pane active">
							<div class="form-group">
								<div class="col-sm-4">
									<div class="col-lg-12 input-group">
										<span class="input-group-addon">
											<a href="javascript:void(0)" title="Název stránky" data-toggle="popover"
											   data-trigger="focus"
											   data-content="Název stránky se použije v titulku stránky, pokud není vyplněn titulek na kartě SEO">
												<i class="fa fa-bars fa-fw"></i>
											</a>
										</span>
										{input name}
									</div>
								</div>
								<div class="col-sm-8">
									<div class="col-lg-12 input-group">
										<span class="input-group-addon">
											<a href="javascript:void(0)" title="Rodič" data-toggle="popover"
											   data-trigger="focus"
											   data-content="Rodič.">
												<i class="glyphicon glyphicon-picture"></i>
											</a>
										</span>
										{input parent}
									</div>
								</div>
							</div>
							<div class="form-group">
								<div class="col-sm-4">
									<div class="col-lg-12 input-group">
										<span class="input-group-addon">
											<a href="javascript:void(0)" title="Název do menu" data-toggle="popover"
											   data-trigger="focus"
											   data-content="Pokud je název do menu prázdný, použije se do menu název stránky">
												<span class="glyphicon glyphicon-menu-hamburger"></span>
											</a>
										</span>
										{input menuTitle}
									</div>
								</div>
								<div class="col-sm-8">
									<div class="col-lg-12 input-group">
										{foreach $form[inMenu]->items as $key => $label}
											<div class="col-sm-3">
												<input n:name="inMenu:$key" data-off-icon-cls="glyphicon-thumbs-down"
													   data-on-icon-cls="glyphicon-thumbs-up"
													   data-group-cls="btn-group-xs">
												<label n:name="inMenu:$key"> {$label}</label>
											</div>
										{/foreach}
									</div>
								</div>
							</div>
							<div class="form-group">
								<div class="col-lg-12">
									<div class="col-lg-12 input-group">
										<span class="input-group-addon">
											<a href="javascript:void(0)" title="Perex stránky" data-toggle="popover"
											   data-trigger="focus"
											   data-content="Perex by měl shrnout to nejdůležitější, co je v textu stránky">
												<i class="glyphicon glyphicon-font"></i>
											</a>
										</span>
										{input perex}
									</div>
								</div>
							</div>
							<div class="form-group">
								<div class="col-lg-12">
									<div class="col-lg-12 input-group margin-bottom-sm">
										<span class="input-group-addon">
											<a href="javascript:void(0)" title="Text stránky" data-toggle="popover"
											   data-trigger="focus"
											   data-content="Text stránky bude tvořit základní obsah zobrazené stránky">
												<i class="glyphicon glyphicon-pencil"></i>
											</a>
										</span>
										{input text}
									</div>
								</div>
							</div>
							<div class="form-group">
								<div class="col-sm-4">
									<div class="col-lg-12 input-group">
										<span class="input-group-addon">
											<a href="javascript:void(0)" title="Obrázek" data-toggle="popover"
											   data-trigger="focus"
											   data-content="Ke stránce může být přidružený obrázek, který se pak zobrazuje v šabloně.">
												<i class="glyphicon glyphicon-picture"></i>
											</a>
										</span>
										{input pictureName}
									</div>
									<div id="pictureContainer">
										<a n:ifset="$picture" data-footer="Obrázek stránky" data-toggle="lightbox"
										   href="{$picture}"
										   title="Obrázek stránky">
											<img src="{$picture}" alt="">
										</a>
									</div>
								</div>
								<div class="col-sm-8">
									<div class="col-lg-12 input-group">
										<span class="input-group-addon">
											<a href="javascript:void(0)" title="Popis obrázku" data-toggle="popover"
											   data-trigger="focus"
											   data-content="Pokud je ke stránce připojený obrázek, objeví se u něj tento popisek.">
												<i class="glyphicon glyphicon-chevron-right"></i>
											</a>
										</span>
										{input pictureDescription}
									</div>
								</div>
							</div>
							<div class="form-group">
								<div class="col-sm-6">
									<div class="col-lg-12 input-group">
										<span class="input-group-addon">
											<a href="javascript:void(0)" title="Galerie" data-toggle="popover"
											   data-trigger="focus"
											   data-content="Ke stránce může být přidružena jedna či více galerií.">
												<i class="glyphicon glyphicon-picture"></i>
											</a>
										</span>
										{input galleryIds}
									</div>
								</div>
								<div class="col-sm-2">
									<input type="checkbox" n:name=active data-off-icon-cls="glyphicon-thumbs-down"
										   data-on-icon-cls="glyphicon-thumbs-up" data-group-cls="btn-group-xs">
									<label n:name=active> Aktivní</label>
								</div>
								<div class="col-sm-2">
									<input type="checkbox" n:name=onHomepage data-off-icon-cls="glyphicon-thumbs-down"
										   data-on-icon-cls="glyphicon-thumbs-up" data-group-cls="btn-group-xs">
									<label n:name=onHomepage> Na úvodní stranu</label>
								</div>
								<div class="col-sm-2">
									<input type="checkbox" n:name=secret data-off-icon-cls="glyphicon-thumbs-down"
										   data-on-icon-cls="glyphicon-thumbs-up" data-group-cls="btn-group-xs">
									<label n:name=secret> Jen pro přihlášené</label>
								</div>
							</div>
							<div class="form-group">
								<div class="col-lg-2"></div>
								<div class="col-lg-9"></div>
							</div>
							<div class="form-group">
								<div class="col-lg-12">
								</div>
							</div>
						</div>

						<div id="seo" class="tab-pane fade">
							<div class="form-group">
								<div class="col-lg-12">
									<div class="col-lg-12 input-group">
										<span class="input-group-addon">
											<a href="javascript:void(0)" title="URL adresa stránky" data-toggle="popover"
											   data-trigger="focus"
											   data-content="Pokud je URL stránky prázdné, doplní se automaticky samo při uložení">
												<i class="fa fa-edge fa-fw"></i>
											</a>
										</span>
										{input url}
									</div>
								</div>
							</div>
							<div class="form-group">
								<div class="col-lg-12">
									<div class="input-group">
										<span class="input-group-addon">
											<a href="javascript:void(0)" title="Titulek prohlížeče" data-toggle="popover"
											   data-trigger="focus"
											   data-content="Titulek se zobrazí na kartě prohlížeče. Pokud není vyplněn, použije se název stránky">
												<i class="fa fa-folder fa-fw"></i>
											</a>
										</span>
										{input title}
									</div>
								</div>
							</div>
							<div class="form-group">
								<div class="col-lg-12">
									<div class="input-group">
										<span class="input-group-addon">
											<a href="javascript:void(0)" title="Popisek stránky" data-toggle="popover"
											   data-trigger="focus"
											   data-content="Popisek by měl obsahovat hlavní námět stránky. Neměl by přesáhnout délku 150 - 160 znaků.">
												<i class="fa fa-comment fa-fw"></i>
											</a>
										</span>
										{input description}
									</div>
								</div>
							</div>
							<div class="form-group">
								<div class="col-lg-12">
									<div class="input-group">
										<span class="input-group-addon">
											<a href="javascript:void(0)" title="Klíčová slova" data-toggle="popover"
											   data-trigger="focus"
											   data-content="Vyhledávače pravděpodobně již nevěnují pozornost klíčovým slovům. Ale jejich uvedení není chyba.">
												<i class="fa fa-hashtag fa-fw"></i>
											</a>
										</span>
										{input keywords}
									</div>
								</div>
							</div>
						</div>

						<div id="secret" class="tab-pane fade">
							<div class="form-group">
								<div class="col-lg-12">
									<div class="col-lg-12 input-group margin-bottom-sm">
										<span class="input-group-addon">
											<a href="javascript:void(0)" title="Text pro přihlášené uživatele"
											   data-toggle="popover"
											   data-trigger="focus"
											   data-content="Text, který se zobrazí pouze přihlášeným uživatelům">
												<i class="glyphicon glyphicon-pencil"></i>
											</a>
										</span>
										{input secretText}
									</div>
								</div>
							</div>
						</div>
						<div class="form-group">
							<div class="col-lg-12">
								{input save} {input saveandstay}
							</div>
						</div>
					</div>
				{/form}
			</div>
		</div>
	</div>
</div>

<script src="{$basePath}/ckeditor/ckeditor.js"></script>
<script>
	var editor = CKEDITOR.replace('frm-editForm-text', {
		height: '400px'
	});
	var editor2 = CKEDITOR.replace('frm-editForm-secretText', {
		height: '400px'
	});

	function openKCFinder(field) {
		window.KCFinder = {
			callBack: function (url) {
				field.value = url;
				window.KCFinder = null;
			}
		};
		window.open({$basePath} + "/kcfinder/browse.php?type=images&dir=images", 'kcfinder_textbox',
			'status=0, toolbar=0, location=0, menubar=0, directories=0, ' +
			'resizable=1, scrollbars=0, width=800, height=600'
			);
	}

	jQuery(function ($) {
		$('#myTab a').click(function (e) {
			e.preventDefault();
			$(this).tab('show');
		});

		$("ul.nav-tabs > li > a").on("shown.bs.tab", function (e) {
			var id = $(e.target).attr("href").substr(1);
			$.cookie('activeTab', id);
		});

		// on load of the page: switch to the currently selected tab
		var hash = $.cookie('activeTab');
		if (location.hash != '')
			$('#myTab a[href="' + location.hash + '"]').tab('show')
		else if (hash != null)
			$('#myTab a[href="#' + hash + '"]').tab('show');
	});
</script>

{/block}

{block title}{_'Editace stránky'} |&nbsp;{/block}

Nevím, jak bych ti to postupně vysvětloval, tak možná bude jednodušší tě zaúkolovat studiem :-). Díky tomu Bootstrapu tam jsou nějaké karty, aby se formulář rozdělil a nebylo vše na jedné stránce. Taky vidíš vedle formulářových polí šedivé tlačítko s nápovědou, místo checkboxů jsem tam dal přepínače apod. Jakkoli si to chceš upravit, můžeš.

Formulář pro přidání stránky bude vypadat podobně. Vlastně se bude lišit jen názvem v titulku, názvem komponenty formuláře a tím, že nebudeme mít pole Id. Naopak pole Parent bude skryté. Nechám tě trochu potrápit s pokusy o úpravu šablony, ale jako vždy si aplikaci můžeš stáhnout.

Ještě mě napadlo, když už jsme u těch šblon, že upravíme hlavní šablonu @layout.latte. Doplníme odkaz do hlavního menu, který povede na výpis stránek:

<ul class="nav navbar-nav">
	<li><a n:href="Users:default"><i class="fa fa-users"></i> Uživatelé</a></li>
	<li><a n:href="Pages:default"><i class="fa fa-file-o"></i> Stránky</a></li>
	<li><span id="ajax-spinner" class="hide">&nbsp;</span></li>
</ul>

To je dnes vše. Aplikaci k dnešnímu dni si můžeš tedy stáhnout: kapitola10.zip.

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

Administrace textových stránek

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

Novinky

Komentáře (2)

  • Rudolf Svátek 2017-03-28 15:13:09
    Jsem pořád učeň :-). Mimochodem - teď už mi stránky běží na novější verzi RS::RS a tam už je zase spousta věcí jinak - líp jsem pochopil Nette, cache a tak. Ale učím se stále. Díky za tipy
  • Jan Galek 2017-03-07 16:25:15
    Abych nemusel vypisovat tolik kódu do šablony, může si vytvořit třídu, která bude dědět od Nette\Application\UI\Form a přepíši ji funkci render, popřípadě i jiné zdali potřebuji, pak už stačí u vytváření komponenty s formulářem použít ten náš formulář ;). a tím nám vypadne starost a ruční vykreslení, navíc ji mohu použít i jinde ;)
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