Strona CakePHP Wersja mobilna
Opracowałem pełną stronę internetową z frameworkiem CakePHP i chcielibyśmy zrobić bardzo lekką wersję strony dla urządzeń mobilnych (głównie iPhone/iPad).
Czy istnieje sposób na wykorzystanie istniejącej strony z nową sub domeną (na przykład mobile.mywebsite.com) które będą renderować określone widoki? Chciałbym uniknąć kopiowania i upraszczania obecnego, aby dopasować się do nowych wymagań. Nie chcę musieć "wznawiać" nowej strony CakePHP i dokonywać zmian dwa razy na dobę czas muszę zmienić działanie kontrolera.
8 answers
Zrobiłem to za pomocą szybkiego dodania do funkcji beforeFilter () w moim app_controller.plik php.
function beforeFilter() {
if ($this->RequestHandler->isMobile()) {
$this->is_mobile = true;
$this->set('is_mobile', true );
$this->autoRender = false;
}
}
To używa CakePHP RequestHandler, aby wyczuć, czy jest to urządzenie mobilne odwiedzające moją stronę. Ustawia właściwość i zmienną view, aby umożliwić operacje, które widoki dostosowują się do nowego układu. Wyłącza również autoRender, ponieważ zajmiemy się tym w afterfiltrze.
W afterfilter() szuka i używa mobilnego pliku widoku, jeśli taki istnieje. Mobile wersje są przechowywane w folderze "mobilnym" wewnątrz folderu widoku kontrolera i mają taką samą nazwę, jak normalne wersje Nie-mobilne. (tj. add.ctp staje się mobilny / add.ctp)
function afterFilter() {
// if in mobile mode, check for a valid view and use it
if (isset($this->is_mobile) && $this->is_mobile) {
$view_file = new File( VIEWS . $this->name . DS . 'mobile/' . $this->action . '.ctp' );
$this->render($this->action, 'mobile', ($view_file->exists()?'mobile/':'').$this->action);
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-15 00:01:42
Odpowiedź dana zadziałała na mnie. Jednak użyłem file_exists zamiast konstruktora plików i dodałem możliwość korzystania z mobilnych układów. Przed filtrem był taki sam, ale afterFilter wyglądał tak:
function afterFilter() {
// if in mobile mode, check for a valid view and use it
if (isset($this->is_mobile) && $this->is_mobile) {
$view_file = file_exists( VIEWS . $this->name . DS . 'mobile/' . $this->action . '.ctp' );
$layout_file = file_exists( LAYOUTS . 'mobile/' . $this->layout . '.ctp' );
$this->render($this->action, ($layout_file?'mobile/':'').$this->layout, ($view_file?'mobile/':'').$this->action);
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-10 01:39:33
Możesz użyć funkcji tematu w CakePHP 2.x dla układu mobilnego.
Po prostu zrób:
if($this->RequestHandler->isMobile())
$this->theme = 'mobile';
Znalazłem to lepiej, jak można udostępniać plik widoku na telefon komórkowy i pulpit motyw Łatwo.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-05 13:38:59
Zmodyfikowałem tę technikę dla aplikacji CakePHP 2.1. Oto mój beforeFilter()
:
public function beforeFilter() {
if ($this->request->isMobile()){
$this->is_mobile = true;
$this->set('is_mobile', true );
$this->autoRender = false;
}
}
A oto moje afterFilter()
:
function afterFilter() {
// if in mobile mode, check for a valid view and use it
if (isset($this->is_mobile) && $this->is_mobile) {
$view_file = file_exists( 'Views' . $this->name . DS . 'mobile/' . $this->action . '.ctp' );
$layout_file = file_exists( 'Layouts' . 'mobile/' . $this->layout . '.ctp' );
if($view_file || $layout_file){
$this->render($this->action, ($layout_file?'mobile/':'').$this->layout, ($view_file?'mobile/':'').$this->action);
}
}
}
To pomaga rozliczać przestarzałe wersje i stałe w CakePHP 2.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-14 15:29:55
Prostym rozwiązaniem jest utworzenie nowego' mobilnego ' układu z odpowiednimi arkuszami stylów i włączenie go w AppController:
public $components = array('RequestHandler');
public function beforeRender() {
parent::beforeRender();
if ($this->RequestHandler->isMobile()) {
$this->layout = 'mobile';
}
}
Ważne jest, aby to zrobić w beforeRender()
w przypadku, gdy zmienisz $this->layout
w metodach kontrolerów.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-12 12:25:41
CakePHP v2. 2. 1 Solution (+Cookies to persist mobile/desktop/other layout)
To rozwiązanie jest oparte na odpowiedziach @ Dan Berlyoung, @deewilcox i @Chris K .
Część tych odpowiedzi nie zadziałała (dla mnie) w CakePHP 2.2.1.
Rozszerzyłem również rozwiązanie, aby wspierać "wymuszanie" mobilnego/desktopowego/innego layoutu z frontendu-przydatne do debugowania i dla użytkowników, którzy nie chcą utknąć na" mobilnym " temacie układ.
/app / Controller / AppController.php
class AppController extends Controller {
public $components = array('Cookie');
public $is_mobile = false;
public $layouts = array('desktop', 'mobile');
// executed before every action in the controller
function beforeFilter()
{
// Using "rijndael" encryption because the default "cipher" type of encryption fails to decrypt when PHP has the Suhosin patch installed.
// See: http://cakephp.lighthouseapp.com/projects/42648/tickets/471-securitycipher-function-cannot-decrypt
$this->Cookie->type('rijndael');
// When using "rijndael" encryption the "key" value must be longer than 32 bytes.
$this->Cookie->key = 'qSI242342432qs*&sXOw!adre@34SasdadAWQEAv!@*(XSL#$%)asGb$@11~_+!@#HKis~#^'; // When using rijndael encryption this value must be longer than 32 bytes.
// Flag whether the layout is being "forced" i.e overwritten/controlled by the user (true or false)
$forceLayout = $this->Cookie->read('Options.forceLayout');
// Identify the layout the user wishes to "force" (mobile or desktop)
$forcedLayout = $this->Cookie->read('Options.forcedLayout');
// Check URL paramaters for ?forcedLayout=desktop or ?forcedLayout=mobile and persist this decision in a COOKIE
if( isset($this->params->query['forcedLayout']) && in_array($this->params->query['forcedLayout'], $this->layouts) )
{
$forceLayout = true;
$forcedLayout = $this->params->query['forcedLayout'];
$this->Cookie->write('Options.forceLayout', $forceLayout);
$this->Cookie->write('Options.forcedLayout', $forcedLayout);
}
// We use CakePHP's built in "mobile" User-Agent detection (a pretty basic list of UA's see: /lib/Cake/Network/CakeRequest.php)
// Note: For more robust detection consider using "Mobile Detect" (https://github.com/serbanghita/Mobile-Detect) or WURL (http://wurfl.sourceforge.net/)
if( ( $forceLayout && $forcedLayout == 'mobile' ) || ( !$forceLayout && $this->request->is('mobile') ) ) {
$this->is_mobile = true;
$this->autoRender = false; // take care of rendering in the afterFilter()
}
$this->set('is_mobile', $this->is_mobile);
}
// executed after all controller logic, including the view render.
function afterFilter() {
// if in mobile mode, check for a vaild layout and/or view and use it
if( $this->is_mobile ) {
$has_mobile_view_file = file_exists( ROOT . DS . APP_DIR . DS . 'View' . DS . $this->name . DS . 'mobile' . DS . $this->action . '.ctp' );
$has_mobile_layout_file = file_exists( ROOT . DS . APP_DIR . DS . 'View' . DS . 'Layouts' . DS . 'mobile' . DS . $this->layout . '.ctp' );
$view_file = ( $has_mobile_view_file ? 'mobile' . DS : '' ) . $this->action;
$layout_file = ( $has_mobile_layout_file ? 'mobile' . DS : '' ) . $this->layout;
$this->render( $view_file, $layout_file );
}
}
}
/app / View / Elements / default_footer.ctp
<ul>
<?php
$paramsQuery = $this->params->query;
if(!is_array($paramsQuery))
{
$paramsQuery = array();
}
$paramsQuery['url'] = ( isset($paramsQuery['url']) ) ? $paramsQuery['url'] : '';
$url = $paramsQuery['url'];
unset($paramsQuery['url']);
$params = $paramsQuery;
$mobile_url = '/' . $url . '?' . http_build_query( array_merge( $params, array( 'forcedLayout' => 'mobile' ) ) );
$desktop_url = '/' . $url . '?' . http_build_query( array_merge( $params, array( 'forcedLayout' => 'desktop' ) ) );
?>
<?php if($is_mobile): ?>
<li><?= $this->Html->link('Desktop Site', $desktop_url, array('target' => '', 'class' => '')) ?></li>
<?php else: ?>
<li><?= $this->Html->link('Mobile Site', $mobile_url, array('target' => '', 'class' => '')) ?></li>
<?php endif; ?>
</ul>
/app / View / Layouts / default.ctp
<h1>Desktop Site Layout</h1>
<?= $this->fetch('content') ?>
/app / View / Layouts / mobile / default.ctp
<h1>Mobile Site Layout</h1>
<?= $this->fetch('content') ?>
/app / View / Pages / home.ctp
<h2>Home - on Desktop</h2>
<?= $this->element('default_footer') ?>
/app / View / Pages/mobile / home.ctp
<h2>Home - on Mobile</h2>
<?= $this->element('default_footer') ?>
Użycie
Użyj linków default_footer
, aby zmienić układ-lub te bezpośrednie urls
http://example.com/pages/home?forcedLayout=desktop
http://example.com/pages/home?forcedLayout=mobile
Plik cookie sesji zachowuje wybraną opcję... na przykład spróbuj ustawić "mobile", a następnie odwiedź url bez param forcedLayout=
.
http://example.com/pages/home
default_footer
Linki utrzymują istniejące paramy (z wyjątkiem " fragmentu" ~ gohere)
http://example.com/pages/home/a/b/c:d?this=that&foo=bar#gohere
URL witryny desktopowej is:
http://example.com/pages/home/a/b/c:d?this=that&foo=bar&forcedLayout=desktop
Aby uzyskać bardziej niezawodne wykrywanie agenta użytkownika urządzenia, rozważ użycie biblioteki PHP Mobile Detect ... możesz następnie kierować Tablety, a nawet określone wersje systemu operacyjnego devise.... Co za zabawa! ^_^
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:53:11
Rozwiązaniem, które wybrałem, była lekka modyfikacja oparta na kilku odpowiedziach tutaj, dla CakePHP 2.5.5. Obsługa jest wykonywana w beforeRender (zauważ, że beforeRender jest uruchamiany tylko na akcjach kontrolera, które faktycznie renderują stronę, więc oszczędza to narzuty w przeciwieństwie do beforeFilter/afterFilter dla metod prywatnych):
$mobile = $this->request->is('mobile');
$this->set('mobile',$mobile);
//Check if an alternate mobile view and/or layout exists for this request.
if($mobile){
if(file_exists(APP.'View'.DS.$this->name.DS.'mobile'.DS.$this->view.'.ctp')){
//Render this action on its mobile view.
$this->view = 'mobile'.DS.$this->view;
}
if(file_exists(APP.'View'.DS.'Layouts'.DS.'mobile'.DS.$this->layout.'.ctp' )){
//Render this action on its mobile layout.
$this->layout = 'mobile'.DS.$this->layout;
}
}
Zmienna $mobile może być używana w każdym widoku, jeśli masz drobne poprawki do wykonania, w przeciwnym razie możesz opcjonalnie zastąpić dowolny widok View / {controller} / mobile / same_file_name.ctp lub layout z View / Layouts / mobile / same_file_name.ctp, aby mieć całkowicie oddzielną strukturę strony.
Zauważ, że to używa $this - > view I $this - >layout, a następnie je modyfikuje, zamiast używać $this->action I $this->render(widok,układ), ponieważ twój widok nie zawsze będzie pasował do Twojej akcji (ten sam widok, wiele akcji, na przykład złamanie za pomocą $this->action), a to rozwiązanie zapobiega konieczności martwienia się o to, kiedy $this - > render() zostanie wymuszone, i pozwala, aby stało się to naturalnie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-16 13:19:55
Tak, możesz ponownie użyć wszystkich swoich domen i kontrolerów, zajrzyj do Tera-Wurlf
I jeszcze lepiej, nie potrzebujesz subdomeny do wersji mobilnej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-08 14:17:11