creating dynamic page URLs with CI (routing) - a simple message board example - php

I feel like I have enough experience with CI to finally start fooling around with creating a message board... Or at least thats what I thought, until I got stuck at generating dynamic pages based on subject names (slugs).
So, I creating the controller/model/views and set up a form that submits the necessary info to the database. I pulled the threads out and display them, and generate a link for each one based on the subject title...i essentially followed the CI tutorial, editing it to suit my needs.
However, understanding the concept of generating dynamic page URLs is throwing me off. I understand a lot better by hearing exactly whats happening during the process, and the codeigniter tutorial (news) doesnt explain it well. It simply tells you what to do and how, and not why.
Anyone out there feel up to attempting to explain in greater detail, the process to code dynamic pages.
What I mean by dynamic pages is :
http://your-site.com/news/1/hello-world
http://your-site.com/news/1/foo-bar
where hello world and foo bar.
Here are some parts that confuse me:
<?php
class Pages extends CI_Controller {
public function view($page = 'home')
{
}
}
And heres the routing
$route['default_controller'] = 'pages/view';
$route['(:any)'] = 'pages/view/$1';
what does $1 represent? Any specific url that there? When would you use $2? Is it built in code to CI, or can you use any variable?
I'm sure the answer can get more detailed, but If someone could answer some of the above questions, i'm sure it'd be very helpful.
With those questions answered, in theory, what should be done to produce a new page for a forum thread?
Thanks!

what does $1 represent? Any specific url that there? When would you
use $2? Is it built in code to CI, or can you use any variable?
$1 represents a reference to the variable created by the wildcard (:any). There is no $2, because you only have one wildcard.
You would have a second wildcard if you created a route like this:
$route['pages/(:num)/(:any)'] = 'pages/$1/$2';
With that said, the route setup within your question kind of defeats the purpose of CI's MVC architecture and route system, as you're redirecting ALL routes to pages/views, I'm fairly sure you want something like:
$route['default_controller'] = 'pages/view';
$route['pages/view/(:any)'] = 'pages/view/$1';

<?php
class Pages extends CI_Controller {
public function view($page = 'home')
{
}
}
The corresponding url for this method would be http://example.com/pages/view/. In the method it is set to $page = 'home' because if there is no third segment in the url, it will default to home.
$route['(:any)'] = 'pages/view/$1';
The variable $1 is whatever you have as your (:any). So if you url is http://example.com/testing, it would route to http://example.com/pages/view/testing and that would in turn set your $page var from your view method to "testing".

Related

Mixing of static and dynamic pages in CodeIgniter

I'm trying to mix static and dynamic content in a CodeIgniter 3.1 tailored website. I'm using the tutorial example given for the static content:
$route['default_controller'] = 'pages/view';
$route['(:any)'] = 'pages/view/$1';
I'm afraid this would be quite messy for the purpose, since (:any) is too generic and I don't want to use something like "/static/(:any)" route.
Any suggestions on how to achieve a solution that let me have a static and controller named friendly URL?
Every idea is welcome and very much appreciated.
As my question seems to be difficult to understand, I'll try to ask it once again:
Is there a way to combine static content with the above code (from codeigniter tutorial) and the usual approach http://example.com/controller/index_named_method dynamic content handling?
Can you give an example?
Should I change $route['(:any)'] for every static webpage's name i.e.:
$route['(home|contact|links)'] ?
Thanks in advance
Well, I must say that I got to an answer myself; as said in my previous post editing, mixing static and dynamic content using index() method in your Controller taking advantage of the tutorial example can be accomplished adding a route with all your controllers name like this:
$route['(books|flowers|links)'] = '$1';
Thanks to those who helped.

CodeIgniter - Stuck with routes

I am trying out CodeIgniter 2.1.4. I already have a controller for showing static pages which I built using the tutorial in CodeIgnitor documentation. I later set-up my routes like this:
// <http://localhost/> refers to <http://localhost/pages/view/>
$route['default_controller'] = "pages/view";
// <http://localhost/somepage/> refers to <http://localhost/pages/view/somepage/>
$route['(:any)'] = "pages/view/$1";
// .htaccess is already setup to rewrite the url without index.php
Now, I don't have much experience with PHP, and the concepts of URL Rewriting and MVC Architecture are fairly new to me.
Let's say there's are pages called •Home, •About, •Admin and •Contact.
For the pages •Home, •About and •Contact, the Pages controller works right as it should.
But for •Admin page, I want to have a separate controller which determines whether the user has logged in or not, and whether he has admin rights etc. And if he hasn't logged in yet, I should load the Login view instead of the Admin view.
The Pages controller has a fairly simple logic. It checks whether the string in argument, appended with .php and prepended with the views directory, exists as a file or not. If it doesn't show_404(), if it does, load view header-template, then load the page, then load view footer-templat. I'm pretty sure most of you who have worked with CodeIgniter must've seen a similar logic for static pages.
I could do redirect('login') inside my Admin view, but that doesn't seem to work. If I create a separate controller for Admin, how would I access it, while according to routes, every URL gets directed to pages/view controller (line#4 in the above code).
As I've already said, I'm fairly new to this. It might be some retarded mistake that I'm making. Or my whole MVC structure might be inappropriately built. How do I get past this and start worrying about the authentication stuff? Can anyone advise?
$route['default_controller'] = "pages/view";
$route['admin/(:any)'] = "admin/$1"; //(admin controller) with "any" method
$route['(:any)'] = "pages/view/$1";
localhost/poject/admin/edit as example
The problem you are experiencing is simple, you overwrite all controllers by that (:any) it isn't wrong but you need to manualy assign each controller that you want route as normal controller as I posted above.
please note that routes are order dependant and if one (first) is used second one is ignored. "Routes will run in the order they are defined. Higher routes will always take precedence over lower ones."
For authentification please see this post.
I would rather use _remap() and extend CI_Controller to take over my routes instead of having this route $route['(:any)'] = "pages/view/$1"; in routes.php.
remapping

