I'm writing simple website with some cms functions. It would be good to have all menu items and pages contents held in database.
I have table with id, name, parent_id and a content field. In future I would maybe move content to a content table to have multiple contents to menu item with fk. But it is not the case here.
The question is:
Do I need the URL field in menu table?
What else do i need to get it to work? Should every page have its own controller? I,m a beginner with zend framework, so please give me some directives. Thanks in advance.
Lets start with Question 2: every page does not need its own controller. If your pages are static you can even load every page using a single action. For more dynamic processing you could use a separate action for each page.
In any case, make sure you structure your code into controllers and actions in a way that makes sense. For example, inside your CMS a user might edit, create or delete a post. You could then create a PostController inside which you write an editAction, createAction and deleteAction.
You could store the URL in the table, but you do not necessarily have to.
Single action approach (mostly for static content)
Make sure the page id or name is stored in a GET param. You could then use the following code:
public function genericpageAction()
{
$thePageID = $this->_request->getParam('id');
// fetch the page content from the db based on $thePageID
// and pass it to the view
}
Of course, here, you could also match against the URL stored in the table if you chose that approach.
Multiple action approach (for more dynamic processing, most likely what you want with a CMS)
You could define a route for each page and load its content in the respective action. For example, for the page to edit a post:
class MyCMS_PostController extends Zend_Controller_Action
{
public function editAction()
{
// fetch the home page content
// do any further processing if necessary
}
}
Related
I have code that I want to run on every page load, such as looking up menu items, looking up the users details etc. These will be displayed on partial views that make up the main view.
Where do I place this code so that it can fill my partial views with each page load? I know I can just add the code to the top of the partial view itself, but this doesn't really follow the MVC pattern.
Is there a function that is always called that I can hook into in my base controller?
You can create a base viewmodel for the repeated code and make other viewmodels inherit from it.
...such as looking up menu items, looking up the users details etc
You're a bit unclear about the type of information you want to load: in case the info is a view-component then indeed you should create a base-view and inherit from it or include it (composition) in any other view.
But, in case it is "user-information" - the data should live in a model-component that again, may live as "base-model" object that is included in other model components.
Here's the layout at the moment:
<header>
<navigation>
<section id="<?= $this->id; ?>">
<?= $content; ?>
</section>
<footer>
The page layout however (here called main.php), has the following hierarchy:
[header]
[dynamic gallery of images depending on db record id field] !!!
[navigation]
[content]
[footer]
Navigation is equal on all pages, so they should be on the layout, correct?
The dynamic gallery wrapper is equal on all pages, so it should be on the layout, correct?
But the images themselves, they should be different depending on the database records.
I don't even know where to start here.
Can I have a little push please?
UPDATE
Should I create a method inside components/controller.php or mycontroller or whatever we may have, that retrieves the value from the model, and make that value available as a public parameter to be used on the layout?
Does this makes sense to you?
As you correctly know, You must put your non-changing views into your main layout. But about views which will change during the request, You must create a different view for each one. Then, depend on your request you can renderPartial() your views.
Say, Your image view.
First, We create a view with name _image.php in our layout directory (or any directory).
Second we fetch the data from database. for example we have images data like below:
$images=array('test1.jpg','test2.jpg',...);
Third, In each request you must send your data to your renderPartial method:
$this->renderPartial('//layout/_image.php',array('images'=>$images));
and in your _image.php you can manipulate your data, which is always different in different requests.
There are another ways to do this:
Using the Yii's DECORATOR feature which is really cool. You can google it
Using Yii's CLIPS feature
UPDATE
In this case, using Yii's Decorator worked for questioner.
I'm creating a blog for a website I am building. The main blog page obviously has each blog listed as it should. But I want each blog to also have it's own individual page on the website. I want this page to be generated on creation of the blog post.
My question is, what would be the best method of creating this page. If I use the php file functions to create it, I would need to fill up a $data variable with hundreds of lines of HTML for the page. Which I guess is feasible, IF I am also able to dynamically change the variable to work for the new content that needs to be posted on said page.
Is there better methods? Would PHP work for this? Any suggestions would help.
In general, I would do it more or less like this:
1. Create a 'Blogs' SQL database table.
Create an 'id' column (primary key), and columns for fields like 'blog_date', 'title', 'author', and 'html_content'.
2. Create a 'Blog' class using php.
Create properties which correspond to the SQL fields in your 'Blogs' table, including 'id'.
3. Create public 'loadFromDB()' and 'saveToDB()' methods
These methods should load and save the SQL values of a row in 'Blogs' (selected by id) to and from the class properties.
4. Create a public 'view()' method for the 'Blog' class
This is simply an HTML view/template of a single blog entry displaying date, title, author, etc.
5. Create an 'index.php' blog page in a folder on the server
You want to use this page to display a single blog entry.
Use a blog's SQL id when calling this page from links in your main blogs page, for example via http GET: 'http://www.yoursite.com/blogs/blog/index.php?id=30'. In your php code inside index.php, where you want the entry to appear, do something like this:
$id_default = 27; // the blog entry which must appear when there is no query parameter
$id = empty($_GET['id']) ? $id_default : $_GET['id'];
$B = new Blog($id);
$B->loadFromDB();
$html = $B->view();
echo $html;
In this way, you don't have to create an HTML page for EVERY blog entry, or put ALL the entries on one page. You can just use one page created dynamically with a GET parameter instead.
Obviously there is more you can/must do, such as creating commenting displays and forms and a 'Comments' SQL table, etc. But this should give you some ideas.
Its possible to create individual page for each blog dynamically. Here are the steps you can follow.
Create one master template. Add some special tags where you want dynamic content.
While adding new post, Read the content from that master template, replace appropriate special tags with actual values
Write finally generated content into new file and save it to associated location.
You are ready to access that page.
I am using CodeIgniter with Template Library and have set up my template view file. Part of my template that doesn't change from page to page displays data from a database.
What is the best way to include this data in my template?
If the content doesn't change very often, something like the user's name, I would store it in the session and call it from there. Otherwise, if you really need to query it on every page request, I would create a base controller (MY_Controller) then create and assign a protected var that you can access from your controllers.
I'm new to the MVC pattern but have been trying to grasp it, for example by reading the documentation for the CakePHP framework that I want to try out. However, now I have stumbled upon a scenario that I'm not really sure how to handle.
The web site I'm working on consists of nine fixed pages, that is, there will never exist any other page than those. Each page contains something specific, like the Guest book page holds guest book notes. However, in addition, every page holds a small news box and a short fact box that an admin should be able to edit. From my point of view, those should be considered as models, e.g. NewsPost and ShortFact with belonging controls NewsPostController and ShortFactController. Notice that they are completely unrelated to each other.
Now, my question is, how do I create a single view (web page) containing the guest book notes as well as the news post box and the short fact? Do I:
Set up a unique controller GuestBookController (with an index() action) for the guest book, so that visiting www.domain.com/guest_book lets the index action fetch the latest news post and a random short fact?
Put static pages in /pages/ and in let the PagesController do the fetching?
< Please fill in the proper way here. >
Thanks in advance!
It sounds like you need to look into elements, or else you may be able to embed this into the layout - but its neater to use an element if you ask me, keep the things separate.
http://book.cakephp.org/2.0/en/views.html#elements
These allow you to have create small views that you are able to embed into other views.
You may also need to put some logic into the AppController (remember all other controllers extend the app controller) to load the data required for these views. The beforeRender function should be useful for this - its one of the hook functions cakephp provides, so if you define it on a controller, its always called after the action is finished before the view is rendered.
Something like this in your AppController should help:
function beforeRender() {
$this->dostuff();
}
function doStuff() {
// do what you need to do here - eg: load some data.
$shortfacts = $this->ShortFact->findAll();
$news = $this->NewsPost->findAll();
// news and shortfacts will be available within the $shortfacts and $news variables in the view.
$this->set('shortfacts', $shortfacts);
$this->set('news', $news);
}
If there are models you need in the app controller for use within this doStuff method, then you need to define them within uses at the top of the AppController
class AppController {
var $uses = array('NewsPost', 'ShortFact');
}