ako pridam do url jazyk cs a en?

Tomas8698
Člen | 109
+
0
-

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
+
0
-

@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
+
0
-

dakur napsal(a):

@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é?

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
+
0
-

@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
+
0
-

@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
+
0
-

@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
+
0
-

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
+
0
-

@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
+
0
-

Dakujem @dakur

Pridat do sablony mozem aj takto?

<?php
$this->template->lang = $this->lang;
?>

A s databazou tiez vyskusam ked budem doma. Potom napisem ze ako.

Zatial velmi pekne dakujem.

dakur
Člen | 493
+
0
-

@Tomas8698 Ano. 👍 Ale proč $this->lang? V renderDefault() přece nemáte jazyk uložený v $this->lang.

Editoval dakur (27. 1. 2021 9:25)

Tomas8698
Člen | 109
+
0
-

Hop, cize tam dam $langs, lebo toto si tam odchytavame

Tomas8698
Člen | 109
+
0
-

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)

ali
Člen | 342
+
0
-

Tohle asi nebude fungovat spravne

}elseif($locale="en"){
    $lang="en";
Tomas8698
Člen | 109
+
0
-

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
+
+1
-

@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
+
0
-

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

dakur
Člen | 493
+
0
-

Paráda, pěkné! 👍 🙂