I'm trying to implement page templating in my codeigniter application, templating is working fine for instance, i have a blog page, which i'm trying to assign as my homepage, with different view and pagination and so on. When i write www.mywebsite.com/blog, it gets opened in homepage template, or assume that i have a page www.mywebsite.com/about , it gets opened in page template too. But when i try to access my website via www.mywebsite.com, i have a 404 error page. How can i assign my blog page as the homepage ?
Page Controller :
class Page extends Frontend_Controller {
public function __construct(){
parent::__construct();
$this->load->model('page_m');
}
public function index() {
// Fetch the page template
$this->data['page'] = $this->page_m->get_by(array('slug' => (string) $this->uri->segment(1)), TRUE);
count($this->data['page']) || show_404(current_url());
add_meta_title($this->data['page']->title);
add_meta_keyword($this->data['page']->keywords);
add_meta_description($this->data['page']->description);
// Fetch the page data
$method = '_' . $this->data['page']->template;
if (method_exists($this, $method)) {
$this->$method();
}
else {
log_message('error', 'Could not load template ' . $method .' in file ' . __FILE__ . ' at line ' . __LINE__);
}
// Load the view
$this->data['subview'] = $this->data['page']->template;
$this->load->view('_main_layout', $this->data);
}
private function _page(){ // methods }
private function _homepage(){ // methods }
}
in my Routes, i have set my default controller to page controller
$route['default_controller'] = "page";
application/config/routes.php
$route['default_controller'] = 'namecontroller';
The problem is that there's no URI segment when you visit www.mywebsite.com. You can try setting the default value as:
$this->uri->segment(1 , 'blog')
Your code
// Fetch the page template
$this->data['page'] = $this->page_m->get_by(array('slug' => (string) $this->uri->segment(1)), TRUE);
count($this->data['page']) || show_404(current_url());
the uri segment code
$this->uri->segment(1)
is looking first url segment, when you browse your site like www.yousite.come/blog it will work find but when you do www.yoursite.com 1st uri segment is missing so it will return false , so i will show 404 page.
Solution :
You can just add the second parameter to the function like
$this->uri->segment(1,'blog');
now if the first url segment is missing it will not return false,it will return the default vlaue 'blog'
For more information about this you can see codeingitor documentation
Related
I have a "routing" problem on CodeIgniter 4.2.7.
My home page is displayed well, the page also reloads well when I click on "home" in my menu, on this side there is no problem, however when I want to access another page I have the message error following "Error 404".
Here is my controller:
class c_accueil extends BaseController
{
public function index()
{
$data['titre'] = "Accueil";
return
view('v_menu')
. view('v_accueil',$data)
. view('v_footer');
}
public function espaceNintendo()
{
$data['titre'] = "Espace Nintendo";
return
view('v_menu')
. view('v_espaceNintendo', $data)
. view('v_footer');
}
Here is my base url:
public $baseURL = 'http://localhost:63342/ProjetWeb';
Here is my route:
$routes->get('/', 'c_accueil::index');$routes->get('/public/espaceNintendo', 'c_accueil::espaceNintendo');
Here is my view (v_menu) :
<?=anchor(base_url().'/public/', 'Accueil')?>
<?=anchor(base_url().'/public/espaceNintendo', 'Espace Nintendo')?>
So "Accueil" works fine but not "espaceNintendo"
Url of my home page which works well:
http://localhost:63342/ProjetWeb/public/
However, the URL as soon as I click on "Espace nintendo" is this:
http://localhost:63342/ProjetWeb/public/espaceNintendo
But it gives me "error 404".
Do you have any idea where the problem comes from?
My helpers are well loaded on my base_controller:
protected $helpers = ['html', 'form', 'url'];
i have codeigniter setup to use "home" as the default controller which is to display homepage
i tried to run the index function within home controller to collect the uri segments to determine whether or not to redirect or display home page but it seems to think that the uri segment is another controller mysite.com/segment1
function index(){
$url1 = $this->uri->segment(1);
if(!empty($url)){
echo $url1;
}
else{
$this->load->view('home_page');
}
}
You are setting $url1 as the segment then testing if $url is empty or not.
From your code, $url will always be empty.
Make sure you keep an eye on what you call your variables.
So what you have now...
function index(){
$url1 = $this->uri->segment(1);
if(!empty($url)){ // $url will always be empty as it's not defined.
echo $url1;
}
else{
$this->load->view('home_page');
}
}
What you should have...
function index(){
$url = $this->uri->segment(1);
if(!empty($url)){
echo $url;
}
else{
$this->load->view('home_page');
}
}
Then it will do as you intended.
You can set default controller to home. Then to be able to read $this->uri->segment(3); you nead to pass thet uri via URL mysite.com/controller/function/uri-segment(3). If you hav an Index function in home controller mysite.com and you want to pass a value of 11 via uri your url shuld look like this:
mysite.com/home/index/11
For this to work i had to change the routes to
$routes[('any')] = "New_controller"; //created a new controller
in "New_controller" i could then define the first segment i want to get
function index(){
// define segments
$url = $this->uri->segment(1);
if(!empty($url)){
echo $url;
}
and of course my
$routes['default_controller'] = "home";
function index(){
// home controller
$this->load->view('home_page');
}
Now when i go to mysite.com it takes me to the homepage or if i go to mysite.com/12345 it takes me to the new controller page where i can run a query on the segment
I have a custom 404 controller. It works fine. In routes.php I have:
$route['404_override'] = 'custom404';
this accesses this controller:
class custom404 extends MasterController {
public function __construct(){
parent::__construct();
}
public function index(){
$this->output->set_status_header('404');
$crit = array(
'subtype' => 'footer',
'status' => 'public'
);
$res = $this->mongo_db->where($crit)->get('contentobjects');
$this->pagedata = $res[0];
$this->load->view('404');
}
}
Can I call this from a different controller?
Currently I'm just forcing the issue by calling an (ostensibly) never-extant page:
if(!$this->viewable($res[0])){
header('Location: /404');
die;
}
Yes you can, just redirect to it directly.
However CI comes with an errors folder, with a sub folder for HTML and a 404 error view page. If you customize this page all your headers will be set correctly automatically, and you can call it in a much clearer manner.
if (empty($result))
{
// show error
show_error('The result you requested could not be found', '404');
}
Or more concisely:
if (empty($result)) show_error('The result you requested could not be found', '404');
The message here can be accessed in the template with $message field.
You can then easily set any code you need, like 401 etc.
http://www.codeigniter.com/user_guide/general/errors.html
I'm getting into frameworks and I'm using CI so i can more familiar with OOP. In the static pages tutorial in the pages controller I am told to copy this code
<?php
class Pages extends CI_Controller {
public function view($page = 'home') {
if (!file_exists(APPPATH . '/views/pages' . $page . '.php')) {
// we dont have a page for that!
show_404();
}
$data['title'] = ucfirst($page); //Capitilize the first letter
$this->load->view('templates/header', $data);
$this->load->view('pages/' . $page, $data);
$this->load->view('templates/footer', $data);
}
}
?>
in the if statement its blocking the pages I'm trying to load such as about.php and index.php
when I remove the ! in the if statement I'm able to render the about.php and index.php which is good, I'm able to load my pages according to the tutorial, but if I type in something random like asdasd.php i don't get the 404 error I get an AN ERROR WAS ENCOUNTERED Unable to load the requested file: pages/asdasd.php
How can i go about fixing this issue, having CI display the 404 when the file isn't there.
Thanks
It seems the issue is in the path in your file_exists call.
You need to add a / (slash) just after /pages in the following line:
if (!file_exists(APPPATH . '/views/pages' . $page . '.php')) {
I have some experience with php, but I just recently started learning Codeigniter. I used to have a website with a fixed navigation pane and sidebar, but the main section of the site loaded dynamically based on a Get variable. It was basically
include head.php
include navbar.php
include sidebar.php
include the page requested from the get variable (home, about, contact, etc.)
include footer.php
I liked this because the entire site did not have to reload when the user navigated from page to page.
I can't figure out how do this with Codeiginiter. Should I be using a controller for each page or one controller with a function for each page? Do anyone know of a good tutorial that does something similar? All the tutorials I've seen reload the entire site for every page.
Edit: Essentially I want to do this but with Codeigniter
Since it looks like you want relatively static content, but loaded dynamically you can do with one controller and (maybe) one method in the controller.
To do it with one method, do this in the welcome controller:
public page( $page_id ){
// views/header.php
$this->load->view( "header" );
if( $page_id = "about" ){
$this->load->view("about"); // views/about.php
}
else if( $page_id = "contact" ){
$this->load->view("contact"); // views/contact.php
}
// views/footer.php
$this->load->view("footer");
}
This takes a single get variable and figures out what page to load in between the header and footer.
This way www.yoursite.com/page/about will load the about page, www.yoursite.com/page/contact will load the contact page
Now, if you want to get rid of the /page part, you need to do some URL rerouting in application/config/routes.php
Alternatively you could use several methods in one controller:
public about( ){
// views/header.php
$this->load->view( "header" );
$this->load->view( "about" );
// views/footer.php
$this->load->view("footer");
}
public contact( ){
// views/header.php
$this->load->view( "header" );
$this->load->view( "contact" );
// views/footer.php
$this->load->view("footer");
}
Now your URLs look nicer without routing, but you have to load the header/footer for every page.
do you really like to copy/paste many $this->load->view() to any controller function?
It's a spaghetti code. You can try next: for example we have main.php controller as default controller. This main controller contain main function:
public function index()
{
ob_start();
$this->load->model('mainmodel');
$data = $this->mainmodel->_build_blocks(); //return array with needed blocks (header, menu, content, footer) in correct order
foreach ($data->result_array() as $row) {
$this->load->module($row['block_name']);
$this->name = new $row['block_name'];
$this->name->index();
}
ob_end_flush();
}
So, each other controller also have index() function which can dispatch actions depends on url segments, prepare params etc.
Footer controller as example (I use Smarty as template engine):
public function index()
{
$this->mysmarty->assign('year', date("Y"));
$this->mysmarty->view('footer');
return true;
}
Content controller will have:
public function index()
{
$name = $this->uri->segment(1, 'index');
$act = $this->uri->segment(2, 'index');
$this->load->module($name);
$this->name = new $name;
$pageData = $this->name->_show($act);
if ($pageData)
{
$this->mysmarty->assign($name, $pageData);
}
$this->mysmarty->view($name);
}
Thats mean what if you want to show http://site.name/page/contactus , we do next:
1) main.php start cycle by needed blocks
2) firstly we show header.tpl by header controller
3) then we show menu
4) then we call content controller which parse url, found what he should call _show() function in Page controller and pass action='contactus' to it. _show() function can contain some switch/case construction which show templates depends of action name (contactus.tpl in this case)
5) in the end we show footer template
In such case we have flexible structure. All controllers should have index() functions and all controllers who can be called in content should have _show($act) function. Thats all.
In codeIgniter you can do that like this, you can load different views at the same time from your controller. for example:
for example in your navbar view you have a Contacts button in your menu that would look like this:
<a href='contacts'>Contacts</a>
In your controller:
public function contacts()
{
$this->load->view('header');
$this->load->view('navbar');
$this->load->view('sidebar');
$this->load->view('contacts_view');
$this->load->view('footer');
}
So we're assuming here that you have the following views already that is ready to be loaded (header.php, navbar.php, sidebar.php, contacts_view.php, footer.php).
UPDATE:
you don't need to have $_GET[] request, just provide the method name from your controller in the <a> anchor tag
in codeigniter i using template
first make template file in one folder with header.php, navbar.php, etc.
example : template.php
<?php
echo $this->load->view('header'); //load header
echo $this->load->view('navbar');//load navbar
echo $this->load->view('sidebar');//load sidebar
echo $this->load->view($body); //load dynamic content
echo $this->load->view('footer');//load footer
?>
second in controller
function index( ){
$data['body'] = 'home'; // cal your content
$this->load->view('template', $data);
}