Im trying to buil a mobile version of my website, usign Cakephp and JQueyrMobile.
For the Cakephp part i opted to use the following in app_controller:
if($this->RequestHandler->isMobile() || isset($this->params['url']['mobile'])) {
$this->layout = 'mobile';
$this->isMobile = true;
}
$this->set('is_mobile', $this->isMobile);
if($this->isMobile) {
$this->action = 'mobile/'.$this->action;
}
Thank i create the /mobile/ folder for every controller/view and it works fine.
I just have a problem with the home.ctp ! i created the alternative mobile version in /views/pages/mobile/home.ctp but it loads the /views/pages/home.ctp.
What should i do in order to redirect to the mobile version of home.ctp usign the code above ?
Thanks!
Have you tried using beforeFilter and afterFilter in your AppController?
I use this for the mobile version of one of my Cake applications:
function beforeFilter() {
if ($this->RequestHandler->isMobile()) {
$this->is_mobile = true;
$this->set('is_mobile', true );
$this->autoRender = false;
}
}
And afterFilter:
function afterFilter() {
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);
}
}
This code comes from another question on mobile content in Cake, have a look at this answer for more information. Another answer on that same question deals with layouts.
Related
I'm writing a small routing system for a project. It's not perfect and it's a custom solution that will map the url to their templates if requested from the user. I want to generate a dynamic page based on an unique id for each event inserted inside the database from the user. So if the user request the event 1234 it will get a page with the event detail at the url https://mysitedomain.com/event/1234. I need to understand how to achieve this with my code, I'm using a front controller and red bean as ORM to access the database.
Here is the code of my router. Any suggestion will be appreciated. for now I'm only able to serve the templates.
<?php
namespace Router;
define('TEMPLATE_PATH', dirname(__DIR__, 2).'/assets/templates/');
class Route {
private static $assets = ['bootstrap' => 'assets/css/bootstrap.min.css',
'jquery' => 'assets/js/jquery.min.js',
'bootstrapjs' => 'assets/js/bootstrap.min.js',
];
public static function init()
{
if( isset($_SERVER['REQUEST_URI']) ){
$requested_uri = parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH);
if( $requested_uri === '/' ){
echo self::serveTemplate('index', self::$assets);
}
elseif( $requested_uri != '/' ){
$requested_uri = explode('/', $_SERVER['REQUEST_URI']);
if( $requested_uri[1] === 'event' ){
echo self::serveTemplate('event', self::$assets, ['event_id' => 001] );
}
else{
echo self::serveTemplate($view, self::$assets);
}
}
}
}
private static function serveTemplate(string $template, array $data, array $event_id = null)
{
if( !is_null($event_id) ){
$data[] = $event_id;
ob_start();
extract($data);
require_once TEMPLATE_PATH."$template.php";
return ob_get_clean();
}
else{
ob_start();
extract($data);
require_once TEMPLATE_PATH."$template.php";
return ob_get_clean();
}
}
}
?>
Writing a router from scratch is a little complex, you have to play a lots with regular expression to accommodate various scenario of requested url and your router should handle HTTP methods like POST, GET, DELETE, PUT and PATCH.
You may want to use existing libraries like Fast Route, easy to use and it's simplicity could give you idea how it is created.
I am trying to make a CRUD Module in Codeigniter HMVC but I seem to be missing something in the process. Here is what I am facing.
I have a News Module which has a Manage function
function manage(){
$grid = Modules::run('Crud/renderGrid', 'News' , 'News management');
}
Render Grid Function
function renderGrid($module , $page_title){
$data['page_title'] = $page_title; //Dynamic
$data['module'] = $module;
$data['view_module'] = 'Crud';
$data['displayfields'] = Modules::run($module.'/get_displayfields');
$data['key'] = Modules::run($module.'/get_key');
$data['rows'] = Modules::run($module.'/get' , $data['key']);
$data['view_file'] = 'manage';
$this->load->module('dashboard');
$this->dashboard->show_dashboard($data);
}
Here, the show_dashboard function just loads up a template layout with a desired view in it.
function show_dashboard($data = NULL){
if($data == NULL){
$data['view_file'] = "manage";
$data['page_title'] = 'Sigma Web Solutions';
}
$this->load->module('templates');
$this->templates->admin($data);
}
Templates->admin
function admin($data){
$this->load->view('admin' , $data);
}
The View (omitting the header n Footer)
<?php
if (!isset($view_file)) {
$view_file = "";
}
if (!isset($view_module)) {
$module = $this->uri->segment(1);
}
if (($view_module!="") && ($view_file!="")) {
$path = $view_module."/".$view_file;
$this->load->view($path);
}
?>
Now, when I try the url news/manage, it gives me a blank page with no source code in it. But when I try something like
crud/renderGrid/news/sometitle/ it works just fine.
Kindly point out what did I miss here. Thanks.
Working Solution:
Thanks to wolf I added a route
$route['managenews']= 'crud/renderGrid/news/News';
And it works like charm. But why do I need a route here? Shouldn't it just work. And this means for every module I need to have 4 entries in my route file for the CRUD system to work. can anyone suggest a better method?
I'm trying to create multilingual application. I've implemented ability of translationable content and next step should be showing it to user. I want to have ability of changing language depending on URL. I've found a couple of components for those purposes but they all create urls which I don't like. For example, my application's default language is English and I have content which is translated into French. I have page "contacts", for instance. And URLs which will be generated by application will be: mysite.com/en/contacts, mysite.com/fr/contacts, but I want to have mysite.com/contacts for default language and mysite.com/fr/contacts for French language. It's simillar for site's root too. mysite.com/ - for default language and mysite.com/fr for French.
Is there any methods for implementing these functionality?
I'm using XUrlManager extension XUrlManager on GitHub
Yii generates URL's based on UrlManager rules. If you want URL's without /lang/ code - you need just create correct rules. For example, if you dublicate records in rules array:
'rules'=>array(
'<_c:\w+>/<_a:\w+>'=>'<_c>/<_a>',
'<language:\w{2}>/<_c:\w+>/<_a:\w+>'=>'<_c>/<_a>',
);
your URL's will be generated withou /en/ and /fr/, but URL's with code works too. By default, XUrlManager use previously selected language and store this in session or cookie.
If you want only hide /en/ and use /fr/ and others always, you can change your XUrlManager extension with:
public function createUrl($route,$params=array(),$ampersand='&')
{
if(!isset($params['language']) && Yii::app()->language!=='en')
$params['language']=Yii::app()->language;
return parent::createUrl($route,$params,$ampersand);
}
I've found very elegant method for solving my problem on http://www.elisdn.ru
Reimplement CHttpRequest
class DLanguageHttpRequest extends CHttpRequest
{
private $_requestUri;
public function getRequestUri()
{
if ($this->_requestUri === null)
$this->_requestUri = DMultilangHelper::processLangInUrl(parent::getRequestUri());
return $this->_requestUri;
}
public function getOriginalUrl()
{
return $this->getOriginalRequestUri();
}
public function getOriginalRequestUri()
{
return DMultilangHelper::addLangToUrl($this->getRequestUri());
}
}
Reimplement CUrlManager
class DLanguageUrlManager extends CUrlManager
{
public function createUrl($route, $params=array(), $ampersand='&')
{
$url = parent::createUrl($route, $params, $ampersand);
return DMultilangHelper::addLangToUrl($url);
}
}
Change config
return array(
'sourceLanguage'=>'en',
'language'=>'ru',
'components'=>array(
'request'=>array(
'class'=>'DLanguageHttpRequest',
...
),
'urlManager'=>array(
'class'=>'DLanguageUrlManager',
...
),
),
...
'params'=>array(
'translatedLanguages'=>array(
'ru'=>'Russian',
'en'=>'English',
'de'=>'Deutsch',
),
'defaultLanguage'=>'ru',
),
);
Create DMultilangHelper
class DMultilangHelper
{
public static function enabled()
{
return count(Yii::app()->params['translatedLanguages']) > 1;
}
public static function suffixList()
{
$list = array();
$enabled = self::enabled();
foreach (Yii::app()->params['translatedLanguages'] as $lang => $name)
{
if ($lang === Yii::app()->params['defaultLanguage']) {
$suffix = '';
$list[$suffix] = $enabled ? $name : '';
} else {
$suffix = '_' . $lang;
$list[$suffix] = $name;
}
}
return $list;
}
public static function processLangInUrl($url)
{
if (self::enabled())
{
$domains = explode('/', ltrim($url, '/'));
$isLangExists = in_array($domains[0], array_keys(Yii::app()->params['translatedLanguages']));
$isDefaultLang = $domains[0] == Yii::app()->params['defaultLanguage'];
if ($isLangExists && !$isDefaultLang)
{
$lang = array_shift($domains);
Yii::app()->setLanguage($lang);
}
$url = '/' . implode('/', $domains);
}
return $url;
}
public static function addLangToUrl($url)
if (self::enabled())
{
$domains = explode('/', ltrim($url, '/'));
$isHasLang = in_array($domains[0], array_keys(Yii::app()->params['translatedLanguages']));
$isDefaultLang = Yii::app()->getLanguage() == Yii::app()->params['defaultLanguage'];
if ($isHasLang && $isDefaultLang)
array_shift($domains);
if (!$isHasLang && !$isDefaultLang)
array_unshift($domains, Yii::app()->getLanguage());
$url = '/' . implode('/', $domains);
}
return $url;
}
}
After all of these steps your application will have URLs which you want
More information here
Im new with Yii and Im trying to implement the parseUrl to manage API Version at the url.
I would like to redirect /api/1.0/... to controller apiV1.0.
Main.php (urlManager rules):
...
array('class' => 'application.components.ApiVersion'),
...
ApiVersion.php:
<?php
class ApiVersion extends CBaseUrlRule
{
public $connectionID = 'db';
public function createUrl($manager,$route,$params,$ampersand)
{
if ($route==='car/index')
{
if (isset($params['manufacturer'], $params['model']))
return $params['manufacturer'] . '/' . $params['model'];
else if (isset($params['manufacturer']))
return $params['manufacturer'];
}
return false; // this rule does not apply
}
public function parseUrl($manager,$request,$pathInfo,$rawPathInfo)
{
if (preg_match('%^(\w+)(/(\w+))?$%', $pathInfo, $matches))
$url = $match[1] . $match[2]; // BUILD YOUR URL (controllerName/actionName)
$this->redirect(array($url));
}
return false;
}
}
Im very lost with how it works, someone could help me?
In your function the regex checks if the path is something like "api/num_of_version/your_model/an_id"
So if your url is matching this your are in the condition, you'll have to set the get values:
$_GET['apiversion'] = $matches[2];
$_GET['model'] = $matches[4];
$_GET['id'] = $matches[6];
And depending on the version you return the good controller:
return "apiV" . $_GET['apiversion'] . "/view";
Some links you need to understand:
How preg_match works (what is the structure of $matches)
Yii custom Url class
Edit: If there is a particular point where your have some trouble please let me now, i'll try to ellaborate a little more my answer on this point.
I'm trying to set up a redirect on my SilverStripe site.
I have created my own module, and now I want the user to be redirected to that after log in.
I've tried with Director::redirect($Url_base . 'myModule'), but it doesn't work.
Does anyone have any suggestions?
Try this: http://www.ssbits.com/customize-the-redirect-after-a-successful-member-login/
I did something like this:
class MyLoginForm extends MemberLoginForm {
public function dologin($data) {
parent::dologin($data);
if (Director::redirected_to() && $Member = Member::currentUser()) {
$this->controller->response->removeHeader('Location');
if ($Member->Email == 'admin') {
$destination = '/admin';
} else {
$destination = '/user/' . $Member->Username;
}
Director::redirect($destination);
}
}
}
If it is the admin user I redirect them to /admin. If it is another user I redirect them to /user/username.