I want to show single blog news by slug but I do not know
Blog Controller :
public function show_news($slug)
{
$page_data['page_title'] = 'News';
$page_data['news_item'] = $this->blog_model->get_news($slug);
$this->template->load('frontend/blog_news',$page_data);
}
Blog Model :
function get_news($slug)
{
$slugs = urldecode($slug);
$query = $this->db->get_where('blogposts', array('slug' => $slugs));
if($query->num_rows() > 0 ){
if($this->db->get_Where('blogposts', array('slug'=>$slugs))->row()->status == '1'){
return $query->row_array();
}
}
}
my route :
$route['blog/(:any)/news/(:any)'] = "blog/show_news/$1/$2";
you have only one parameter($slug) with show_news function so obviously the route "blog/show_news/$1/$2"; will be incorrect.Manage your route like this..
$route['blog/news/(:any)'] = "blog/show_news/$1";
It redirects every blog/show_news/slug to blog/news/slug
In your controller, you have only 1 parameter. This is not ok with your route configuration. It should be
$route['blog/news/(:any)'] = "blog/show_news/$1"; as already said.
But, your question title is
Codeigniter - routes multiple parameters
If you mean that you want to pass another parameter, than, with your current route, you can access the $2 variable by adding a second parameter to the method of your controller like this.
public function show_news($slug, $secondParameter){
Related
I began writing a webapp in Codigniter 4 and currently, i'm stuck with the pagination.
I created a controller, a model an a view to retrieve database entries für usergroups and used CI's built-in pagination-library.
UsergroupsModel:
<?php namespace App\Models;
use CodeIgniter\Model;
class UsergroupsModel extends Model{
protected $table = 'roles';
protected $allowedFields = [];
protected $beforeInsert = ['beforeInsert'];
protected $beforeUpdate = ['beforeUpdate'];
public function getGroups(){
$db = \Config\Database::connect();
$builder = $db->table('roles');
$query = $builder->get();
$results = $query->getResultArray();
return $results;
}
}
Controller (Usergroups):
<?php namespace App\Controllers;
use App\Models\UsergroupsModel;
class Usergroups extends BaseController
{
public function index()
{
//Helper laden
helper(['form','template','userrights']);
$data = [];
$data['template'] = get_template();
$data['info'] = [
"active" => "menu_dash",
"title" => "Dashboard",
"icon" => "fab fa-fort-awesome fa-lg",
"sub" => "Frontend",
];
//Check Permissions
$data['userrights'] = get_userrights(session()->get('id'));
if($data['userrights'][1] == 1)
{
foreach($data['userrights'] as $key => $value){
$data['userrights'][$key] = '1';
}
}
else
{
$data['userrights'] = $data['userrights'];
}
$model = new UsergroupsModel;
$model->getGroups();
$pager = \Config\Services::pager();
$data['usergroups'] = $model->paginate(5);
$data['pager'] = $model->pager;
//Create Views
echo view($data['template'].'/templates/header', $data);
echo view($data['template'].'/backend/navigation');
echo view($data['template'].'/templates/sidebar');
echo view($data['template'].'/backend/usergroups');
echo view($data['template'].'/templates/footer');
}
//--------------------------------------------------------------------
}
In the view, i got my pagination by using
<?= $pager->links() ?>
The default pagination works fine, but i get an URI like https://DOMAIN.DE/usergroups?page=2
In the official Codeigniter 4 docs for the pagination, you can find the following:
Specifying the URI Segment for Page
It is also possible to use a URI segment for the page number, instead of the page query parameter. >Simply specify the segment number to use as the fourth argument. URIs generated by the pager would then >look like https://domain.tld/model/[pageNumber] instead of https://domain.tld/model?page=[pageNumber].:
::
$users = $userModel->paginate(10, ‘group1’, null, 3);
Please note: $segment value cannot be greater than the number of URI segments plus 1.
So in my controller i changed
$data['usergroups'] = $model->paginate(5);
to
$data['usergroups'] = $model->paginate(5,'test',0,2);
and in the view i added 'test' as a parameter.
<?= $pager->links('test') ?>
In the Routes i added
$routes->get('usergroups/(:num)', 'Usergroups::index/$1');
and in the Controller i changed the index-function to
public function index($segment = null)
The URIs generated from the pagination now look like this:
https://DOMAIN.DE/usergroups/2
but it does not change anything in the entries and the pagination itself alway sticks to page 1.
I think, i can not use CI's built in library when switching to segment-URIs and thus i need to create a manual pagination.
Can somebody help me to fix this problem?
I currently had the same problem using segments in my pagination.
After much research I discovered that when you use segments associated with a group name in your case "test" you must assign the segment to the variable $ pager
$pager->setSegment(2, 'nameOfGroup');
You only need to change the first parameter with the segment number that you are using and the second with the name of the group that you are assigning.
It seems like there's a bug in Version 4.0.3. so it can't work out of the box. But i found a way to solve it:
The index-function needs to look like this:
public function index($page = 1)
and
within the Controller, the $data['usergroups'] need to look like this:
$data['usergroups'] = $model->paginate(5, 'test', $page, 2);
with 2 being the segment of the page-number in the URI.
Works like a charm.
I have a blog page of posts that I am trying to paginate using CodeIgniter. The numbering and limiting seem to be working fine, except I keep getting a 404 when I try to travel to another page.
The strange thing is the normal culprits that cause this issue are correct. The baseUrl and the uri_segment.
My controller looks like this:
$config = array();
$config["base_url"] = $this->config->site_url("/blog");
$config["total_rows"] = $this->blog_model->count();
$config["per_page"] = 2;
$config["uri_segment"] = 2;
$config["num_links"] = round($config["total_rows"] / $config["per_page"]);
$config['use_page_numbers'] = TRUE;
$this->pagination->initialize($config);
$page = ($this->uri->segment(2)) ? $this->uri->segment(2) : 0;
$this->load->view('blog', array(
'user' => $this->user,
'blog' => $this->blog_model->loadPosts($config['per_page'], $page),
'links' => $this->pagination->create_links(),
'footer' => $this->blog_model->loadFooter()
));
And then in my model I am grabbing the posts
public function loadPosts($limit, $start)
{
$this->db->limit($limit, $start);
$this->db->order_by("date", "desc");
//this loads the contact info
$query = $this->db->get('entries');
return $query->result();
}
My full URL is www.mysite.com/blog and then with the pagination it appears as www.mysite.com/blog/2.
For the base_Url I have also tried base_url() . "/blog";.
And I have tried setting the uri_segment to 1 and 3, but nothing seems to work.
As well I have tried playing around with the routing and have added just to see if it would do anything:
$route['blog/(:num)'] = 'blog/$1';
You can use this line of code if your code is inside the index method:
$route['blog/:any'] = "blog/index/$1";
Because you have used the segment(2), and you should change the blog/index/$1 to blog/:any.
Assuming the function name that contain your pagination code is index(), you should change the route to:
$route['blog/(:num)'] = 'blog/index/$1';
And in your index() function, add the $page parameter:
public function index($page = 1){
...
With your routes, try if you can to add as many :anys or :nums after as you like:
$route['blog'] = 'blog/index'; // For the first level
$route['blog/(:any)/(:any)'] = 'blog/index/$1/$2'; // For extra "uri" segments.
// base_url pagination
$config["base_url"] = base_url("blog"); // Is preferred
You can keep your other code as it is. Just add this at your routes.php file:
$route['blog/:num'] = "blog/index";
//Assumes your code is inside the index method.
//If not, use this way:
//$route['blog/:num'] = "blog/YOUR_METHOD_NAME";
You can't pass a parameter to the index() function of a controller like it is a random function.
If you try to do controller/var instead of controller/function/var, CodeIgniter will search for a function var() inside the controller which does not exists. That's what happen when you try to access blog/2: 2() isn't a function in your controller.
You can create a new function in your controller, let's say page(), and move your code inside. That way, you will call blog/page/2. Function page() will exists and will not get a 404. Also don't fordet to redefine your base_url for pagination.
$config["base_url"] = site_url("blog/page");
Another solution if you absolutely need the URL like /blog/2, routes:
$route['blog/(:any)'] = 'blog/index/$1';
Remap may also be a solution: http://www.codeigniter.com/user_guide/general/controllers.html#remapping
I understand that when you do this in Laravel:
Route::get('news/read/{year}/{month}/{date}/{title}/{id}', 'PageController#index_page');
We can use all {var} name as parameters in the controller. But how if I only want to use {id} and {title} instead of all of them in the controller?
This is currently my controller:
public function index_page($year=null, $month=date, $date=null, $title=null, $id=null) {
$plugin_files = $this->addJqueryPlugin(array('unslider'));
$data['css_files'] = $this->addCSS(array('styles'));
$data['js_files'] = $this->addJS(array('main'), false);
$data['css_plugin'] = $plugin_files['css_files'];
$data['js_plugin'] = $plugin_files['js_files'];
if (is_null($id)) {
$data['title'] = 'Homepage';
$this->layout->content = View::make('page.home', $data);
}
else {
$data['isModal'] = true;
$data['title'] = ucwords(str_replace("-", " ", $title . '--' . $id));
$this->layout->content = View::make('page.home', $data);
}
}
I tried putting only $title and $id but it reads from {year} and {month} instead. Only solution I can think of is change the order of the route to news/read/{title}/{id}/{year}/{month}/{date}, but I'm trying to keep the format like the previous one, is it possible?
Firstly, this seems wrong
public function index_page($year=null, $month=date, $date=null, $title=null, $id=null)
Remember that the order of default parameters must be as last parameters of function - check PHP Manual example here for details. I assume you misspelled $month=date for $month='some_default_date_value' ?
Second, answering your questions, you've got at least 2 options here:
A. routing to different methods for different parameter count or order
//Routes
//different routes for different params
Route::get('news/read/{year}/{month}/{date}/{title}/{id}', 'PageController#indexFull');
Route::get('news/read-id/{id}/{title}', 'PageController#indexByIdAndTitle');
Route::get('news/read-some-more/{month}/{date}/{id}/{title}/{year}', 'PageController#indexByWeirdParamsOrder');
//Controller
//different methods for different routes
public function indexByIdAndTitle($id, $title){ return $this->indexFull($id,$title); }
public function indexFull($id, $title, $year=null, $month=null, $date=null) { ... }
public function indexByWeirdParamsOrder($month, $date, $id, $title, $year) { ... }
B. changing the parameters order in route and using optional param / default value
//Routes
Route::get('news/read/{id}/{title}/{year?}/{month?}/{date?}', 'PageController#indexFull');
//Controller
public function indexFull($id, $title, $year=null, $month=null, $date=null) { ... }
Last but not least, check the Laravel docs for routing and parameters.
I am starting to learn codeigniters active record and i am querying my database using parameters passed from the controller to the model.
First i am passing the id from the controller to the model and that works.
Controller
function bret($id){
$this->load->model('school_model');
$data = $this->school_model->get_city_and_population($id);
foreach ($data as $row)
{
echo "<b>Name Of The City</b>...........". $row['Name'];
echo "<br/>";
echo "<b>Total Population</b>...........".$row['Population'];
}
}
Model
function get_city_and_population($id){
$this->db->select('Name,Population');
$query = $this->db->get_where('city', array('ID'=>$id));
return $query->result_array();
}
I went ahead and put in multiple parameters expecting to fail but this works but i am not so sure why it worked or what worked.
Controller
public function parameters($id,$name,$district){
$this->load->model('school_model');
$data = $this->school_model->multiple_parameters($id,$name,$district);
foreach ($data as $row)
{
echo "<b>Total Population</b>...........".$row['Population'];
}
}
Model
function multiple_parameters($id,$name,$district){
$this->db->select('Population');
$query = $this->db->get_where('city', array('ID'=>$id,'Name'=>$name,'District'=>$district));
return $query->result_array();
}
In my multiple parameters example i visited http://example.com/env/at/index.php/frontpage/parameters/7/Haag/Zuid-Holland/
Here,i know the name Haag is in id 7 and the district is Zuid-Holland
Here are my questions.How does codeigniter know how to pass the parameters from the url to the model and secondly,what if i was slightly wrong like 7/Haag/Zuid-Hollandes/,how would i show the user that,that url is wrong and fallback to a default value instead of showing blank when the parameters are wrong?.
//In codeiginter URI contains more then two segments they will be passed to your function as parameters.
//if Url: http://example.com/env/at/index.php/frontpage/parameters/7/Haag/Zuid-Holland/
//Controller: forntpage
public function parameters($id,$name,$district){
echo $id.'-'$name.'-'.$district;
}
//and if you are manually getting url from segment & want to set default value instead of blank then use following:
public function parameters(
$this->load->helper("helper");
$variable=$this->uri->segment(segment_no,default value);
//$id=$this->uri->segment(3,0);
}
//or
//Controller: forntpage
public function parameters($id='defaultvalue',$name='defaultvalue',$district='defaultvalue'){
echo $id.'-'$name.'-'.$district;
}
That's just simple uri mapping in CI, or uri param binding if you will.
When you have a method like:
public function something($param1, $param2) {
// get from: controller/something/first-param/second-param
}
That means your uri segments are passed as arguments to your controller method.
The above method could be written as:
public function something() {
$param1 = $this->uri->segment(3);
$param2 = $this->uri->segment(4);
// segment 1 is the controller, segment 2 is the action/method.
}
You need to understand that you have to manually check if the uri segments are exactly what you want them to be, as CI doesn't do anything else than this mapping.
Next, if you want to have some defaults, following statement is true:
public function something($param1 = 'some default value', $param2 = 'other value') {
// get from: controller/something/first-param/second-param
}
That is, if a url like: /controller/something is passed along, you will still get your default values back. When controller/something/test is passed, your first param is overridden by the one from the url (test).
That's pretty much it.
I have a controller called user which just loads the user profile page for now
class user extends CI_Controller {
public function __construct(){
parent::__construct();
}
public function index($username = null){
//load index page
$this->load->view('profile/index');
}
}
i have also routed it so i can load it from user/$username in routes
//user profiles pretty url
$route['user/(:any)'] = "user/index/$1";
the thing is i would like to change it and allow directly the users to go to their profiles without typing user/$username and instead $usernamd like mysite.com/$username...
I tried it but it messes up everything.how can i achieve this?
Thanks.
I guess the only way to achieve something like this is to add all other controllers to your routes file.
You could try something like this
$route['controller'] = "controller";
$route['controller/(:any)'] = "controller/$1";
$route['(:any)'] = "user/$1";
Combined with the _remap function as stated here. In your users controller.
Have you heard of the _remap function?
If you replace the index() function with this:
public function _remap($username = null) {
$this->load->view('profile/index');
}
It will probably work. You don't have to use the routes.php.
I used something like this for my users ; this "p" function in my users controller, mysite.com/users/p/$user_id , routes are good but I solved it like this, you could also do it do index function if you don't want something like "p"
function p()
{
$total_slashes = count ( $this->uri->segment_array () );
$last = end ( $this->uri->segments );
if ($total_slashes == 3) {
$data ['userdetails'] = $this->users_model->userDetails ( $last );
// $last is our user_id
$this->load->view('profile/index');
}
}