create a dynamic url in codeigniter like facebook

I need to create a dynamic url in codeigniter like the facebook application. Is it possible to create such url using the codeigniter framework?
eg:
1. www.facebook.com/nisha
2. www.facebook.com/dev
You need to set up custom routing for the controller in application/config/routes.php. Like:
$route['([a-zA-Z]+)'] = "controller_name/function/$1";
This makes urls like the way you want, but it makes all of your controller inaccessible, that is because any '/controllername/parameter/' format will match with '(:any)' and will be redirected to our 'controller_name/function/'.
To stop controllers redirected by the CI router, you will have to explicitly define all of your controllers on the routes.php first then add the above mentioned routing rule at last line. Thats how i made it to work.
Hope that helps you in some way.
Its pretty easy to setup this by the use of routes. Read their routing guide
$route['([a-zA-Z]+)'] = "controller/user/$1";
However, if their is only one way of accessing the website, is like domain.com/username then its ok, otherwise, this will prove be a hard catch on the long run. On that case, limit the Route to a limited scope like
$route['users/([a-zA-Z]+)'] = "controller/user/$1";
This will help in the extending the system in numerous way
Try this way. it will reduce a lot of repetitive line if you have lots of controller but i don't know does it violate any CI rules.
//this code block should be placed after any kind of reserved routes config
$url_parts = explode('/',strtolower( $_SERVER['REQUEST_URI']) );
$reserved_routes = array("controller_1", "controller_2", "controller_3" );
if (!in_array($url_parts[1], $reserved_routes)) {
$route['([a-zA-Z0-9_-]+)'] = "controller_1/profile/$1";
}

Routing with CodeIgniter, getting 404 with correct $routes

