ako pridam do url jazyk cs a en?
- Tomas8698
- Člen | 109
Zdravim chcem sa opytat, na mojej stranje mam podstranku https://localhost:8082/…g-mailserver a chcel by som pridat cs alebo en podla toho aky je jazyk takto: https://localhost:8082/…g-mailserver
Moj common.neon vyzera takto:
<?php
final class RouterFactory
{
use Nette\StaticClass;
public static function createRouter(): RouteList
{
$router = new RouteList;
//$router->addRoute('', "Homepage:default");
$router->addRoute('[<locale=cs cs|en>/]<presenter>', "Homepage:default");
$router->addRoute('sitemap.xml', 'Homepage:sitemap');
$router->addRoute('/<action>/<urlseo>', 'Homepage:package');
return $router;
}
}
?>
Som zaciatocnik a neviem vlastne od coho sa odrazit a ako postupovat.
Za pomoc velmi pekne dakujem.
- dakur
- Člen | 493
@Tomas8698 Pokud to chceš pro ten Homepage:package
, tak
přidáš do routy parametr locale
:
<?php
final class RouterFactory
{
use Nette\StaticClass;
public static function createRouter(): RouteList
{
$router = new RouteList;
//$router->addRoute('', "Homepage:default");
$router->addRoute('[<locale=cs cs|en>/]<presenter>', "Homepage:default");
$router->addRoute('sitemap.xml', 'Homepage:sitemap');
$router->addRoute('/<locale=cs cs|en>/<action>/<urlseo>', 'Homepage:package');
return $router;
}
}
?>
V presenteru ho potom budeš mít v proměnné $locale
:
class HomepagePresenter
{
public function actionPackage($locale, $action, $urlseo)
{
// ...
}
}
A je možné, že tvoje URL pasuje i k routě
$router->addRoute('[<locale=cs cs|en>/]<presenter>', "Homepage:default")
,
takže to pak spustí Homepage:default
místo
Homepage:package
. To zjistíš v Tracy baru – je tam tabulka
všech rout a taky znázorněné, která pasuje k aktuální requestu a které
by ještě mohly, pokud by dostaly šanci (tj. byly by výš). Je to
srozumitelné?
- Tomas8698
- Člen | 109
dakur napsal(a):
@Tomas8698 Pokud to chceš pro ten
Homepage:package
, tak přidáš do routy parametrlocale
:<?php final class RouterFactory { use Nette\StaticClass; public static function createRouter(): RouteList { $router = new RouteList; //$router->addRoute('', "Homepage:default"); $router->addRoute('[<locale=cs cs|en>/]<presenter>', "Homepage:default"); $router->addRoute('sitemap.xml', 'Homepage:sitemap'); $router->addRoute('/<locale=cs cs|en>/<action>/<urlseo>', 'Homepage:package'); return $router; } } ?>
V presenteru ho potom budeš mít v proměnné
$locale
:class HomepagePresenter { public function actionPackage($locale, $action, $urlseo) { // ... } }
A je možné, že tvoje URL pasuje i k routě
$router->addRoute('[<locale=cs cs|en>/]<presenter>', "Homepage:default")
, takže to pak spustíHomepage:default
místoHomepage:package
. To zjistíš v Tracy baru – je tam tabulka všech rout a taky znázorněné, která pasuje k aktuální requestu a které by ještě mohly, pokud by dostaly šanci (tj. byly by výš). Je to srozumitelné?
Ano to je pre „Homepage:package“, to je vlastne pdostranka produktov ktore vytahujem z databazy a na zaklade jazyka ktore evidujem v databaze pod stlpcom locale si ich vytahujem na hlavnu stranku „homepage:default“ a tam mi zobrazi podla jazyka prelozene a cz balicky a po kliknuti na podrobnosti ma presmeruje na podstranku. Mam otazku to je potrebne ak mam funkciu renderPackage() menit nazov na actionPackage() ako si mi pisala alebo mozem nechat svoj? Vlastne ono ked tam mam locale ako si mi pisal tak ked tam zadam manualne do url jazyk tak mi to bezi ale samo mi ho tam nezobrazuje. Treba nieco este doplnit, neviem sa pohnut s tymto. Za pomoc dakujem
posielam aj z homepage presenter ako to mam :
<?php
public function renderPackage(string $urlseo): void
{
//$this->template->formTitle=$urlseo;
$package=$this->database->table('packages')->where('urlseo', $urlseo)->fetch();
// TODO pokud nenajde vyhod error
//var_dump( $this->template->package);
if (!$package) {
$this->error('Stránka nebyla nalezena');
}
$packages = $this->database->table('packages')->fetchAll();
$this->template->package = $package;
$this->predmet = $package['subject'];
$this->template->formTitle = $package['formtitle'];
}
public function renderSitemap(): void
{
$packages = $this->database->table('packages')->fetchAll();
//pouziji jako hlavni sablonu prazdnou sablonu
$this->setLayout('empty');
// zajisti genrovani ablolutnich URL
$this->absoluteUrls = true;
$this->template->packages = $packages;
$this->getHttpResponse()->setContentType('application/xml');
}
?>
a tu je este renderdefault() ktory pouzivam na hlavnej stranke :
<?php
public function renderDefault(): void
{
$lang = ['cs', 'en']; // languages in application
$httpRequest = $this->getHttpRequest();
$locale = $httpRequest->detectLanguage($lang);
if (is_null($locale)) {
$lang = "cs";
}
$packages=$this->database->table('packages')->where('locale', $lang)->fetchAll();
$this->template->packages=$packages;
}
?>
- dakur
- Člen | 493
@Tomas8698 Zatím jsem pochopil, že máš databázi packages, které
jsou pro zjednodušení buď pro české uživatele nebo zahraniční (cs nebo
en). Potom máš hlavní stránku, kde chceš vypisovat packages v závislosti
na tom, jaký jazyk má uživatel nastavený v prohlížeči. A teď – co
je tedy problém? Potřebuješ, aby odkaz toho package vedl na adresu
/cs|en/package/urlseo
podle toho, jaký locale má ten vypsaný
package? Nebo něco jiného?
K tvé otázce, zda potřebuješ actionPackage()
, když máš
renderPackage()
– jsou to doplňky. Obě metody se volají
v rámci view, jehož jméno nesou (tedy v tvém případě
package
), ale action
se volá dřív a používá se
pro vytahování dat z databáze a logiku (přesměrování etc.), kdežto
render
se volá později a používá se k naplnění šablony
daty. V jednodušších presenterech je možné vytahování dat udělat až v
render
, aby si člověk ušetřil psaní kódu, to už záleží na
osobních preferencích. Např. redirect bych ale zachoval určitě v
action
. Viz taky obrázek zde: https://doc.nette.org/…n/presenters#…
a vysvětlení action zde: https://doc.nette.org/…n/presenters#…
Editoval dakur (26. 1. 2021 9:39)
- dakur
- Člen | 493
@Tomas8698 napsal:
Dakujem Velmi pekne za rychlu odpoved
A ano vlastne podla toho aky jazyk je nastaveny generuje napr ang balicky alebo ceske. A ked klikne uzivatel na podrobnosti(cz) alebo details(en) tak ho hodi na cz alebo en podstranku. Lebo teraz mi to aj ked som na en hodi na podstranku package kde mi nastavi default cz jazyk. A tak isto aj urlseo je cz verzia a en vezia a aby aj nazov bol podla localu z hlavnej stranky na ktorej klikol na ten link details alebo podrobnosti. Mozem poslat screen ked budem doma.
A precital som si dokumentaciu, ktoru ste mi poslali a podla toho si mozem do actionPackage() vlozit kod kde si vytahujem locale z databazy a urlseo?
A este redirect:
Takto ste to myslel?$this->redirect(„:Presenter:HomePage“);
A v renderPackage ponechat udaje, kvoli tomu ze to vytahuje (urlseo) na stranku?(ked som to pochopil spravne)
Tu posielam package.latte:
{block title}{$package['titlelong']}{/block}
{block keywords}{$package['keywords']}{/block}
{block description}{$package['description']}{/block}
{block content}
<div id="homex">
<div class="container">
<div class="row">
<div class="col-md-12 col-sm-12">
<h1>
{$package['titlelong']|noescape}
</h1>
</div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-md-12 col-sm-12">
{$package['textlong']|noescape}
</div>
</div>
</div>
<div class="container">
{if $package['price']!=null}
<div class="row">
<div class="col-md-12 col-sm-12">
<p><strong>Cena</strong> balíčku <strong>{$package['titlelong']}</strong> je {$package['price']} Kč</p>
</div>
</div>
{/if}
</div>
<div class="container">
<div class="row">
<div class="col-md-12 col-sm-12">
<p>{$package['callaction']}</p>
</div>
</div>
</div>
{include "contactFormAll.latte"}
{/block}
- dakur
- Člen | 493
@Tomas8698 Jde o to uvědomit si, čeho se snažíte dosáhnout. Jste na homepage, tam máte něaký locale a teď se ptáte, jak ten locale aplikovat i v jiném view – neboli jak ho předat.
Jak se dostanete do toho druhého view – package
? Odkazem,
který jste pravděpodobně vygeneroval nějak takto:
<a href="{link Homepage:package, urlseo => $urlseo}">podrobnosti o balíčku</a>
No a jak do něj předat locale? No jako cokoliv jiného, jako parametr v URL:
<a href="{link Homepage:package, locale => $locale, urlseo => $urlseo}">podrobnosti o balíčku</a>
$locale
si samozřejmě musíte v Homepage:default
předat do šablony.
Homepage:package
pak musí mít mechanismus, jak ten locale
vyzobnout z adresy – to už jsme udělali předtím:
// router:
$router->addRoute('/<locale=cs cs|en>/<action>/<urlseo>', 'Homepage:package'); // tady říkáme, že URL obsahuje locale parametr
// presenter:
public function renderPackage(string $locale, ...) // tady říkáme, že parametr locale z URL dostaneme v proměnné $locale
{
$db->getPackages()->where(['locale' => $locale]); // a tady už taháme dat podle locale, které jsme původně detekovali v Homepage:default
}
Celé flow tedy je:
- Homepage:default:
- detekuj jazyk z HTTP requestu
- předej ho do šablony
- v šabloně ho použij jako parametr v odkazu na Homepage:package
- Homepage:package
- získej locale z URL skrz parametr metody action/renderPackage()
- vytáhni z DB co potřebuješ podle daného locale
Editoval dakur (26. 1. 2021 13:04)
- Tomas8698
- Člen | 109
Dakujem @dakur
Chcem sa opytat, ze ci na to idem dobre ked chcem pridat do sablony premenu
$locale takto: {var $locale}, vlastne zeby som to pridal do layout.latte? ci je
to spravne?
Tam kde sa dostavam do druheho view do „package“ som zmenil tak ako ste
pisal.
Jazyk deteckujem z http requestu v renderDefault() takto:
<?php
public function renderDefault(): void
{
$lang = ['cs', 'en']; // languages in application
$httpRequest = $this->getHttpRequest();
$langs = $httpRequest->detectLanguage($lang);
if (is_null($langs)) {
$lang = "cs";
}
$packages=$this->database->table('packages')->where('locale',$langs)->fetchAll();
$this->template->packages=$packages;
}
?>
V renderPackage() si vytahujem z db cez ->where(‚urlseo‘, $urlseo),
da sa nejak vyuzit ze to tam mam a pridat ku tomu
->where(‚locale‘, $locale)?
Tu posielam renderPackage()
<?php
public function renderPackage(string $urlseo, $locale): void
{
//$this->template->formTitle=$urlseo;
$package=$this->database->table('packages')->where('urlseo', $urlseo)->fetch();
$db->getPackages()->where(['locale' => $locale]);
// TODO pokud nenajde vyhod error
//var_dump( $this->template->package);
if (!$package) {
$this->error('Stránka nebyla nalezena');
}
$packages = $this->database->table('packages')->fetchAll();
$this->template->package = $package;
$this->predmet = $package['subject'];
$this->template->formTitle = $package['formtitle'];
}
?>
A trsoku som teraz zmeteny pouzit aj actionPackage() alebo len renderPackage(). Tam action by sa mal starat o vytahovanie jazyka a urlseo alebo to nechame uz len na renderPackage?
Posielam aj router:
<?php
public static function createRouter(): RouteList
{
$router = new RouteList;
//$router->addRoute('', "Homepage:default");
$router->addRoute('[<locale=cs cs|en>/]<presenter>', "Homepage:default");
$router->addRoute('sitemap.xml', 'Homepage:sitemap');
$router->addRoute('/<locale=cs cs|en>/<action>/<urlseo>', 'Homepage:package');
return $router;
}
?>
Editoval Tomas8698 (26. 1. 2021 18:44)
- dakur
- Člen | 493
@Tomas8698
Ad předání) V presenteru máte proměnnou $langs
.
Potřebujete ji použít v šabloně. Jak to uděláte?
Ad DB) Podle docs se
zdá, že by mělo jít použít
->where('urlseo', $urlseo)->where('locale', $locale)
– dva
where()
zřetězené za sebou by měly fungovat jako
AND
.
Ad actionPackage()) To teď nechte být, není to podstatné.
- Tomas8698
- Člen | 109
Super, funguje to vyborne. Dakujem velmi pekne @dakur
Posielam aj kod ak by niekto mal rovnaky problem.
RenderDefault()
<?php
public function renderDefault(): void
{
$langs = ['cs', 'en']; // languages in application
$httpRequest = $this->getHttpRequest();
$locale = $httpRequest->detectLanguage($langs);
if (is_null($locale)) {
$lang = "cs";
}
$this->template->lang=$locale;
$packages=$this->database->table('packages')->where(['locale'=> $locale])->fetchAll();
$this->template->packages=$packages;
}
?>
RenderPackage()
<?php
public function renderPackage(string $urlseo, $locale): void
{
//$this->template->formTitle=$urlseo;
$package=$this->database->table('packages')->where(['urlseo'=> $urlseo])->where(['locale' => $locale])->fetch();
.....
?>
Premena $locale ktoru sme si poslali cez odkaz na homepage:package
<?php
<a n:href="Homepage:package, $pakage['urlseo'] ,$pakage['locale']" class="btn btn-warning">
{_pricing.btn-princing}</a>
</div>
?>
a Router
<?php
public static function createRouter(): RouteList
{
$router = new RouteList;
//$router->addRoute('', "Homepage:default");
$router->addRoute('[<locale=cs cs|en>/]<presenter>', "Homepage:default");
$router->addRoute('sitemap.xml', 'Homepage:sitemap');
$router->addRoute('/<locale=cs cs|en>/<action>/<urlseo>', 'Homepage:package');
return $router;
}
?>
Editoval Tomas8698 (27. 1. 2021 20:12)
- Tomas8698
- Člen | 109
Hop to hned upravim pardon. Vlastne mam problem este s tym ze mi tie balicky na hlavnej stranke homepage:default vytahuje len ang aj ked som na cz stranke. Mozem poslat aj foto ak by bolo potrebne a skusal som to este opravit, len neviem ako na to. Ked zadam napriamo do premenej $packages=…->where(‚locale‘,„cs“)->fetchall() takto:
<?php
$packages=$this->database->table('packages')->where('locale',"cs")->fetchAll();
?>
tak mi vytiahne ceske ze vlastne s databazou spolupracuje len ked tam dam premenu $locale ktora detekuje jazyk cez http request tak mi da ang texty. Cele poobedie som za tym a neviem kde mi mohla byt chyba.
Editoval Tomas8698 (27. 1. 2021 20:07)
- dakur
- Člen | 493
@Tomas8698 Když se podíváte na ten screen, který jste mi posílal
v mailu 26.1. ve 12:04, tak uvidíte, že v databázi máte locales v plném
formátu, tj. cs_CZ
a en_US
. Tady je hodnota
$locale
v krátkém tvaru, tj. cs
. Proto to nemůže
nikdy najít.
Jinak pokud nevíte, co se skriptem je, zkuste projít kód od shora dolů a
ke každému řádku si do komentáře zapsat, co očekáváte, že v tom bude.
Pokud při tom nenajdete žádnou chybu, tak si zkuste pomocí funkce
dump()
vypsat skutečné hodnoty, které tam jsou (nebo použijte
debugger, pokud s ním umíte).
Potom tam vidím ještě slepou větev:
if (is_null($locale)) {
$lang = "cs";
}
Proměnnou $lang
po tom ale nikdy nepoužijete. To vám hlásí
i PhpStorm zašedlou barvou textu.
Já vím, že je to v začátcích těžké, ale zkuste v tom kódu míň náhodně skákat a víc se soustředit na postupné řešení problému – nejdřív udělám, ale hlavní stránka dělala, co má, potom budu řešit package stránku. Nebo naopak, to je jedno, hlavně ne všechno naráz. 🙂
- Tomas8698
- Člen | 109
Zdravim problem som nakoniec vyriesil
Takto vyzera vysledne a spravne homepagePresenter
<?php
final class HomepagePresenter extends Nette\Application\UI\Presenter
{
/** @var Nette\Localization\ITranslator @inject */
public $translator;
public $langs = ['cs', 'en'];
private $predmet = "";
public function renderIndex(): void
{
$httpRequest = $this->getHttpRequest();
$locale = $httpRequest->detectLanguage($this->langs);
// bdump($locale);
if (is_null($locale)) {
$locale = "cs";
}
$this->redirect('Homepage:default', $locale);
}
public function renderDefault($locale): void
{
$this->template->lang=$locale;
$packages=$this->database->table('packages')->where(['locale'=> $locale])->fetchAll();
$this->template->packages=$packages;
}
/** @var Nette\Database\Context */
private $database;
public function __construct(Nette\Database\Context $database) {
$this->database = $database;
}
public function renderPackage(string $urlseo, $locale): void
{
$package = $this->database->table('packages')->where(['urlseo' => $urlseo])->where(['locale' => $locale])->fetch();
if (!$package) {
$this->error('Stránka nebyla nalezena');
}
$this->template->package = $package;
$this->predmet = $package['subject'];
$this->template->formTitle = $package['formtitle'];
}
public function renderSitemap(): void
{
$packages = $this->database->table('packages')->fetchAll();
//pouziji jako hlavnu sablonu prazdnu sablonu
$this->setLayout('empty');
// zajistujem genrovanie ablolutnich URL
$this->absoluteUrls = true;
$this->template->packages = $packages;
$this->template->langs=$this->langs;
$this->getHttpResponse()->setContentType('application/xml');
}
?>
A upravil som aj router
<?php
public static function createRouter(): RouteList
{
$router = new RouteList;
$router->addRoute('', "Homepage:index");
$router->addRoute('[<locale= cs|en>]', "Homepage:default");
$router->addRoute('sitemap.xml', 'Homepage:sitemap');
$router->addRoute('/<locale= cs|en>/<urlseo>', 'Homepage:package');
return $router;
}
?>
Dakujem velmi pekne za pomoc @dakur a aj ostatnym velmi si mi pomohli dokoncit stranku a zaroven naucit sa nieco nove. Dakujem