I'm working on a client website which part of it to retrieve news, this is my first codeigniter application and I have followed CI tutorials, slugs and routing.
The problem I'm having is that everything works fine but when it comes to get a record based on slug I get 404. What I did was removed index.php from my URL and tested it, which works fine.
This is my route.php
$route['default_controller'] = "welcome";
$route['404_override'] = '';
$route['news/(:any)'] = 'news/singe_news/$1';
$route['news'] = 'news';
This is my model news_model.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class News_model extends CI_Model {
function get_all(){
$sql="SELECT * FROM news AS news";
$query=$this->db->query($sql);
return $query->result();
}
//// get a single post
function get_single($slug = FALSE) {
if ($slug === FALSE)
{
$query = $this->db->get('news');
return $query->result_array();
}
$query = $this->db->get_where('news', array('slug' => $slug));
return $query->row_array();
}
function news_categories(){
$sql="SELECT * FROM news_categories";
$query=$this->db->query($sql);
return $query->result();
}
}
and this is my controller news.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class News extends CI_Controller {
public function index()
{
$this->load->model('news_model');
$data['results']=$this->news_model->get_all();
$this->load->view('public/header', $data);
$this->load->view('public/menu');
$this->load->view('public/news-listing', $data);
$this->load->view('public/footer', $data);
}
public function single_news($slug) {
$this->load->model('news_model');
$data['single_news'] = $this->news_model->get_single();
/// if (empty($data['single_news']))
/// {
/// show_404();
///}
$this->load->view('public/header');
$this->load->view('public/menu');
$this->load->view('public/single-news', $data);
$this->load->view('public/footer');
}
}
So questions I have:
1- Where does $slug come from? I have a view has
2- Is there anything missing?
URLs need to be
domain.com/news/this-is-a-slug
Many thanks and apologies if this may have been asked in different format with different intention on other posts.
Where does $slug come from?
Your URI looks like this: www.example.com/controller/method/arg1/arg2/arg3 (w/o query string)
Is there anything missing?
Well, there is few things you should do:
Use autoload (config/autoload.php) to load your most used models, or if this model is not used widely at least load it at class constructor.
You are not passing $slug argument to model method, this will not work even if you will fix your routing.
$data['single_news'] = $this->news_model->get_single();
Better to show 404 if you can't find a slug, don't refetch all data on fail.
To fix 404 error follow those steps:
Check your .htaccess file for errors
Check uri_protocol setting in config
Try routing like this $route['news/((.+)$)?'] = "news/singe_news/$1"; (this should replace both routes for news)
Related
I am learning CI and I'm trying to do this tutorial where you fetch data. My browser is just dumping this and nothing else
{entries}
{id}
{title}
{news}
{/entries}
Can you please help me figure this out? I'm pretty sure it has to do with my parser in the controller file
now this is my view:
<head>
<title>News Blog</title>
</head>
<body>
{entries}
<p>{id}</p>
<h3>{title}</h3>
<p>{news}</p>
{/entries}
</body>
Model
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class NewsModel extends CI_Model {
public function __construct() {
$this->load->database();
}
public function getNews($slug = FALSE){
$query = $this->db->get('news');
return $query->result_array();
}
}
and controller
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class News extends CI_Controller {
public function __construct() {
parent::__construct();
$this->load->model('newsModel');
}
public function index() {
$news = $this->NewsModel->getNews();
// I believe the issue is in the next few lines
$data['contactjs']=$this->parser->parse('templates/Javascript/contactjs',[],TRUE);
$data['bootCSS']=$this->parser->parse('templates/CSS/bootCSS',[],TRUE);
$data['CSS']=$this->parser->parse('templates/CSS/CSS',[],TRUE);
$data['jQuery']=$this->parser->parse('templates/Javascript/jQuery',[],TRUE);
$data['bootstrap']=$this->parser->parse('templates/Javascript/bootstrap',[],TRUE);
$template = '{id} {title} {news}';
$newsData = array('entries'=> $news);
$newsData = $this->parser->parse('pages/news', [], TRUE);
$data['news'] = $this->parser->parse('pages/news', $news, TRUE);
$this->load->view('templates/header', $data);
$this->load->view('pages/news');
$this->load->view('templates/footer');
}
}
Did you load the parser library? Try to output the $news variable, see if it contains some data. Also, check your application/log folder for more information. Maby there is a php error you're not seeing.
Next line of code should load your pages/news view just like any other view without the parser:
$this->load->view('pages/news'); // This view doesn't contain any parsed data now
I think you should create a temp variable and place all the data of all parsed views into it. Then load it in a view. To check, try to output the last variable and see if it contains any data like so;
echo "<pre>"; print_r($data['news']);
I am new to codeIgnitor and keep getting the error 404, please advise where am I going wrong, below is my structure and pages.
database name: stoma_store_suppliers ,
Database fields: supplierid, supplier_name, supplier_phone
Models Page:_____________suppliers.php
<?php
Class Suppliers extends CI_Model
{
public function get_suppliers($supplierid) {
if($supplierid != FALSE) {
$query = $this->db->get_where('store_suppliers', array('supplierid' =>$supplierid));
return $query->row_array();
}
else {
return FALSE;
}
}
}
?>
Controllers Page__________
suppliers.php
<?php if (!defined('BASEPATH'))exit('No direct script access allowed');
class Suppliers extends CI_Controller {
public function show($supplierid) {
$this->load->model('suppliers');
$store_suppliers = $this->suppliers->get_suppliers($supplierid);
$data['supplier_name'] = $suppliers['supplier_name'];
$data['supplier_phone'] = $suppliers['supplier_phone'];
$this->load->view('index', $data);
}
}
?>
Views Page:
index.php
<?php print $supplier_name; ?>
<?php print $supplier_phone; ?>
Required things to access any page of codeigniter are:
First letter of controller file must be capital like Suppliers.php.
The first letter of the class definition must match the filename, e.g. for Suppliers.php it would be class Suppliers extends CI_Controller.
If a database is to be used, then the correct connection details must be set in the file config/database.php.
Below are the steps to access the any page created in the codeigniter.
Write your site domain followed by index.php, e.g. http://mysitedomain.com/index.php/suppliers
To remove the need for index.php in the URL add an .htaccess file at the root folder. Details here. In that case the URL will be
http://mysitedomain.com/. Now, domain name will get followed by controller name and the function to be accessed, e.g.
http://mysitedomain.com/suppliers/show
To pass arguments to a controller using the URL add them after the controller/function segments, e.g. http://mysitedomain.com/user/show/dede
If a controller has an index function - public function index(){ - it can be accessed two ways:
A) http://mysitedomain.com/suppliers/index
B) http://mysitedomain.com/suppliers
If /function/argument URI segments are not provided after controller name, codeigniter will call index() by default.
My problem is that I can't read a piece of data on an individual page. For example, on the front page, I have a number of jokes pulled in from the db; I want to be able to click on a joke and send the user to a url such as jokes.com/read/a-chicken-crossed-the-road. At the moment, it sends me to my custom 404 page with the url being jokes.com/read/1 (1 being the joke_id) and I haven't been able to get past this problem for a while, so I though I would try here.
Here is my setup :
main view:
<p class="joke-content"><?php echo $joke; ?></p>
read view:
<?php
foreach($results as $row){
echo "<li>$row->joke</li>";
echo "<li>$row->name</li>";
echo "<li>$row->date_added</li>";
}
?>
controller:
//constructor class enables a function called to be used in any function within this controller
function __construct(){
// Call the Controller constructor
parent::__construct();
$this->load->model('getjokes_m');
}
public function index(){
$this->read();
}
//main jokes functions grabs all the jokes in the database and orders them in their correct category
public function read(){
$data['results'] = $this->getjokes_m->readJokes($this->uri->segment(3));
$this->load->view('template/header');
$this->load->view('template/sidebar');
$this->load->view('content/read', $data);
$this->load->view('template/footer');
}
and finally my model:
function readJokes()
{
$query = $this->db->query('SELECT j.*, c.name FROM jokes j LEFT JOIN category c ON c.category_id = j.category_id WHERE joke_id = ?');
//displays the results if the table has data inside
return $query->result();
}
routes:
$route['default_controller'] = "top";
$route['404_override'] = 'not_found';
$route['register'] = 'login/register';
$route['logout'] = 'login/logout';
$route['admin'] = 'admin/login';
$route['noaccess'] = 'login/noaccess';
I think it might be the sql statement I am using, because it doesn't return any data.
If somebody could point me in the right direction as to why this is not working and to get the first 55 characters in the URL slug, it would be brilliant.
If I understand this problem correctly you want a slug as a parameter of your read() function.
you did not specify controllers name lets assume you want it to be call "read"
The easiest way is to do following:
edit routes.php as following:
$routes['read/(:num)/(:any)'] = "read/read_it/$1";
line above takes URL as following: server.ufo/read/1/my-super-joke and translates it to this server.ufo/read/read_it/{id}
lets have controller structure as following:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Read extends CI_Controller {
public function __construct()
{
parent::__construct();
//Do your magic here
}
public function index()
{
//leave empty or redirect somewhere
}
public function read_it($id = FALSE)
{
if ($id === FALSE) redirect(); //go to default controller
$data['results'] = $this->getjokes_m->readJokes( $id ); //id is NUMERICAL auto incremented value!!
$this->load->view('template/header');
$this->load->view('template/sidebar');
$this->load->view('content/read', $data);
$this->load->view('template/footer');
}
}
/* End of file read.php */
/* Location: ./application/controllers/read.php */
and lastly generation of links is simple:
<p class="joke-content"><?php echo $joke; ?></p>
remember joke_id is autoincremented ID, and joke_name is your magic slug (name)
Ok I have a simple question I am using codeigniter frame work to create a simple blog. When I set up just a controller and a view I can print my database information (blog roll) to my view just fine. When I use the model controller view method i fail.
Here is what I would like to implement in to a method controller view setup.
my original view that works:
<?php
//is there an array from your search form?
if($_GET){
$books = $this->db->get('blog');//query the blog table in the database
if($books->num_rows() < 1)//are there clients to show?
{
echo 'There are no blog post'; //error message if no post
}
else
{
foreach(result() as $row)//loop through the blog
{
echo $row->title."<br>";//display each titles info
}
}
}
?>
This is what i have set for my New model
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Blog_Model extends CI_Model {
function get($args = null)
{
$query = $this->db->get('blog');
return $query->result();
foreach(result() as $row)//loop through the books
}
function insert($data)
{
$this->db->insert('blog', $data);
}
function update($data,$id)
{
$this->db->where("id",$id);
$this->db->update('blog', $data);
}
function delete($id)
{
$this->db->where("id",$id);
$this->db->delete('blog');
}
}
this is my new controller
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Blog extends CI_Controller {
public function index()
{
$this->load->model('blog_model', 'blog');
$data['blogs'] = $this->blog->get();
$this->load->view('blog',$data);
}
}
I am not sure what to do for my new view? I just want to echo the blog roll to the view
Well you´re doing a foreach in the model after the return function.
So what you return is just this:
$query->result()
You may should do the foreach in the view, this would be better placed as a model just should just return and not process information. Best place would be in this case the controller or may view - depending on how strict you are.
I did not work with CodeIgniter for a while so may try this:
Controller:
class Blog extends CI_Controller
{
public function index()
{
$this->load->model('blog_model', 'blog');
$data['blogs'] = $this->blog_model->get()->result();
$this->load->view('blog',$data);
}
}
The View
Here goes some text...
<?php
foreach($blogs as $post)
{
echo $post['someData'];
echo $post['someData2'];
}
?>
After all this code...
May you want to lookup this (CodeIgniter Doc).
Hope this helps. Try to
Controller:
$data['blogs'] = $this->blog_model->get();
Even though you load the model in order to call its function you must pass its name.
Model:
Must always have result() or row() when query are applied.
Hope this helps in your endeavors
I am trying to develop a social network where people can visit mysite.com/username. I used the _remap function and I got it working, however it is not loading any of my other controllers. Can someone be of assistance please?
This is my default controller:
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Welcome extends CI_Controller {
public function index($username = NULL)
{
$this->load->model('user_model');
if ($this->user_model->is_a_username($username)) {
$data['title'] = $username;
$data['main_content'] = 'users/profile_page';
$this->load->view('shared/template',$data);
} else {
$this->home();
}
}
public function _remap($method, $params = array())
{
if (method_exists($this, $method))
{
return call_user_func_array(array($this, $method), $params);
}
show_404();
}
public function home()
{
if ($this->ion_auth->logged_in()) {
$data['title'] = 'Carnect';
$data['main_content'] = 'users/wall_page';
$this->load->view('shared/template',$data); #if logged in show the user's wall
} else {
$data['title'] = 'Carnect';
$data['main_content'] = 'welcome/index';
$this->load->view('shared/template',$data); #if not logged in show the home page
}
}
}
and this is my routes file:
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
$route['default_controller'] = "welcome";
$route['404_override'] = '';
$route['login'] = "auth/login";
$route['logout'] = "auth/logout";
$route['register'] = "auth/create_user";
/*$route['news'] = "news/index";
$route['politics'] = "politics/index";
$route['culture'] = "culture/index";
$route['messages'] = "messages/index";*/
$route['(:any)/(:any)'] = "$1/$2";
$route['(:any)/(:any)/(:any)'] = "$1/$2/$3";
$route['(.*)'] = 'welcome/index/$1';
An example of one of the controllers that will not load..
session_start();
class News extends CI_Controller {
function News()
{
parent::Controller();
}
function index() {
$data['title'] = 'Politics';
$data['main_content'] = 'news/index';
$this->load->view('shared/template',$data);
}
}
I am working on a project that has a similar requirement on those urls.
I did it by adding route like this:
$routes['news'] = 'news/index';
or
$routes['news'] = 'news';
which are exactly lines that you've commented.
Sadly, It isn't possible without those lines (at least I couldn't do it).
If your URL was: example.com/news/index, it would match the rule $routes['(:any)/(:any)'], but if it was example.com/news, it wouldn't match anything and go to your last rule.
CodeIgniter's Routing doesn't take real segments, but the uri segments shown in the url. Therefore, your url example.com/news would be interpreted as a $username = news.
You'd have to do this uri routing for each url which only has 1 uri segment. You'd want to make sure no user has the same username with your controllers or he/she can never visit the user page.
You have to write a rule in application/config/routes.php file just add a following line
$route['(:any)'] = "welcome/index/$1";
You can access by using http://example.com/username if your have added .htaccess rule for removing index.php file from url or you can access like http://example.com/index.php/username