Using CodeIgniter, I am getting a strange behaviour in my code. What I want is to have a sort of person listing in my database and when I type the id of a given person, a page appears with all the informations we’ve got about this person in the database.
Just a simple thing. I succeeded with the news official tutorial thing and it doesn’t work at all with this !
I wrote a controller inherited class which is named Person, with a viewPersonById method, just like that :
class Person extends CI_Controller{
public function __construct()
{
parent::__construct();
$this->load->model('Person_Model');
}
public function index()
{
}
public function viewPersonById($parId){
$data['person'] = $this->Person_Model->get($parId);
$data['title'] = 'Person information';
$this->load->view('templates/header', $data);
$this->load->view('people/view', $data);
$this->load->view('templates/footer');
}
My routes.php is written like this :
$route['people/(:any)'] = 'Person/viewPersonById/$1';
$route['news/create'] = 'news/create';
$route['news/modify/(:any)'] = 'news/modify/$1';
$route['news/(:any)'] = 'news/view/$1';
$route['news'] = 'news';
$route['(:any)'] = 'pages/view/$1';
$route['default_controller'] = 'pages/view';
And all that I get is a 404 when I enter http://127.0.0.1:8888/ci/index.php/people/1 in my browser. What is wrong in my code ? I can’t see it.
Any ideas ? Thanks and sorry for my poor english.
EDIT :
Ok guys, I found out what was wrong. I feel like the biggest jackass ever because the name of my files were weird like "person.controler.php" and "person.model.php". The name of your controller and what you put in routes.php have to match exactly.
So I just had to rename person.controler.php to person.php and person.model.php to person_model.php so the model can be loaded within the controler. CI uses the names of the files to see what it has to load. Be careful with that.
If your controller filename if person.php, then you should change:
$route['people/(:any)'] = 'Person/viewPersonById/$1';
to
$route['people/(:any)'] = 'person/viewPersonById/$1';
lowercase p in person.
PS: Try to open http://127.0.0.1:8888/ci/index.php/Person/viewPersonById/1, you'll know the issue
Sounds to me like your .htaccess isn't set up or being read.
Not all default server configurations will go up the path until they find your index.php script.
Not directly related, but you should have a look at the CodeIgniter Style Guide
Method names should be lowercased and words separated by underscores ('_'). You might not like it and find it a pain in the -you know where-, but trust me sticking with the standards is always the best idea, plus it looks nice and consistent with third party libraries/plugins/helpers.
Plus you don't want to have to custom route every method of every controller. And you also don't want uppercase characters in your urls

Routes in Codeigniter - Automatically

I have a problem with Codeigniter routes. I would like to all registered users on my site gets its own "directory", for example: www.example.com/username1, www.example.com/username2. This "directory" should map to the controller "polica", method "ogled", parameter "username1".
If I do like this, then each controller is mapped to this route: "polica/ogled/parameter". It's not OK:
$route["(:any)"] = "polica/ogled/$1";
This works, but I have always manually entered info in routes.php:
$route["username1"] = "polica/ogled/username1";
How do I do so that this will be automated?
UPDATE:
For example, I have controller with name ads. For example, if you go to www.example.com/ads/
there will be listed ads. If you are go to www.example.com/username1 there are listed ads by user username1. There is also controller user, profile, latest,...
My Current routes.php:
$route['oglasi'] = 'oglasi';
$route['(:any)'] = "polica/ogled/$1"
$route['default_controller'] = 'domov';
$route['404_override'] = '';
I solved problem with this code:
$route['oglasi/(:any)'] = 'oglasi/$1';
$route['(:any)'] = "polica/ogled/$1"
$route['default_controller'] = 'domov';
$route['404_override'] = '';
Regards, Mario
The problem with your route is that by using :any you match, actually...ANY route, so you're pretty much stuck there.
I think you might have two solutions:
1)You can selectively re-route all your sites controller individually, like:
$route['aboutus'] = "aboutus";
$route['where-we-are'] = "whereweare";
//And do this for all your site's controllers
//Finally:
$route['(:any)'] = "polica/ogled/$1";
All these routes must come BEFORE the ANY, since they are read in the order they are presented, and if you place the :any at the beginning it will happily skip all the rest.
EDIT after comment:
What I mean is, if you're going to match against ANY segment, this means that you cannot use any controller at all (which is, by default, the first URI segment), since the router will always re-route you using your defined law.
In order to allow CI to execute other controllers (whatever they are, I just used some common web pages, but can be literally everything), you need to allow them by excluding them from the re-routing. And you can achieve this by placing them before your ANY rule, so that everytime CI passed through your routing rules it parses first the one you "escaped", and ONLY if they don't match anything it found on the URL, it passes on to the :ANY rule.
I know that this is a code verbosity nonetheless, but they'll surely be less than 6K as you said.
Since I don't know the actual structure of your URLs and of your web application, it's the only solution that comes to my mind. If you provide further information, such as how are shaped the regular urls of your app, then I can update my answer
/end edit
This is not much a pratical solution, because it will require a lot of code, but if you want a design like that it's the only way that comes to my mind.
Also, consider you can use regexes as the $route index, but I don't think it can work here, as your usernames are unlikely matchable in this fashion, but I just wanted to point out the possibility.
OR
2) You can change your design pattern slightly, and assign another route to usernames, something along the line of
$route['user/(:any)'] = "polica/ogled/$1";
This will generate quite pretty (and semantic) URLs nonetheless, and will avoid all the hassle of escaping the other routes.
view this:
http://www.web-and-development.com/codeigniter-minimize-url-and-remove-index-php/
which includes remove index.php/remove 1st url segment/remove 2st url sigment/routing automatically.it will very helpful for you.
I was struggling with this same problem very recently. I created something that worked for me this way:
Define a "redirect" controller with a remap method. This will allow you to gather the requests sent to the contoller with any proceeding variable string into one function. So if a request is made to http://yoursite/jeff/ or http://yoursite/jamie it won't hit those methods but instead hit http://yoursite/ remap function. (even if those methods/names don't exist and even if you have an index function, it supersedes it). In the _Remap method you could define a conditional switch which then works with the rest of your code re-directing the user any way you want.
You should then define this re-direct controller as the default one and set up your routes like so:
$route['(.*)'] = "redirect/index/$1";
$route['default_controller'] = "redirect";
This is at first a bit of a problem because this will basically force everything to be re-directed to this controller no matter what and ultimately through this _remap switch.
But what you could do is define the rules/routes that you don't want to abide to this condition above those route statements.
i.e
$route['myroute'] = "myroute";
$route['(.*)'] = "redirect/index/$1";
$route['default_controller'] = "redirect";
I found that this produces a nice system where I can have as many variable users as are defined where I'm able to redirect them easily based on what they stand for through one controller.
Another way would be declaring an array with your intenal controllers and redirect everything else to the user controller like this in your routes.php file from codeigniter:
$controllers=array('admin', 'user', 'blog', 'api');
if(array_search($this->uri->segment(1), $controllers)){
$route['.*'] = "polica/ogled/$1";
}

Categories