im messing around with laravel to do a multilanguage website.
I am trying to implement this:
$languages = array('en','fr');
$locale = Request::segment(1);
if(in_array($locale, $languages)){
\App::setLocale($locale);
}else{
$locale = null;
}
Route::group(array('prefix' => $locale), function()
{
Route::get('/', 'Homecontroller#index');
Route::get('contact', 'Homecontroller#contact');
});
for what i can see, everythings works fine,
I understand, Laravel take locale from my url segment, check if it's in languages, if is not null he change the routing adding the prefix. I have 2 question:
1) Why all my images now is not showed properly anymore, when i go to en/contact, while when i go to en/ I can see them.
2) to use a database to pick up languages, i don't necessarly have to change App:setLocale, but i need to do a model to extract language to database and put in the right place?
3) how to pass the variable languages to blade, so i can change the description of the product?? (I used to do ?lang=en and then take it with a $_GET
Sorry i know maybe this is just a basic question, but i come from pure php and pure mysql background.
EDIT:
1) I need to use the HTML:: image facade like {{HTML::image('path')}}
To me it seems like you are linking to your images with relative
paths which will break when you start to have a different structure
in your URL. So try having absolute URL:s in your image src tags or
make them start with a slash (/). E.g. {{ HTML::image('/absolute/path/to/image.jpg') }}
I'm not sure if I understand your question, but you want to store your translations in the database instead of in files which is the default? Maybe this could be something for you: https://github.com/Waavi/translation
This is doable in a lot of different ways. For example you could
just call {{{ Request::segment(1) }}} in your blade template and
get your language (assuming it's segment number 1). But the neatest
way would probably be to wrap it in a function and put it in an appropriate place according to your application's structure.
Related
I have been learning Laravel recently and I have seemingly missed a key point: why should relative links be avoided?
For example, I have been suggested to use URL::to() which outputs the full path of the page passed as a parameter - but why do this when you could just insert a relative link anyway? E.g., putting URL::to('my/page') into a <href> will just insert http://www.mywebsite.com/my/page into the <href>; but on my website href='my/page' works exactly the same. On my website I have based all relative URL's from the index.php file found in the public directory.
Clearly, I'm missing a key point as to why full paths are used.
I've found that using route() on named routes to be a much better practice. If at one point you decide, for example, that your admin panel shouldn't point to example.com/admin, but example.com/dashboard, you will have to sift through your entire code to find all references to Url::to("/admin"). With named routes, you just have to change the reference in routes.php
Example:
Route::get('/dashboard', ['as' => 'admin', 'uses' => 'AdminController#index']);
Now every time you need to provide a link to your admin page, just do this:
Admin
Much better approach, in my opinion.
This is even available in your backend, say in AdminController.php
// do stuff
return redirect()->route('admin');
http://laravel.com/docs/5.1/routing#named-routes
Neither absolute nor relative links should be used - it's advisable to use named routes like so:
Route::get('my/page', ['as' => 'myPage', function () {
// return something
}]);
or
Route::get('my/page', 'FooController#showPage')->name('myPage');
Then, generate links to pages using URL::route() method (aliased as route() in L5), which is available in Blade as well as in your backend code.
That way, you can change the path to your routes at any time without having to worry about breaking links anywhere in your application.
I have pages that are generated from a database, based on the URI. Functons as it should, however I can't set-up my routes to eliminate the controller and function from the URL.
$route['studios/(:any)'] = 'studios/location/$1';
Right now, I have the route to show the controller name and the URI variable (whatever that may be). However, I want to eliminate the controller name as well and just display the URI variable that's called as the URL. Hard to explain - hopefully someone picks up my drift...
Current URL would be: domain.com/studios/studio1
But I want to just display: domain.com/studio1
I tried $route['/(:any)'] = 'studios/location/$1';, but that's messing up my entire site.
Help?
$route['studios(/:any)*'] = 'studios/location';
This route will force everything from studios on to studios/location. You can then access any of the parameters using URI segments:
$id = $this->uri->segment(2);
If your URL was somewhere.com/studios/location/2, $id would resolve to 2
However, since you want it to just be from the root on, you will have to put your override route at the bottom of the routes file so it is assessed last:
// all other routes here. Which must be specifically
// defined if you want a catch all like the one you mentioned
$route['(:any)'] = 'studios/location';
Alternatively, if you want a high maintenance site, you can specify a collection of routes like so:
$route['(studio1|studio2|studio3)'] = 'studios/location/$1';
how is it "messing up your site"?
In any case, you should not have the / before (:any)
Just:
$route['(:any)'] = 'studios/location/$1';
EDIT:
BEFORE the $route['(:any)'], you'll need to specify routes fro all your controllers; this is pretty normal, don't know if I'd call it "high maintenance", but you'll need to decide
I am trying to create short links to my application in codeigniter but I've met a kind of a problem when designing my route. The problem is that I want a route which will take a string containing a-Z and numbers and redirect that to a controller called image with the string after. Like this: app.com/randomstring -> app.com/image/randomstring. But when I am trying to do this in the routes config file with a regular expression it disables my application and I am unable to enter "normal" urls with controllers that already exist.
How my route looks like right now (I know it's probably very wrongly made):
$route['(^[A-Za-z0-9]+$)'] = "image/$1";
Is there any easy way to redirect with that short url without using another fake controller first like this: app.com/i/randomstring -> app.com/image/randomstring
And could you maybe help me improve and tell me what part of my regexp is failing?
As I mentioned in the comments, without a clearly defined spec on what the image urls will be, there's no comprehensive way to solve this. Even YouTube (related to the library you linked to) uses urls like /watch?v=h8skj3, where "watch" is the trigger.
Using a i/r4nd0m$tring would make this a non-issue, and it's what I suggest, but I had another idea:
$route['(:any)'] = "image/$1";
// Re-Route all valid controllers
foreach (array('users', 'login', 'blog', 'signup') as $controller)
{
$route[$controller] = $controller;
$route[$controller.'/(:any)'] = $controller.'/$1';
}
unset($controller);
You might need the image route last, I'm not 100% sure. This should route everything to image/ except the controllers you define. You could even use glob() or something to scan your controller directory for PHP files to populate the array.
Another way to get one character shorter than i/string could be to use a character trigger, like example.com/*randomstring, but that's a little silly, i/ is much cleaner and obviously, easier to deploy.
With CodeIgniter I'm trying to create a URL structure that uses a title string as the entire URI; so for example: www.example.com/this-is-a-title-string
I'm pretty confident I need to use the url_title() function in the URL Helper along with the routes.php config folder but I'm stuck bringing it all together.
Where do I define the URI and how is it caught by the routes folder?
Seems to be a straight forward problem but I'm getting stuck creating the URLs end-to-end. What am I missing?
I thought about a catch-all in the routes folder: $route['(.*)'] = "welcome/controller/$1"; ....but how would this work with multiple functions inside a particular controller? ...and maybe it's not even the right way to solve.
You can send all requests to a driver with something like this:
$route['(:any)'] = "welcome/function";
Then use the _remap function to route requests inside the controller.
However, using URL's as you suggest limits the CI functionality. Try something better like www.example.com/article/this-is-a-title-string
$route['article/(:any)'] = "articles/index";
and in article (controller), use _remap...
If you're going to re-route every request, you should extend CI_Router.
The actual implementation depends on what you're doing. If you customize CI_Router, you can do it AFTER the code that checks routes.php, so that you can keep routes.php available for future customization.
If the URI contains the controller, function, and parameters, you can parse it within your extended CI_Router and then continue with the request like normal.
If the URI is arbitrary, then you'll need something (file, db, etc) that maps the URI to the correct controller/function/parameters. Using blog posts as an example, you can search for the URI (aka post-slug in WordPress) in the db and grab the corresponding record. Then forward the request to something like "articles/view/ID".
Let's pretend I'm trying to learn CI, and as my test project I am building a group-buying site.
What I'd like is to have a different page for each city, e.g.:
http://www.groupon.com/las-vegas/
http://www.groupon.com/orlando/
I'd also like to have different pages such as:
http://www.groupon.com/learn
http://www.groupon.com/contact-us
If I am building this in CI and following the MVC ideology, how would this work? I'm having difficulty seeing how to accomplish the desired URL's with the concept of:
http://www.domain.com/controller/view/segment_a/segment_b/etc...
What I would do is create a custom 404 controller that acts as a catch-all for non-existent routes.
It would take the URI, possibly validate it, and re-route it to the (e.g.) "city" controller.
If the city controller can't find the city (whatever string was specified), then it needs to issue a proper 404. Otherwise, you're good to display your information for that city.
Also, once you create your custom 404 controller, you can send all 404 errors to it by specifying a route named '404_override'.
That's where URI Routing comes in. But in your case you'll probably will have to be carefull defining your routes as the first and only part of your route is a variable part already.
This really has nothing to do with MVC, and much more to do with good URL.
You're looking for URLs that are both (a) clear from the user's point of view and (b) that give hints to your application as to how it's meant to be handled.
What I'd do in this case is redesign your URLs slightly so that rather than:
http://www.groupon.com/las-vegas/
http://www.groupon.com/orlando/
You would have URLs that looks like this:
http://www.groupon.com/destinations/las-vegas/
http://www.groupon.com/destinations/orlando/
The bit at the beginning--/destinations/--can be used by your URL routing code to decide what controller should be dealing with it. If your routing code is URL-based, you might have an array like this:
$routes = array(
'/destinations/' => 'on_destination_list',
'/destinations/(.+)' => 'on_destination',
'/(.*)' => 'on_page');
// Basic URI routing code based off of REQUEST_URI
foreach ($pattern => $func) {
if (preg_match("`^$pattern$`", $_SERVER['REQUEST_URI'], $placeholders)) {
array_shift($placeholders);
call_user_func($func, $placeholders);
}
}
Keep in mind that I wrote that routing code off the top of my head and it may not be absolutely correct. It should give you the gist of what you need to do.
Doing things this way has the added benefit that if somebody goes to http://www.groupon.com/destinations/, you'll have the opportunity to show a list of destinations.