I am creating multiple CodeIgniter views that could possibly be placed in any order by a controller. One of these views is a table of contents that I want to display the correct order of the views as they appear in the page. Is it possible to detect which order the views appear in and then change, add or remove elements from the table of contents?
CodeIgniter won't be able to help you with it cause it renders the view instantly when you call $this->load->view(...) (see the relevant code for view loading in the core Loader class).
You'll have to do your own logic for that, there's nothing stopping you from creating an array with information about the views you need to load, and load your table of contents view beforehand:
$views = array('page1.php' => 'Page 1', 'page2.php' => 'Page 2');
$this->load->view('table_of_contents.php', $views);
foreach($views as $view => $title){
$this->load->view($view);
}
Related
How can I load views of my nav menu without reloading the entire main view? something like templates or partial views. Is necesary to do this with ajax? How can it be? I donĀ“t know much about ajax. It will be possible to see an example?
I load my home view in controller like this:
$data = [
'header_view' => 'main/header',
'nav_view' => 'main/nav',
'section_view' => 'main/main_view',
'article_view' => 'main/article',
'aside_view' => 'main/aside',
'footer_view' => 'main/footer',
];
$this->load->view('home_view', $data);
Then I load the vievs from home view:
<section>
<?=$this->load->view($section_view);?>
</section>
...
And in the nav view I wanted to put the links to different sections without reload the nav view, because I will have a tree structure and other stuff.
why don't you use AngularJS ? you can make a single page application using ui-routes or ng-routes. you can make ajax call to your controller method that will render your view, and you can show that view in .
EDIT
In order to do a one page iframe site, you need to set up a controller to return a page without anything else
Controller -> loadpage($name)
then route it however you'd like
then, create an iframe with an id
<iframe name="maincontent"></iframe>
obviously, add in your needed styling / attributes.
On your links, add in targets
Link 1
For my Codeigniter site, I started by making a view for each controller situation. This was impractical, as it would require going back to the code for each to make a change. So I changed approach and operated on a 'default' controller with optional fields. I then thought I could load special views as needed into it.
I put together this view with optional fields with fields for $title, $search_bar on/off etc. However, now came the content area. I was able to load more views into this default view using:
$data['content_views'][]='blocks/login';
$this->load->view('default/a', $data);
and in the 'default'view:
if(isset($content_views)&& (is_array($content_views)))
{
foreach($content_views as $content_view)
{
$this->load->view(&$content_view);
}
}
(and that works fine)
Two questions:
Am I making things to complex? Is this an accepted way of doing this? Or have I misunderstood the functioning of a view and how they are intended to work?
I want a way to mix the $content_view, i.e. a block of text, then a view. I'm not quite sure as to how to proceed. Say I want a message first, then a view, then more text. This method will only accept views.
Can anybody help me create this flexible approach?
Yeah I would say you're making things a little complex. While I may not be following your description well enough to know precisely how to respond, I can tell you how I do it:
First the whole site is run through a template so the header and footer are the container file and all views needed within the site are rendered as page type views - like an article page, a gallery page, etc. Components are loaded and passed to the views as strings:
$content['sidebar'] = $this->load->view('components/sidebar', $data, true);
That last true says to render as string.
Essentially, this means the page views are pretty much html with php echoing out the necessary elements. No views calling other views, which is how I read your example.
CI loads views progressively, so your controller can output like so:
$this->load->view('header', $header_data);
$view_data['sidebar'] = $this->load->view('components/sidebar', $sidebar_data, true);
$this->load->view('content', $view_data);
$this->load->view('footer', $footer_data);
and in content view, handle the sidebar like so:
<?php if(isset($sidebar)): ?>
<nav>
<?php echo $sidebar; ?>
</nav>
<?php endif; ?>
And, assuming you populate those arrays for each view it will render header, then content, then footer. And also render sidebar if it is present.
So combining everything, I'm basically saying you can load in sections in your controllers progressively, passing sub-views as strings to whichever section makes sense. That keeps your view controlling in the controller where it belongs and not in the view files themselves. In my experience, I have not had to write a site that was so complex that this construct wasn't perfectly suitable if the site is planned well.
My employer requires certain pages on the website have a two page feature.
What this means is that some default content show up on the node_view page as normal but the second part should show up when a link is clicked.
This will be easy if I could do this across multiple nodes but the requirement is for all the data to be stored in one node but displayed across two pages.
I hacked together the following code:
function mymodule_node_view($node, $view_mode, $langcode){
$path = current_path();
$path_alias = drupal_lookup_path('alias',$path);
$links = array( 'test' => array('title'=>'my_link', 'query'=>'', 'href'=>"{$path_alias}/nextpage") );
$node->content['my_module'] = array(
'#theme' => 'links__node__mymodule',
'#links' => $links,
'#attributes' => array('class' => array('links', 'inline')),
);
}
That creates a hyperlink called my_link across the top of my content area - which is great.
The problem starts when I click the hyperlink. Supposing I am on http://example.org/homepage and I click the hyperlink, I expect to be redirected to http://example.org/homepage/nextpage. Also, I still want to maintain the view and edit tabs of the actual node I was on. However, Drupal correctly gives me a "page not found" error.
What's interesting is if I used http://example.org/node/1 and visited http://example.org/node/1/nextpage, I don't get the issues I described above but the url is less descriptive.
To solve this problem, I am sure I have to extend hook_menu but I don't know how to account for any number of taxonomy terms leading up to the actual node title. So, I can't predict how many % I will need before the node title and then my /nextpage. However, I want /nextpage to still have the view and edit tabs of it's parent page.
This is all unexplored territory for me.
Update
I found the following function which does a great job of returning the entire node path complete with taxonomies:
$path = current_path();
$path_alias = drupal_lookup_path('alias',$path);
What I don't know is how to take advantage of this in hook_menu to dynamically create /nextpage for my nodes.
Please remember, I don't really want /nextpage to be entirely independent of the original and actual Drupal node. When on /nextpage I want to be able to have access to the view, edit etc tabs of the node.
So, /nextpage effectively is just an extension of a Drupal node page.
There is a quick way to do that. Using views module.
In the fields section choose the field you wanna view. And in the arguments add the nid.
Then add the link to the node view you already created.
The final result http://mysite/views-page/[nid]
Hope this helps... Muhammad.
I would check the node_menu() function to get some reference on how it's implemented.
Not sure on your taxonomy requirements so this might be insufficient but I'll go with what I understand.
But off the top of my head I'd go for something like:
function mymodule_menu() {
$items['node/%node/nextpage'] = array(
'title' => 'Next page',
'type' => MENU_LOCAL_TASK, // Makes it a tab on node/%node-pages
'page callback' => 'mymodule_node_page_view', // Your page display function
'page arguments' => array(1), // First will be a node object, second will be whatever value is passed in the url
// You should rip access callback and access arguments from node_menu()
);
return $items;
}
That should do something like what you are asking for.
It is also possible, easier and definitely recommended to do this with Panels/Pages (see also Chaos Tools) or arguably Views as they are quite capable of all this and generally a better way to work with Drupal's strengths than custom code.
Updated
To clarify I've simplified the menu hook and you should be able to use the below page view function. I still believe you would make a better solution using Panels and overriding node_view and such.
The MENU_LOCAL_TASK part in the menu hook should turn this into another tab along with View and Edit.
function mymodule_node_page_view($node) {
die("It works: ".$node->title);
}
Hope that's more helpful.
Let's say I want to display the specials module on the homepage in a position different than $content_top, $content_bottom, $column_left or $column_right. How do I do that? If you have some experience with this, could you give me some pointers?
The module will be display in home.tpl but I'm assuming I would need to edit the controller file home.php
To do this, you will need to make edits to two files
Firstly, you will need to edit the controller. In this example, I'm going to add the specials to the home page
So open the controller file catalog/controller/common/home.php. Somewhere before this line $this->response->setOutput($this->render()); add the following
$this->data['special_block'] = $module = $this->getChild('module/special', array(
'limit' => 5,
'image_width' => 80,
'image_height' => 80
));
The array is the settings for the module. Note that the layout, position, status and sort order aren't included, as they're irrelevant here. I've also used special_block as a unique key for the content, to avoid it conflicting with any other items that may need rendering
Then in your template file, you just need to use <?php echo $special_block; ?> wherever you want the module to go
I'm working on a site for a client that wants to be able to update modifying their content. The brief was to allow them to edit pages, but not create or delete them. For the site I decided to work with cakePHP, as I've heard good things.
First up, a quick explanation of my setup. I've got a single table, called 'contents', in which i'm storing each page's content. The table has a pid, a varchar 'title', a varchar 'slug' and a longtext 'body'. They're all pretty self explanitory, Each page will have it's own row, and body will be a simple HTML dump.
I've got two situations that I am having trouble with. Firstly, is setting the homepage. Cake's default is the page based on home.ctp, but that is static. Currently the page I was as the homepage is at localhost/alc/contents/view/2. I understand this is something to do with the routing, but most examples out there give half the solution, when I need every detail :P
The second problems is the slugs of the pages. Each page is currently under /contents/view/id, and i'd like this to be the slug in the database instead. Each time i try to change this (i.e. modify the view link in my index), I get an error rather than the page's content.
Any help on this would be appreciated, as there are the two things I cannot seem to grasp properly. Thanks!
By the way, you can view the site at http://www.roberttilt.name/web-dev/ALC_proto/
For the first question you need to open the /app/config/routes.php and change the line which is for the home page. i.e.:
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
need to become
Router::connect('/*', array('controller' => 'contents', 'action' => 'view'));
In your controller file /app/controllers/contents_controller.php go to action view and change it to accept empty id i.e.
function view($id = null){
if($id == null){ //Load the default home page
$this->find('first', array('conditions'=>array('default'=>1)));
} else {
//load the
$this->find('first', array('conditions'=>array('OR'=>array('slug'=>$id, 'id'=>$id))));
}
.....
}
This way if the id or slug are not provided you are loading the home page. If one of them is loaded, just use it to load the contents of the desired web page.
Your links will look like:
$this->Html->link('About', array('controller'=>'contents', 'action'=>'view', $slug_var));
The link will be converted to
About
Probably you have to take a look on the Cookbook.