Adding Model to View Topic is solved

Discussion and education for beginner / novice programmers interested in embarking on the development process to take advantage of the extensible nature of the Joomla! CMS.

Moderators: tjay, seadap, Rogue4ngel, matthewhayashida

Forum rules
Post Reply
kojilab

Adding Model to View

Post by kojilab » Wed Feb 06, 2008 8:51 pm

Hi

I am new to Joomla yet very familiar with MVC framework.

I have a view that uses another mode (two total). How can I include a model whose name doesn't match the name of the view?

Is there any file naming convention as well for model. I'm meaning file name, not class name.

Thanks

User avatar
Pentacle
Joomla! Intern
Joomla! Intern
Posts: 61
Joined: Wed Oct 25, 2006 12:34 pm
Location: Turkey

Re: Adding Model to View

Post by Pentacle » Wed Feb 06, 2008 9:31 pm

I'm overriding display method in my controller like this. Second is the second model's name:

Code: Select all

   function display()
   {
      $document =& JFactory::getDocument();

      $viewType   = $document->getType();
      $viewName   = JRequest::getCmd( 'view', $this->getName() );
      $viewLayout   = JRequest::getCmd( 'layout', 'default' );

      $view = & $this->getView( $viewName, $viewType, '', array( 'base_path'=>$this->_basePath));

      // Get/Create the model
      if ($model = & $this->getModel($viewName)) {
         // Push the model into the view (as default)
         $view->setModel($model, true);
      }
      if ($model =& $this->getModel('Second')) {
         $view->setModel($model, true);
      }

      // Set the layout
      $view->setLayout($viewLayout);

      parent::display();
   }

My Joomla! 1.5 extensions - http://joomla.ercan.us
Progress is made by lazy men looking for easier ways to do things.

mtlnews

Re: Adding Model to View

Post by mtlnews » Thu Feb 07, 2008 12:41 am

If you just need another model, then you can use

// Assumed model
$model  = & $this->getModel();

// Different model
// with filename: other.php
// class name: ComponentModelOther
// for the view: ComponentViewOther
$other  = & $this->getModel( 'other' );

User avatar
CirTap
Joomla! Intern
Joomla! Intern
Posts: 73
Joined: Mon Dec 12, 2005 5:34 pm
Contact:

Re: Adding Model to View

Post by CirTap » Thu Feb 07, 2008 1:14 pm

Hi,

the relationship of View and Model should be 1:1 not 1:n.
the relationship of Model and Layout can be 1:n.

If a component needs to display different types of data, each dataset becomes a model used by one view.
The general MVC pattern allows one to toggle the datamodel for a view at good will, and you can to that too in the Joomla! Framework, but this Framework is not "intended" to be used in such a way :-)
I have a view that uses another mode (two total). How can I include a model whose name doesn't match the name of the view?

You should make each mode a different view with it's own model, if the data presented in each "mode" differs.
I presume that this "mode" is somehow determined by an argument in the URL, try to use &view and &layout and see if that fits into the schema, instead of using &view only and some "made up" argument which basically translates to the concept of layouts and you end up reinventing the wheel.

If a view represents a specific set of data it may of course render this data in very different ways by using different layouts (stuff in ./tmpl subfolder). For example a horizontal or vertical table, or an ordered list. It'd always be the same set of data (columns) -- the layout template is not required to display all the data the current model provides but it can rely on a specific set of fields; a "model".
If you toggle the model of a layout's view, these layouts would never really "know" what data they could use *safely* and would become more complicated and cluttered with loads of conditional statements. Or you end up with more layouts that you'd need, because "default.php" would become a nightmare of conditionals to handle all the various models it's confronted with.

If the component (!) provides different "modes", it may get away with one view using one model but different layouts.
If the data for each "mode" totally differs, ie. one requires a JOIN with other tables or changes the column names, you should add a new view using this joining model, and this second "default" layout may turn out pretty simple. For each mode's datamodel you can still add more layouts when needed.
You may finally end up with a bunch of "default" layout templates that even look pretty much the same, but that's ok and absolutely intended: the designer now has the freedom to choose which parts of the component she wants to override in the site template; layout_X for "mode 1" or layout_X for "mode 2", or all layouts of "mode 1" but none of"mode 2" -- and she probably wants to do so :)

Maybe both View classes share a lot of code, and you want to avoid duplication. Use OOP:
  class MycomponentMasterView extends JView
and the specific ones following J!'s schema include and extend this MycomponentMasterView class
  class MycomponentViewMode1 extends MycomponentMasterView
  using model "Mode1"
  class MycomponentViewMode2 extends MycomponentMasterView
  using model "Mode2"
