ipub\mobile-detect není deviceView, routa na přesměrování, $this->mobileDetect nejde volat metody

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
James07
Člen | 41
+
0
-

Snažím se detekovat mobilní zařízení a připravil jsem si pro ně odlišný layout.

Mám ale problém s rozjetím addonu ipub\mobile-detect, především:
Zde je link na dokumentaci a zdrojáky, podle kterého postupuji

  1. po přidání do vlastních presenterů mi to vypisuje chybu že nezná proměnnou deviceView, která se přidává do basePresenteru v metodě createTemplate:
<?php
 $template->_deviceView      = $this->deviceView; // není deklarovaná v presenteru
// nevím jak bych ji měl inicializovat
?>
  1. v konfiguraci addonu v config.neon je část pro přesměrování (host: http://…) Rád bych si udělal url ve tvaru http://m.host/…nter/akce/id,…, napsání ale takto nestačí a evidentně je asi nutné vytvořit routu pro tento styl url, mohl by někdo poradit jak na to? Ideálně aby mi spolupracovala s mými nadefinovanými routami, ukázka jedné z mnoha:
<?php
// bootstrap.php
$container->router[] = new Route('rezervace/[<id>]', array(
	'presenter' => 'Bookings',
	'action' => 'default'
));
?>
  1. Proč nedát
<?php
  /**
     * @var \IPub\MobileDetect\MobileDetect
     */
    protected $mobileDetect

?>

přímo do BasePresenteru?(jako public)

  1. Když jsem dal php snippet kódu výše do jakéhokoli presenteru a zavolal v jeho metodě nějakou metodu na $this->mobileDetect, vždy mi vyhodil chybu Call to a member function getBrowsers() on a non-object search►, např:
<?php
class TestPresenter extends BasePresenter
	/** * @var \IPub\MobileDetect\MobileDetect */
    protected $mobileDetect;
	public function actionDefault() {
		// chyba
		$browsers = $this->mobileDetect->getBrowsers();
	}
}
?>
  1. A na konec tento latte kód vyhazuje chybu že makro {layout} nesmí být uvnitř jiného makra.
<?php
{isMobileView}
    {layout '../Path/To/Your/Mobile/Device/@layout.latte'}
{/isMobileView}
?>

Latte\CompileException {layout} must be placed outside any macro in …/Products/default.latte:1 search►

Jiří Nápravník
Člen | 710
+
0
-

ad 1 a mas tam tu Traitu? use IPub\MobileDetect\TMobileDetect; ta ti tu promennou prave inicializuje

3. klidne si ji dej do basepresenteru, to nicemu nevadi. Jako public je zbytecna, staci protected

4. no a mas ji nastavenou? Pokud mas jen:

/** * @var \IPub\MobileDetect\MobileDetect */
    protected $mobileDetect;

tak to je jen definovana promenna, musis ji tam nejak injectnout – bude pres @inject (pozor musi byt public), nebo pres inject metody, ci konstruktor

James07
Člen | 41
+
0
-
  1. Omylem jsem smazal to use …, nyní už to tam mám a vyhazuje mi to stále chybu Cannot read an undeclared property App\Presenters\ProductsPresenter::$deviceView

A kam všude musím napsat to use IPub\...., když jsem protected $mobileDetect dal do BasePresenteru?

  1. protected $mobileDetect jsem dal do BasePresenteru
  2. Nemám ji injectnutou, a nejsem si jistý, jak přesně to udělat. Díval jsem se do dokumentace , ale ani nevím, jestli to je to to, co potřebuji a o @inject tam nepadlo ani slovo.
Jiří Nápravník
Člen | 710
+
+1
-

1. kam to use davas? k namespacum nahore? to je spatne, tohle je traita, mrkni jak se s ni pracuje.

proste udelej:

class BasePresenter extends Nette\Application\UI\Presenter
{

    use IPub\MobileDetect\TMobileDetect;

}

