I have a site I am working on that has a URL structure that looks like:
example.com/category-name
This currently goes to a 1000 line long controller called pages that was built years ago and has never been changed. I am inserting a new controller above this in the route that looks like:
$route['(:any)'] = 'new_controller/load/$1
$route['default_controller'] = "pages";
The idea is for new_controller to work like this:
example.com/page-name
This looks up page-name in a database and displays some text made by business people in the admin of the site.
The problem comes from that if page-name is not found in this table, for legacy purposes I must fall through new_controller/load and then use the pages controller normally.
For SEO reasons I can't change the URL structure, it has to remain example.com/category-name and they want it to share the same URL structure example.com/page-name because it's shorter(I tried to convince them to do something like example.com/page/page-name)
From new_controller/load/$1 how would I then call say pages/view/$1 ?
Thanks in advance it is going to really save my butt at work haha
In your route config you can use the config below. new_controller controller handles all page requests so long as their uris don't contain pages/view/.* which pages controller handles.
$route['pages\/view\/(.*)'] = 'pages/view/$1';
$route['(?!pages\/view)(.*)'] = 'new_controller/load/$1';
In new_controller controller - you can do something like the code below so if the slug doesn't exist in database it will be handled by pages controller instead.
public function load($slug)
{
if(/*slug in database*/){
echo "Slug content from database";
}
else { // slug not in database
redirect(site_url('pages/view/'.$slug)); // You can use this
echo file_get_contents(site_url('pages/view/'.$slug)); // or this
$this->load->view('pages_template'); // or this
// or semething else.
}
}
Related
I'm relearning PHP and codeigniter but i can't help but notice how ugly my url looks.
So i have a pages controller: Say lets load homepage.
It would look like this:
public function home(){
$this->load->view('template/header');
$this->load->view('template/navbar');
$this->load->view('pages/home');
$this->load->view('template/footer');
}
I guess thats decent as my url will probably look like this:
http://localhost/ProjectName/index.php/pages/home
But whenever i click on a link that involves more data processing for example lets say my home has a list of users and i click on one to view their profile. I ofcourse have to pass something to identify which profile i am to load so my link would look like this:
http://localhost/OnlineStories/index.php/pages/view_userprofile/1
In my controller id have:
public function view_userprofile(){
$userid = $this->uri->segment(3);
//process data then load view
}
I'm not asking for any advanced stuff but i would like to ask simple things to improve my url like correct standard for naming my controller functions.
For example: on previous instances of loading my homepage my function name was view_home now its simply just home so its cleaner.
Maybe i could rename my view_userprofile to simply user_profile.
Anyway is there any better method to passing values from view to controller other than uri segment? its what ive been using so i never gave it much thought. I've seen some use get() but idk if its better than uri segment?
Or should i stick with the uri segment and keep my url as controller/method/parameter?
I haven't really explored post-project polishing in codeigniter so idk if theres a way to polish/change the url(just the name).
Talk about URL in CodeIgniter, you never mention about application/config/routes.php file. Have you seen it ..?
In routes.php file you can create your URL name and mapping it to the controller/function that you have
like this:
$route['user/update'] = 'user_controller/update_data_function'
so, you can call URL http://your.site/index.php/user/update to execute your update_data_function() in your User_controller.php
For organizational purposes I need to have subfolders in my views directory. For example for managing login / registration: views/login_reg/login.php and views/login_reg/register.php.
In my URI want to see: www.mysite.com/login or www.mysite.com/register instead of www.mysite.com/login_reg/login.
I have tried the following in routes:
$route['(:any)/login'] = 'login_reg/login';
Which does not work.
EDIT:
A simple example to elaborate further:
//Controller: login_reg.php
class Login_reg{
function login(){
$this->load->view('login_reg/login');
}
function register(){
$this->load->view('login_reg/register');
}
}
//Routes:
$route['login_reg/(:any)'] = 'login_reg/$1';
So my URI looks like this: www.mysite.com/login_reg/login, or www.mysite.com/login_reg/register
So I want one controller to manage all login / registration related views. But I do not want to see the controller name in the URI. Is this possible? Or is the best approach to have a controller for login, a controller for registration, a controller for password changing etc? This seems a bit excessive. I want to have my files well organised into related directories as this is part of a very large site.
Here you don't need routing at all.
Simply add your folder name while loading view.
For example your controller name for login is like
function login()
{
//code goes here
$this->load->view('login_reg/login');
}
and similar for register.
Hope this helps you.Feel free to let me know if you further queries.
--- Update ---
To hide controller name make chanes in route.php like this;
$route['login'] = 'login_reg/login';
$route['register'] = 'login_reg/register';
and your url will go like this now :
http://yourwebsite.com/login
I've just started to get into MVC with PHP and have had a good mess about with the likes of CodeIgniter and CakePHP. I'm interested to find out what people's approaches to the following would be:
Normally when I have built a website with a CMS in the past I have approached it by having a core URI table in my database. Each URI is unique and represents a page on my website (e.g. www.example.com/about would reference a record in my URI table with 'about' as the unique URI). The URI table also contains a 'type' column which tells the system what type of page it is (e.g. splash, basic, gallery or whatever). Each 'type' has a corresponding table in my database with all the data for records of that type in them (e.g. I would have tables: basic, gallery and splash). The type also tells the system which template/pagehandler to load which in turn does what it needs to do for each page type.
So if you go to www.example.com/about, my system looks in my URI table for a record with URI 'about', finds it's type to be 'basic' so it loads the basic template/pagehandler which uses the basic table in my database to load and render the page. In the CMS I follow a similar approach, I'll have add/edit forms for all of the different types in my page manager.
I was wondering how you would approach this using an MVC framework such as CodeIgniter? I essentially want to have different controllers for each type of page on both the front and back. However, when someone get's to my site, they will end up on a URI with a single level so I need to check the type of the page and pass off to the correct controller. Is there a way you would recommend of checking the type of each page and then loading the relevant controller to do the rest of the work?
My approach eventually was to extend the _parse_routes() method of the Router class to check the database for any records matching the current uri and set the request with the corresponding value from the database.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class MY_Router extends CI_Router {
function __construct() {
parent::__construct();
}
function _parse_routes() {
require_once( BASEPATH .'database/DB'. EXT );
$db =& DB();
$routes_table_exists = $db->query("SHOW TABLES LIKE 'routes';");
if ($routes_table_exists->num_rows > 0) {
$uri_routes = $db->get_where('routes', array('uri' => $this->uri->uri_string()));
if ($uri_routes->num_rows > 0) {
$row = $uri_routes->result()[0];
if (isset($row->request)) {
return $this->_set_request(explode('/', $row->request));
}
}
}
parent::_parse_routes();
}
}
Whether or not it's the best approach to take it seems to work so far.
Usually its a combination of Routes and naming your controllers. so for example you have an About page, and you don't need a separate About controller. Lets say you have a general Pages controller, and then a view($page) method to retrieve and show the page.
example.com/about
$route['about'] = "pages/view/about";
if you just have a few pages there are advantages to hard coding the routes - it protects your database. but otherwise taking an example from the tutorial
$route['default_controller'] = 'pages/view';
$route['(:any)'] = 'pages/view/$1';
this does the same thing but now it will take example.com/anything can go here
Versus something like a contact page - where you probably want to have a separate controller called Contact, because you will need to validate the contact form, add it to a database, email it, show a response, show the form again if did not validate, etc So then you can just do a simple link to show the contact form: example.com/contact
the contact form submits to: example.com/contact/submit
more about Routes
http://ellislab.com/codeigniter/user-guide/general/routing.html
and definitely look at the tutorial it will give you more examples about routes
http://ellislab.com/codeigniter/user-guide/tutorial/index.html
I think this is a route issue but I'm not sure. I have a page with this URL:
siteurl.com/kowmanger/titles/titles/edit/$id
I'm trying to find out that when I'm on this page I load the titles page it says page not found so I need to tell it that the $id is just a paramter so I can use it to get the data of the title.
UPDATE :
So I decided to change my titles controller so that there's a edit and add function inside of the titles controller that way they dont' have separate controllers when they are in fact methods.
So now I have:
kansasoutalwwrestling.com/kowmanager/titles/titles - list of titles
kansasoutalwwrestling.com/kowmanager/titles/titles/add - addnew form
kansasoutalwwrestling.com/kowmanager/titles/titles/edit/$id - edit form
I don't have any routes set up so far for this. For some reason though I"m getting the same page for both of these page.
kansasoutalwwrestling.com/kowmanager/titles/titles/add - addnew form
(right link url) kansasoutalwwrestling.com/kowmanager/titles/add -
addnew form
I need a route so that it'll show the correct url if the add method is accessed.
Also I need to set up a route so that if the correct edit link is accessed it sees the id attached to the end of the url and it'll accept it so that I can do a my database query to get the title data.
UPDATE: So to reiterate I have a module(subfolder) called titles. Inside of the module I have a controller called titles and inside of that controller I have 3 functions called index(), add(), edit().
I tried using Chris's suggestion on the routes but its not routing correctly. Also wanted to mention I'm using wiredesignz modular separation framework if that matters.
Any additional ideas?
Possible answer based on your post, not one hundred percent your entire structure but if i had to guess based off the post I would try this as my routes first..
$route['titles/titles/edit/(:any)'] = 'titles/titles/edit/$1';
$route['titles/titles/add'] = 'titles/titles/add';
$route['titles/titles'] = 'titles/titles';
$route['titles'] = 'titles/index';
Are you using custom routing in your configuration files ?
The general routing protocol used by codeigniter is like this:
domain.com/controller/methode/param1/param2/param3
This being said, your url
siteurl.com/kowmanger/titles/titles/edit/$id
corresponds to something like this :
class Kownmanger extends CI_Controller
{
public function titles($titles, $action, $id)
{
}
}
In case you are using sub-folders in your controllers folder, what I have just said will change, Could you please tell us what's your directory structure ?
I have a site that has a lot of pages that lye at the root (ex. /contact, /about, /home, /faq, /privacy, /tos, etc.). My question is should these all be separate controllers or one controller with many methods (ex. contact, about, index within a main.php controller )?
UPDATE:
I just realized that methods that are within the default controller don't show in the url without the default controller (ie. main/contact wont automatically route to /contact if main is the default controller ). So you would need to go into routes and override each page.
If all of these are just pages, I would recommend putting them into a single controller. I usually end up putting static pages like this into a 'pages' controller and putting in routes for each static page to bypass the '/pages' in my URLs.
If they are share the same functionality, so they should be in the same controller.
for example, if all of them are using the same model to take content from, so, one controller can easily handle it.
Why in one controller? because you always want to reuse your code.
class someController{
function cotact(){
print $this->getContentFromModel(1);
}
function about(){
print $this->getContentFromModel(2);
}
function home(){
print $this->getContentFromModel(3);
}
private function getContentFromModel($id){
return $this->someContentModel->getContentById($id);
}
}
(instead of print, you should use load a view)
See in my example how all of the function are using the same getContentFromModel function to share the same functionality.
but this is one case only, there could be ther cases that my example can be bad for...
in application/config/routes.php
$route['contact'] = "mainController/contact";
$route['about'] = "mainController/about";
$route['home'] = "mainController/home";
$route['faq'] = "mainController/faq";
$route['privacy'] = "mainController/privacy";
and you should add all of these methods within the mainController.php
You can also save the content of the pages in your database, and them query it. For instance, you can send the url as the keyword to identify the page content
$route['contact'] = "mainController/getContent/contact";
$route['about'] = "mainController/getContent/about";
$route['home'] = "mainController/getContent/home";
$route['faq'] = "mainController/getContent/faq";
$route['privacy'] = "mainController/getContent/privacy";
in this case you only have to create one method named "getContent" in the controller "mainController" and this method will look something like this:
class mainController extends CI_Controller
{
public function getContent($param)
{
$query = $this->db->get_where('mytable', array('pageName' => $param));
// then get the result and print it in a view
}
}
Hope this works for you
The page names you listed should probably be different methods inside your main controller. When you have other functionality that is related to another specific entity, like user, you can create another controller for the user entity and have different methods to display the user, update the user, register the user. But its all really a tool for you to organize your application in a way that makes sense for your domain and your domain model.
I've written a blog post about organizing CodeIgniter controller methods that might be helpful to you. Check it out here: http://caseyflynn.com/2011/10/26/codeigniter-php-framework-how-to-organize-controllers-to-achieve-dry-principles/