Those view classes may not even need to contain any code and consist of nothing but the bare skeleton, but they'd provide the framework unique names which results in a different model to be used, and a distinct path for their layouts.

MVC is all about names.

com_content is probably the most flexible component in Joomla! and this flexibility is based on dedicated views and their unique models, but several views come with said different layouts or even use different renderers (html, pdf, feed). There's no "model-juggling" taking place.

Have fun,
CirTap

edited: typos
Last edited by CirTap on Thu Feb 07, 2008 1:37 pm, edited 1 time in total.
You can have programs written fast, well, and cheap, but you only get to pick 2 ...

"I love deadlines. I like the whooshing sound they make as they fly by." Douglas Adams

mtlnews

Re: Adding Model to View

Post by mtlnews » Fri Feb 08, 2008 10:39 pm

I didnt know that. Im always learning something new in joomla. How should external libraries be added though? Say for example you have a library for parsing and creating iCalendar files. Should you create a new model file (with no view) and include it whenever you need it, or create a "Master Model" with all the iCalendar parsing functions in it, even though it might be useless for other models?

User avatar
CirTap
Joomla! Intern
Joomla! Intern
Posts: 73
Joined: Mon Dec 12, 2005 5:34 pm
Contact:

Re: Adding Model to View

Post by CirTap » Sun Feb 10, 2008 4:10 pm

Hi,

we're probably hijacking this thread, but anyway ...

How to do things always depends on what is needed :-) There's no general rule or "law".

Let me just clarify my statement about Views and their Models. This was taken from JView::setModel(&$model, $default = false):
We support a multiple model single view system by which models are referenced by classname.  A caveat to the classname referencing is that any classname prepended by JModel will be referenced by the name without JModel, eg. JModelCategory is just Category.

If you look at this method's signature it's indeed the standard behaviour to add new models to the list. It's just that if you don't do anything -- literally --, the framework will derive the names, classes and file locations of the default model and layout from the view's name.
When I wrote "it's not indented to be used that way", I meant you should not replace a view's default model by another "default". A specific view ought to provide at least the same default data, but it may of course be extended with extra data for use in additional layouts.

This is exactly what happens in com_content: the article view, at the very least, contains the data of an article -- that's the default, but some "layouts" can also display the category or section an article belongs to. Whether they show up depends on com_content's  and the menuitem's parameters. If these parameters tell com_content that categories will be required that is they're  expected by the chosen layout, it'll load and add the category and/or section models, and the layout template may then access this extra information via additional properties and methods.
The amount of items may change or their ordering, but the default data isn't: you still have things like $title or $introtext from the default model.

Now, do you always have to include the whole iCal library?
I don't know. This (again) depends on the tasks your component provides and how it's supposed to provide the data to the user and certainly how this data is stored on your server.
If it's "default" job is to parse iCal files for display in an HTML page -- some event calender or such --, it's probably a good idea to only include these parts of the library to reduce weight. On the other hand, if -- what I suppose happens as well -- somone downloads an .ical file (set of events), this download task would probably just need the library parts the create/render this structure.
Does this require different models? I'm not too familiar with iCal, but I think there's not much difference in the resulting "colums" or "fields" and hierarchy whether the data comes from an iCal file or from the database. I'm pretty sure that iCalender library already provides some interface or data structure, and this should basically become the blueprint for your implementation inside Joomla.

What's probably special about this, are the possibly different data-sources: on the one hand it's some special formatted "text file", and on the other it's the database (I suppose) -- or maybe both?
Will users upload their .ical files in some way?
Will those files be located on the file system?
Do you have a database table with a big text column that will contain the "native" iCalender data; like jos_content contains "native" HTML for each article?
Will you break each "event" into pieces and make it a record on its own? with individual columns?
Or is there a combination of all?
:-)

All this makes "it depends" the only possible answer to whether or not you should include the whole iCalendar library, and if you can get along with one (default) model for each view or several adjacent models.
If the library is split into a parser and renderer, I would load the required parts/classes only when they're needed. Maybe write a "helper" class with utilities or decorators for the incoming and outgoing data.
Make outlines and a feature lists of each intended "view" and its presentation, and each action/task your component will provide. Think about the various layouts and how they need the calender data to be structured, ordered, filtered, etc. A "view by month" probably requires a different model than a "view by title" or "view by category", and so does a "details view".

Have fun,
CirTap
You can have programs written fast, well, and cheap, but you only get to pick 2 ...

"I love deadlines. I like the whooshing sound they make as they fly by." Douglas Adams


Post Reply