a z toho ded vsechny presentery

3. ten $mobileDetect tam nedavej, diky tomu use, ho tam mas
4. staci kliknout o kapitolu vedle a tam inject mas: https://doc.nette.org/…dependencies

James07
Člen | 41
+
0
-

Ty traity se mi začínají líbit. Podíval jsem se na zdroják toho TMobileDetect a už tomu asi rozumím, jak to má fungovat. Předtím jsem to dal právě k namespacům a proto to nefungovalo. Už bych skoro jásal, ale po vložení use jako traity mi to tu traitu nechce nalézt a vyhazuje chybovou hlášku Trait 'App\Presenters\IPub\MobileDetect\TMobileDetect' not found. Toto je můj relevantní obsah BasePresenteru:

<?php

namespace App\Presenters;
use Nette,
	App\Model;
abstract class BasePresenter extends Nette\Application\UI\Presenter {
	use IPub\MobileDetect\TMobileDetect;

	protected function createTemplate($class = NULL) {
        // Init template
        $template = parent::createTemplate($class);

        // Add mobile detect and its helper to template
        $template->_mobileDetect    = $this->mobileDetect;
        $template->_deviceView      = $this->deviceView;

        return $template;
    }
}
?>

a v config.neonu:

<?php
extensions:
	mobileDetect: IPub\MobileDetect\DI\MobileDetectExtension
?>

Editoval James07 (11. 4. 2015 21:39)

Mysteria
Člen | 797
+
+1
-

Heh, tou samou chybou (dávání trait za namespace a ne do třídy) jsem si taky prošel a málem jsem z toho zešílel, proč to nejde.

Každopádně k tvé chybě, chybí ti tam lomeno:

abstract class BasePresenter extends Nette\Application\UI\Presenter {
    use \IPub\MobileDetect\TMobileDetect;
}
James07
Člen | 41
+
0
-

Ještě 2. bod dotazu:

  1. V konfiguraci addonu v config.neon je část pro přesměrování (host: http://…) Rád bych si udělal url ve tvaru http://m.host/…nter/akce/id,…, napsání ale takto nestačí a evidentně je asi nutné vytvořit routu pro tento styl url, mohl by někdo poradit jak na to? Ideálně aby mi spolupracovala s mými nadefinovanými routami, ukázka jedné z mnoha:
<?php
// bootstrap.php
$container->router[] = new Route('rezervace/[<id>]', array(
    'presenter' => 'Bookings',
    'action' => 'default'
));
?>

UPDATE:
Zkoušel jsem se podívat tady po fóru a našel jsem celkem přehlednou odpověď od Uživatele @Michalek – https://forum.nette.org/…erzi-v-nette#…

Zkusil jsem podle toho upravit 1. routu od vrchu v bootstrap.php na:

<?php
$container->router[] = new Route('//[!<mobile (www|m)>.]' . PROJECT_URL . '/<presenter>/<action>/[</id>]', array(
                'mobile' => 'm',
                'presenter' => 'Register',
                'action' => 'default',
));
?>

Metodu beforeRender jsem nechal jak je uvedeno v odkaze s tím rozdílem, že se ptám přes mobileDetect->isMobile() a přejmenoval jsem podle toho své mobilní šablony.
Problém mi nastává při pokusu o načtení stránky, na mobilním zařízení i desktopu jsem přesměrován na http://m.PROJECT_URL/ a to mi vyhodí nelze nalézt stránku: Server na adrese m.192.168.137.1 nelze najít, protože se nezdařilo vyhledání DNS.

Editoval James07 (13. 4. 2015 8:22)

akadlec
Člen | 1326
+
0
-

Tak místo PROJECT_URL můžeš použít třeba %domain%

<?php
$container->router[] = new Route('//[!<mobile (www|m)>.]%domain%/<presenter>/<action>/[</id>]', array(
                'mobile' => 'm',
                'presenter' => 'Register',
                'action' => 'default',
));
?>
James07
Člen | 41
+
0
-

Přiznám se, že nevím co [!<mobile (www|m)>.] znamená. Někdo, kdo by mi řekl co to je?
@akadlec
Upravil jsem routu na %domain%, ale v tom problém není. PROJECT_URL jsem měl ve tvaru ip adresy 192.168.137.1/nette/www/. Takže děkuji za zobecnění routy :-)

