CodeIgniter Url Rewrite (language dependent) - codeigniter

So, i have my .htaccess, my controllers, everything is going fine. I added localization, so now i have Portuguese(Default), English and Italian.
I am using the _lang files in the appplication/languages directory, i am using session->userdata('lang') and everything works fine.
My controllers are named with portuguese words, after the top menu. What i'm looking for is:
to rewrite my url, changing the name of the controller, depending on the session->userdata('lang').
Is this even possible? how?
Thank you
So i am trying, as InFog suggested, in the routes file:
if ($this->session->userdata('lang') == 'english') {
$route['novidades/([a-z]+)'] = 'news/$1';
}
but i just get a blank screen when i open the application.
And i've tried it without the if clause, and nothing happens, when i go to
http://localhost/myapp/novidades
the url stays the same

You can solve this using CodeIgniter Routes. You can do it editing the file 'system/application/config/routes.php:
$route['news/([a-z]+)'] = 'noticias/$1';
This way an URL like '/news/run-fools' will be remaped to 'noticias/run-fools'. Now you can have just one controller =)
Good Luck

Override CI_Router to translate the name in the fetch_class() method to change controllers. Override fetch_method() to change methods.

Related

ASP.NET Core MVC : Razor pages routing, incorrectly re-using previous route data

I'm working on a dotnet 6 mvc application using RazorPages, and I'm having a problem with strange routing behavior.
I have a RazorPage /Pages/News.cshtml
This page is accessible using the default route /news
When called without any parameters this page will display an index of news articles.
I also want this page to be able to display a specific news article, via a path like this...
/news/1234-my-news-article
To achieve this, I've added a config like so...
builder.Services.AddRazorPages(options =>
{
options.Conventions.AddPageRoute("/News", "News/{id:regex(^\\d+\\-.*)?}");
});
In my templates, I can then use links like this...
<a asp-page="/News" asp-all-route-data="#(new Dictionary<string, string> { { "id", "1234-my-news-article" } })">My News Article</a>
or
<a asp-page="/News">All Articles</a>
However, once I've navigated to a specific article, the index link doesn't render correctly, and will instead link again to the same article. It appears to be re-using the current routing parameters.
Is there some way to avoid this?
update:
I've found a work-around, if I use this tag instead...
<a asp-page="/News" asp-route-id="">All Articles</a>
then it will link correctly to "/news".
It seems a bit counter-intuitive to have to explicitly set this to blank. I would have assumed it would default to unset, unless explicitly set otherwise.
This is known as ambient route values (https://www.learnrazorpages.com/razor-pages/tag-helpers/anchor-tag-helper#ambient-route-values), where the current route values are automatically added to outbound links which are generated by the anchor tag helper if the destination page is the same as the current page. In older versions of Razor Pages, this was the default behaviour for all pages.
As you have discovered, you can override this by setting the route value to an empty string, or as suggested elsewhere, to use a plain anchor tag for your link.
asp-page tag helper will add id value to the route by default.It is by design.If you don't want to add it,you can try to use href to replace asp-page:
All Articles

Is there a way to set optional route location parts?

firstly, I am not sure how to structure the question title correctly, feel free to edit it to represent the question correctly. I will try to explain what I mean.
I implemented localization on my app (URL of tutorial is at bottom of this post), and I have created my route as follows:
// Set language
Route::get('lang/{locale}', 'PagesController#lang');
And it works. But only on pages which have only one "level" in the url:
example.com/first-level - changing language works on these URLs
example.com/first-level/second-level - changing language doesn't work on these pages
At first I thought the problem is with url parameters, cause by chance, the pages where I first noticed changing language didn't work was on a url which has a route with an parameter like this
example.com/first-level/{id}
So then I tried to rewrite the route for changing languages to this (added an optional parameter)
// Set language
Route::get('lang/{optional?}/{locale}', 'PagesController#lang');
But that didn't work either
The language is changed by anchor tags which point to the route
<a href="lang/en">English</
Serbian
Expected result: being able to change the language from whichever page the links are clicked. Clicking the links on pages like example.com/one/two and example.com/one/{id}/two are supposed to work.
Actual results: changing language works only on example.com and pages like example.com/one , and fails on example.com/one/two and example.com/one/{id}/two . When the links are clicked on these pages, the app is sent to an URL like this: example.com/one/lang/en and example.com/one/{id}/lang/en respectively.
I implemented localizations on my project following this tutorial https://appdividend.com/2019/04/01/how-to-create-multilingual-website-using-laravel-localization/#Step_2_Creating_Translation_Files
You can simply define both routes.
Route::get('lang/{locale}', 'PagesController#locale');
Route::get('lang/{optional}/{locale}', 'PagesController#lang');
Then handle the optional variable with your controller methods.
public function locale($locale)
{
return $this->lang(null, $locale);
}
public function lang($optional, $locale)
{
// ... your logic
}
As for your link problem, you need to use an absolute path.
// relative path — https://yourdomain.com/current/path/lang/en
English
Serbian
// absolute path — https://yourdomain.com/lang/en
English
Serbian

How to load an index page without a controller

I have a question and apologies if it is too simple but I really couldn't figure it out. If I have my domain for example: www.shop.com. I changed .htaccess to omit the need for index.php. Now I am wondering how can I load for example a page (main home page) without having any controller in url address. E.g.:
www.shop.com =========> should land me on the home page of my site.
currently the only way I can do it is by defining a controller and doing this:
www.shop.com/controller/
Thanks and your help is much appreciated :)
Go to /application/config/routes.php
Add the default_controller rule like so
$route['default_controller'] = 'home';
So now in /application/controllers/home.php method index() will run on the index page.

