Who defines the URLs to be redirected to the mobile version?
Lets take twitter as an example:
https://twitter.com
-> redirect mobilehttps://dev.twitter.com
-> not redirect mobileIn an MVC application who would be responsible for the rule redirects?
Could be all in www
has redirection to mobile device?
If you would like to redirect the subdomain you will need to enter the subdomain with / appended in the From / Known As URL field. For example: subdomain.school.org/. You can then choose to redirect to an existing page on another one of your School websites or redirect the domain to a specific URL.
A Redirect rule instructs the client (usually a browser) to switch URLs and navigate to the destination of the rule. Redirect rules are typically used for old paths that you'd like to redirect to new ones.
One way is to use
.htaccess
or equivalent tools to redirect from server (apache is not the only webserver) and force a redirect. It's already covered in other answers. But there is a different approach to. One that actually would utilize MVC: do not redirect at all.
In correctly implemented MVC, view instances would contain all the UI logic. They would acquire data from model layer (the "how" constitutes most of the difference between Model2, MVP and MVVM), decide from which templates to assemble the response or even if the response need anything more then an HTTP location header.
The difference between mobile and desktop version would be contained to the view instances, assisted by controllers, which in correct MVC structure would only change the state of model layer and current view. What changes it makes should depend on user input.
The following code would be part of bootstrap.php
or init.php
:
// the request instance acts like abstraction for all the user input
$request = new Request;
$request->setUri();
// instantiate the routing mechanism
$router = new Router( new RouteBuilder );
$router->import('/path/to/config.file');
// apply rules from router so that request instance now
// contains the parsed values from URI
$router->route( $request );
// handling of model layer
$serviceFactory = new ServiceFactory;
// since in MVC the controllers are closely tied to views
// (1 controller for 1 view), usually it is convenient to use same class names
$resource = $request->getParameter('resource');
// instantiation of view and controller
$class = '\\View\\' . $resource;
$view = new {$class}( $serviceFactory );
$class = '\\Controller\\' . $resource;
$controller = new {$class}( $serviceFactory, $view);
// i find it convenient to have controller's action be made from
// both REQUEST_METHOD and command name
$action = $request->getMethod() . $request->getParameter('command');
// run it all
$controller->{$action}( $request );
echo $view->render();
In this way, when execution hits the controller's action, it is provided with a fully prepared instance of Request
. Said instance is what determines the details about user's equipment and provides a simple interface for reading these details.
The controller also has access to the model layer and current view, both of which are injected in it through the constructor.
The most straight-forward way is the let the controller alter the state of current view.
namespace Conroller;
class SomeThing
{
public function getUserDetails( $request )
{
if ( $request->isFromMobile() )
{
$this->view->adjustFor( $request->getDeviceType() );
}
$community = $this->serviceFactory->create('Community');
$community->loadUser( $request->getParameter('id'));
}
}
The adjustFor()
method in this case informs the current view instance, that it will need use the templates, that are meant for some non-default device.
There is one very important downside for this approach: it violates OCP from SOLID principles (for lazy people: the short version), because you would have to rewrite each controller method, if you decided to add mobile version for an existing project.
While the following code is relatively easy to understand, it is a bit flawed:
$resource = $request->getParameter('resource');
// instantiation of view and controller
$class = '\\View\\' . $resource;
$view = new {$class}( $serviceFactory );
It starts to break down even when the you only have to provide both HTML and JSON/XML response. The view starts to accumulate same repeating IF
s all over the code. That is a clear sign that you should have used polymorphism, and these lines would be where to do it.
Instead of the above shown code, you could use something like:
$resource = $request->getParameter('resource');
$class = '\\View\\' . $request->getDeviceType . $resource;
$view = new {$class}( $serviceFactory );
Now, when you are having mobile/desktop application you have two classes: \View\DekstopSomething
and \View\MobileSomething
. They each can have separate logic and request completely different data from model layer.
In the meanwhile, the rest of your code is completely decoupled from the output form.
Few reasons why, instead of using server redirects, you should better choose this approach:
Your application becomes independent from server software
Not everywhere you will have Apache (high-load sites often use Nginx or Lighttpd instead) and even if you have Apache, your ability to use mod_rewrite would depend on server's configuration.
Unified scheme for all the links in your site
The link for viewing some news item is always the same, no matter on what device you use it. It makes fro much easier sharing and bookmarking of URLs.
Single point of change
This approach lets you initially make the site for desktop users and then add the mobile/tablet support without rewriting any of the existing code.
You might also be interested in reading two older post on the subject about implementation of model layer and access control in context of MVC.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With