Po zadání http://192.168.137.1/nette/www/register jsem přesměrován s tou routou na http://m.192.168.137.1/nette/www/. Není to divné, nemělo by to být podle té routy http://m.192.168.137.1/nette/www/register?

A to přesměrování se provede vždy, i když jsem na počítači, že by to nakonec neměla být úplně první routa?

akadlec
Člen | 1326
+
0
-

Ne, to tě přesmeruje MobileDetect na zadanou adresu co máš v configu. Zatím nebere možnost přesměrovat na zadanou routu. A samo přesměrovat by tě to mělo když se prohlížeč detekuje jako mobilní.

James07
Člen | 41
+
0
-

Já jsem ale zakázal v configu přesměrování přes mobileDetect:

<?php
mobileDetect:
	redirect:
		mobile:
			isEnabled: false				## default false
			host: http://m.192.168.137.1/nette/www/		## with scheme (http|https), default null, url validate
			statusCode: 301				## default 302
			action: redirect			## redirect, noRedirect, redirectWithoutPath
		tablet:
			isEnabled: false			## default false
			host: http://t.site.com		## with scheme (http|https), default null, url validate
			statusCode: 301				## default 302
			action: redirect			## redirect, noRedirect, redirectWithoutPath
		detectTabletAsMobile: true		## default false
?>

Asi si pletu víc věcí najednou a nedává mi to vůbec smysl. Myslím, že mám především problém s tím, že moje aplikace neví, co je na URL http://m.192.168.137.1/nette/www/.

Původně jsem myslel, že se děje následující:
v config.neon jsem deaktivoval mobileDetect přesměrování, mobileDetect používám pouze pro zjištění mobilního prohlížeče v

<?php
	// metoda mi nastaví layout a šablony pro mobilní verze
	// BasePresenter
	protected function beforeRender() {
		if ($this->mobileDetect->isMobile()) { // mobileDetect detekuje mobilní prohlížeč a tím to pro něj končí
			$this->setView($this->getView() . '.mobile');
			$this->setLayout('layout.mobile');
		}
?>

A tato routa

<?php
$container->router[] = new Route('//[!<mobile (www|m)>.]%domain%/registrovat', array(
                'mobile' => 'm',
                'presenter' => 'Register',
                'action' => 'default',
));
?>

mi zobrazí stránku http://192.168.137.1/nette/www/register na počítači jako:
http://192.168.137.1/nette/www/registrovat
a na mobilu jako
http://m.192.168.137.1/nette/www/registrovat
Ale teď už jak to píšu, mi vyvstává problém, jak detekuje routa, že je to m-ková verze, když mobileDetect používám jenom pro nastavení layoutů šablon ->Takže by mě nakonec mobileDetect měl i přesměrovat na m-kovou verzi a ta routa mi zajistí pouze to, že bude výsledná url vypadat „hezky“ tzn m.url/registrovat ?

akadlec
Člen | 1326
+
0
-

MobileDetect tě přesměruje na zadaný tvar mobilní verze v okamžiku kdy máš desktopovou a detekuje že si na mobilu. Takže pak tě hodí na m.adresa.webu/neco a to jak s tím budeš dále pracovat je na tobě. Můžeš si asi do routy přidat filtr co ti to bude konvertovat na TRUE a FALSE a pak to mít v presenteru jako persistentní parametr.

A pokud se ti to přesměrovává mimo mobiledetect tak ti to dělá asi router nebo nějaké nastavení