How can integrate html template in codeigniter

I'm new to codeigniter. please tell me how can I integrate or install a html theme/template in codeigniter ? (my css folder path=news/css and application folder path=news/application where news is my main folder)
-thanks.
This is a very simple, very powerful way to do templates in codeigniter that is also very flexible.
http://news.dice.com/2013/02/18/how-to-build-a-to-do-app-with-codeigniter/
ignore the title, most of the lesson is about setting up templates in CI.
Note that i was first exposed to this method from a jeffrey way CI tutorial on net.tutsplus.com
All of them are worth checking out: http://net.tutsplus.com/sessions/codeigniter-from-scratch/
edit -- ok this is good enough addition to post. So in the tutorial, on the template.php page, you will see
$this->load->view($maincontent);
which is cool. but this is much better:
// load your header views
$templatefolder = 'beta/';
if(isset($content01))
$this->load->view($templatefolder.$content01);
if(isset($content02))
$this->load->view($templatefolder.$content02);
if(isset($content03))
$this->load->view($templatefolder.$content03);
// load your footer views
so instead of calling the view "maincontent", i've put in references to $content1, $content2, etc. Because we are doing if isset none of them are required. that way you can easily send more then one view file to the template. Or none at all if you are just showing a message, etc. Also notice that we have $templatefolder - that way you can easily reuse the template file for other site templates, even with the same content.
in your controller (similar to tutorial) it would be
$data['content01'] = 'codeigniterrawks';
$data['content02'] = 'mypetlion';
// beta template
$this->load->view( 'template_beta', $data );
note how easy it is if i want to bring in those same view files into a different template
$data['content01'] = 'codeigniterrawks';
$data['content02'] = 'mypetlion';
// alpha template
$this->load->view( 'template_alpha', $data );
I ran into this exact question about a week ago, this guide really helped me:
http://net.tutsplus.com/tutorials/php/an-introduction-to-views-templating-in-codeigniter/
To do the CSS url's, I added "uri" to my libraries in config/autoload.php (so it looks like this:
$autoload['libraries'] = array('uri', 'database');)
" type="text/css" media="screen" />
the base_url function automatically return whatever the base url of your site is, ie
http://localhost/news/
with the argument appended to the end.
The reason behind this is that if/when you ever need to migrate servers, you just change the base_url in the config file and it automatically updates across all of your templates and sources.
Try this,
I'm using this and it's very powerful.
https://github.com/philsturgeon/codeigniter-template

Change layout in controller depending on url

I have controller PlayerController and actions inside: View, Info, List.
So on urls "/Player/View" i get result with default Layout.
I want to get result with different Layout on request "/External/View".
How can i achieve this?
Although you can override the layout from the controller as has been suggested in another answer, in my opinion this means the controllers are getting just too involved in determining what the UI will be. Best to leave this purely to the Views to decide.
The closest to what you're asking is to do this in your current "~/Views/_ViewStart.cshtml":
#{
if(Context.Request.Path.StartsWith("/External", StringComparison.OrdinalIgnoreCase))
Layout = "~/Views/_ExternalLayout.cshtml";
else
Layout = "~/Views/_Layout.cshtml";
}
Where "~/Views/_ExternalLayout.cshtml" is your alternative layout.
Might want to check the leading "/" is correct on there, I can't remember if it is.
If you put this in the existing _ViewStart, then any view that is being rendering in response to a url starting with "/External" will use this new layout, otherwise the 'normal' one will be used.
Another approach is to use the routing table to add a route value that can be used here to make a layout decision; but I've gone for this approach to keep it simple.
You can specify which layout should be used when returning a view inside your 'ExternalController' controller action.
return View("View", "~/Views/Shared/_AnotherLayout.cshtml")

Resources