I have some controllers: Post, Pages, Authors. On each controller, I want to set the individual URL from the database. The structure of the database page: There will be thousands of records in the database.
how can this be implemented, take also indicate every URL will load from the database on the basis of slug. I stuck in this from last two day
Current Url structure is -
http://127.0.0.1/hmvc/post/post_details?id=1
I want urls something like this
http://127.0.0.1/hmvc/blog-post-1
Since you have the slugs already in your database I'm assuming that you already have the CRUD of that table done and you just want to interact with it.
First your controller and method:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Post extends CI_Controller {
public function post_details($slug)
{
$this->load->model('article_model', 'article');
$this->data['article'] = $this->article->get_by_slug($slug);
}
}
/* End of file post.php */
/* Location: ./application/controllers/post.php */
Then your model:
<?php
defined('BASEPATH') or exit('No direct script access allowed');
class Article_model extends CI_Model
{
public function get_by_slug($slug = null)
{
if (is_null($slug)) {
return array();
}
return $this->db->where('slug', $slug)
->get('posts')
->row();
}
}
/* End of file article_model.php */
/* Location: ./application/models/article_model.php */
Finally your routes should look like this:
$route['default_controller'] = 'dashboard';
$route['404_override'] = '';
$route['translate_uri_dashes'] = false;
$route['(:any)'] = 'post/post_details/$1';
Please check the following code by placing it at the bottom of your config/routes.php file.
What it does is, check if 'blog-post-' is present in the uri(not in querystring) part. If present, then explode it and check if the second part is a valid positive integer. If yes, then set the route rule for 'post/post_details/{NUMBER}' for the uri.
It will not break the routes rules for other controllers(Pages, Authors) by trying to redirect their hits to 'post' controller.
$uri = $_SERVER['REQUEST_URI'];
$check_part = 'blog-post-';
if (strpos($uri, $check_part) !== FALSE) {
$uri_parts = explode('blog-post-', $uri);
if (count($uri_parts) == 2) {
$id = intval($uri_parts[1]);
if ($id > 0) $route[ltrim($uri, '/')] = 'post/post_details/'.$id;
}
}
Related
I'm developing a web application and i'm slightly confused by routes and how they work.
My web application has an admin area and the URL structure is as follows;
example.com/admin/view/form/123
My Admin controller looks like this;
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Admin extends CI_Controller {
public function index()
{
$data = array(
'title' => 'Admin Page'
);
$this->load->view('admin/index', $data);
}
public function view() {
$form_submission_id = $this->uri->segment(4);
$records = $this->Admin_model->getDetails($form_submission_id);
$data = array(
'title' => 'Form Details',
'records' => $records
);
$this->load->view('admin/view/index', $data);
}
}
I don't have any custom routes setup.
When I visit the following URL, I can see the page and corresponding data successfully;
example.com/admin/view/form/123
But, when I change the /form/ URL segment to something random like below I can still see the correct data;
example.com/admin/view/foo/123
Why is this?
I was expecting to see a 404 page?
What do I need to change in order to achieve what I want?
Perhaps i'm misunderstanding the logic and should have my controllers / routes setup differently?
Codeigiter URL has a structure as domain/controllerName/actionName/param1/param2 and so on. In your code URL example.com/admin/view/form/123 admin is controller, view is action name and form and 123 is the parameters which you passed using get method. You can access these parameters like $this->uri->segment(3).
Thus in your code:
It will not show any error as your function is not even using 3rd URI segment.
It will not show 404 page as it found correct controller and action.
To achieve domain related functionality, you need to either change for function code accordingly or need to use routes for this.
Hope it helps you to clarify this code.
Rohit Mittal answer is good and also,
You can change the view fuction in admin controller like as:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Admin extends CI_Controller {
public function view($form = null,$form_submission_id = null) {
if($form == "form" && $form_submission_id){
$records = $this->Admin_model->getDetails($form_submission_id);
$data = array(
'title' => 'Form Details',
'records' => $records
);
$this->load->view('admin/view/index', $data);
}
}
Here is what I want to achieve:
https://www.example.com/properties
https://www.example.com/properties/properties-in-newyork
https://www.example.com/properties/properties-in-DC/property-for-rent
https://www.example.com/properties/all-cities/property-for-rent
https://www.example.com/properties/all-cities/property-for-sale
All above is for search. Now I want to get details page like:
https://www.example.com/properties/2br-apartment-for-sale-100
I want to differentiate between search and details page links. Here is what I tried:
$route['properties/index'] = 'properties';
$route['properties(/:any)'] = 'properties/property_details$1';
How can I differential which URL is for properties/property_details function and which URL is for properties/index function?
enter image description here
Set your route.php like this :
$route['properties/index'] = 'properties';
$route['properties'] = 'properties/property_details';
$route['properties/(:any)'] = 'properties/property_details/$1';
Access url :
this direct you index method
https://www.example.com/properties/index
this will direct you property_details method
https://www.example.com/properties/
Controller :
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Properties extends CI_Controller {
public function __construtct()
{
parent::__construtct();
$this->load->helper('url');
}
public function index()
{
echo 'index';
}
public function property_details($component = NULL)
{
echo 'property_details';
echo $component;
}
}
If I'm correct, according to your explanation with differentiating the routes, the problem you are having is, it always running the route for index despite of what your URL having after properties.
You may try it by changing the order of the routes like this;
$route['properties(/:any)'] = 'properties/property_details/$1';
$route['properties/index'] = 'properties';
It always works according to the order of the routes you have placed. If there are acceptable parameters, for the program, properties/index is also something similar to properties(/:any). So, to differentiate between these two, we have to change the order of the routes like this.
I am trying to send a url from view page to controller but it does not seem to work the way i am thinking.
View Page
Product
User
I want to get "tbl_product"
Controller admin
<?php
class Admin extends CI_Controller {
public function test() {
echo $this->uri->segment(4);
}
}
?>
but if the segment(4) is changed to segment(3), it shows up with displaying "product" in the screen
your controller function should have arguments for your url segments
for example:
public function test($product = 'product', $tbl = 'tbl_product') {
echo $tbl // contains the string tbl_product
}
Since you said your routes look like this:
$route['default_controller'] = "admin";
$route['404_override'] = ''
and your URL is like this:
<?= base_url() ?>admin/test/product/tbl_product
Then if your base_url() is localhost/my_app, your URL will be read as this:
http://localhost/my_app/admin/test/product/tbl_product
http://localhost/my_app/CONTROLLER/METHOD/PARAMETER/PARAMETER
So in your controller, you can do this:
class Admin extends CI_Controller {
public function test($product = NULL, $tbl_product = NULL) {
echo $product;
echo $tbl_product;
}
}
It's strange to use codeigniter for this purpose, because codeigniter uses as default the url format bellow.
"[base_url]/[controller]/[method]"
I think it will be better and more easy to just pass the values you want as get parameters and make some httaccess rules to make your url more readable for the user and robots. That said you can do that:
Product
<?php
class Admin extends CI_Controller {
public function test() {
echo $this->input->get('product');
//should output 'tbl_product'
}
}
?>
If you prefer to use uri instead u should route your uri's so it will be like.
In your routes file you probably I'll need something like this.
$route['product/(:any)'] = "Admin/test";
This way you will probably access the uri segments correctly.
Thank you so much for going through.
$this->uri->segment(4); // is now working :S
its not working properly after all I made changes to routes.php and came back to default again. I seriously have no idea what the reason behind not displaying the result before.
Edit: I am new Codeigniter I am not how to use Codeigniter Routing. I create Contact Us page and Map page. Map page is the subpage of Contact Us page.
Table Name : Pages
id label link parent
1 Contact Us contact-us 0
3 About Us about-us 0
2 Map map 1
Here my Controller
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Page extends CI_Controller {
public function __construct()
{
parent::__construct();
$this->load->helper('url');
$this->load->model('page_model');
}
public function index()
{
$data['getAllPage'] = $this->page_model->getAllPages();
$this->load->view('page_listing',$data);
}
public function view($id) {
$data['single_page'] = $this->page_model->displaySinglePage($id);
$this->load->view('single_page',$data);
}
}
In routes.php I have put $route['(:any)'] = "page/view/$1";
When I enter url "http://mytest.dev/contact-us/" or "http://mytest.dev/about-us/" it show correct content of Contact page but I enter "http://mytest.dev/contact-us/map" it still show content of Contact page.
What I want when I enter "http://mytest.dev/contact-us/map" it shuold show content of Map page
Thanks in advance.
Please try code maybe can help
// Parents and Child page.
$route['page/(:any)/(:num)'] = "page/view/$1/$2";
// For Main Home Page.
$route['(:any)'] = "page/view/$1";
I think following routes should work
$route['contact-us'] = 'page/view/$1';
$route['contact-us/map'] = 'page/view/$2';
when you'll echo $id in view method.
"http://mytest.dev/contact-us/" will print $1
and
"http://mytest.dev/contact-us/map" will print $2
Hope this solution will help.
My site has a main 'events' page and an 'events/calendar' page. Create the pages as separate views and then create a function for each sub page in the main controller. Here's my Events controller. If you want a dynamic page you can add the appropriate code in the function.
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Events extends CI_Controller {
public function index()
{
$this->load->view('inc/header.php');
$this->load->view('events_view');
$this->load->view('inc/footer.php');
}
public function calendar()
{
$this->load->view('inc/header.php');
$this->load->view('calendar_view');
$this->load->view('inc/footer.php');
}
}
I have tried to integrate codeigniter and wordpress in my system and it does. By putting the wordpress in my codeigniter root seems to be working but adjustments has been made in the config, index and route.php. I can use wp functions now in my codeigniter view file, however, there is a problem occur. Whenever I access other functions in my controller, it redirects to the index function of the controller. What is the problem with this? Is there a conflict between wp and ci url with this or there could be other reason? If there is, how could I solve this one? Here are my codes. Thanks for the help.
Config.php
from: $config['index_page'] = 'index.php'; to $config['index_page'] = '';
routes.php
the default routing works fine
from: $route['default_controller'] = "welcome";
$route['404_override'] = '';
any of the options below results to the problem indicated above
to: 3 routing options
option 1:
# Option 1 - Use this section for a normal CI site
# with WP in its own folder
$route['default_controller'] = "ci_pages";
$route['(:any)'] = "wp_pages/$1";
$route['(:any)'] = "ci_pages/$1";
$route['404_override'] = '';
option 2:
# Option 2 - Use this section for a blended CI/WP site
# with selected WP pages routed to eppear in the web root
# Any WP route outside the WP folder must be set up as a CI route.
$route['default_controller'] = "ci_pages";
$route['(:any)'] = "ci_pages/$1";
$route['sample-page'] = "wp_pages/$1";
$route['404_override'] = '';
option 3:
# Option 3 - Use this section for a CI site where WP is only
# for content management and does not display its own pages
# through CI routing.
$route['default_controller'] = "ci_pages";
$route['(:any)'] = "ci_pages/$1";
$route['404_override'] = '';
controller: ci_pages.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class CI_Pages extends CI_Controller
{
public function index()
{
$this->load->view('home');
}
public function test()
{
$this->load->view('test');
}
}
?>
I think your second option should work i think you need to do like following :
In the route.php
$route['default_controller'] = "ci_pages";
$route['(:any)'] = "ci_pages/index/$1";
$route['sample-page'] = "wp_pages/$1";
$route['404_override'] = '';
controller: ci_pages.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class CI_Pages extends CI_Controller
{
public function index()
{
$this->load->helper('url');
$array_segments = $this->uri->segment_array();
if( isset( $array_segments[1] ) ) {
$function_name = $array_segments[1];
$this->{$function_name}();
}
}
public function home()
{
$this->load->view('home');
}
public function test()
{
$this->load->view('test');
}
}
?>
Hope this may work for you I haven't tested it. But the idea here is you need to route to your functions from index function only
Take a look at your config file
config.php
and change this uri_protocol line FROM:
$config['uri_protocol'] = 'QUERY_STRING';
TO this:
$config['uri_protocol'] = 'REQUEST_URI';