While working on codeigniter, I sorted out one thing that I can call model function from view page also.
For an example
here's my example model
<?php
class autoload_model extends CI_Model{
function __construct() {
parent::__construct();
}
/*---------data fetching-----------*/
function get_data_from_table($table,$data,$cond)
{
$this->db->select($data);
$this->db->where($cond);
$result= $this->db->get($table);
return $result;
}
/*---------ends-----------*/
}
?>
Now in my view page i have written this
<table cellspacing="1" cellpadding="0">
<tr>
<td>Product Title</td>
<td><Product Price</td>
</tr>
<?php
$product_list = $this->autoload_model->get_data_from_table("td_product","*",
"product_id > 0")->result_array();
if(count($product_list)>0)
{
foreach($product_list as $pl)
{?>
<tr>
<td><?php echo $pl['product_title'];?></td>
<td><?php echo $pl['product_price'];?></td>
</tr>
<?php
}
}
else
{?>
<tr>
<td colspan="2">No data Found</td>
</tr>
<?php
}
}?>
</table>
the whole things works fine, its just that I want to know whether its good to use in such fashion or not?
NOTE:
The autoload model is automaticaly loaded in the config/autoload.php file
Codeigniter is PHP Framework which built on top of the MVC (Model - View - Controller) design pattern. if you do not follow this then do not use framework
In one word: NO.
Why?
1) Since codeigniter is a MVC Framework, we should follow some defined protocols of MVC.
2) We've to see that how a MVC Framework works and accordingly we've to use it.
3) So how CI works?
- Firstly, we have a URL which loads a particular page.
- The routes checks the routes matching the URL and calls particular Controller.
- If no match found in routes, it then checks the matching Controller and Function
- Controller calls the model with addon data, and models uses that data for database operations.
- Models then returns required data back to the Controller and then Controller loads the view using that data.
CI Flow:
Request ---> Routing ---> Controller ---> Model/Libraries/Helpers/Plugins ---> Controller ---> Views
Your answer:
1) Calling models in views will work anyways (if model is autoloaded) but still it's wrong. Doing that means we're breaking MVC rules.
2) Also you can see in above flow that there is no connection between models and views.
3) So where can we call models: controllers, libraries, helpers.
so another way of looking at this - you are calling the view to render a product table - but you have not confirmed whether there are products.
the controller calls a product model and requests products. if products come back then the controller assigns an appropriate view for displaying products and passes the products_list object (or array) to the view. there should not be any code in the middle of a table in a view like
if(count($product_list)>0)
the only php code the view should have is things like
foreach($product_list as $pl)
to display the products. the value of $product_list comes from the model. so if for example your database table name changes -- that change is done in the model -- not the view.
and if NO products come back from the model - then there is no $product_list. the controller assigns a view where the user can search/browse for other products. we don't need an if(count) in the view because we already know what the search results are.
Related
Is it right to use php code or blade code in view file using laravel?
for MVC consideration is it better to sepearate front end code like HTML with any server side code and keep them in corresponding controller file ?
for example using like this:
in view:
<table>
<Loop> <!-- instate of using #foreach -->
<tr>
<td>
<-UserId->
</td>
<td>
<-UserName->
</td>
</tr>
</Loop>
</table>
in controller:
$html = view('page');
$loop_section=my_own_func_to_get_loop_tag_content($html);
//edit loop_section var with php foreach and return resault to $modified_loop_section var
$html=str_replace($loop_section,$modified_loop_section,$html);
return $html;
Updated:
above code is just an example way that isn't seemed a good way.
but i look for better way to separate any php code (including if foreach etc) with html code in view file without using a custom tag and code?
Yes you should definitely use Blade code in your templates. So function my_own_func_to_get_loop_tag_content should be processed in template file, but it should only show data. All business logic (such as DB querying, sorting, calculations, ...) should be done in your controllers. View is only for displaying data, so there shouldn't be any logic.
I have a pattern that I come across sufficiently often and I am looking for specifically a ZF2 (ZF3) way of solving this somewhat N + 1-related issue.
The following are excerpts from a single PHP file:
Looping through DB records & building table rows with data
Some number (say N) table rows are printed:
<?php
for ($i = 0; $i < db_num_rows($result); $i ++)
{
$row = db_fetch_array($result);
?>
<tr onclick="js_action(<?=$row['id']?>)">
<td><?=$row['number']></td>
<td><?=$row['company']?></td>
</tr>
<? } ?>
A single embedded JS Script that needs to be printed only once
<script type="text/javascript">
function js_action(id)
{
// some JS code
}
</script>
Question
I want to separate view generation from DB, and my main concern here is . . . do I use partialLoop view helper or skip it out entirely?
I can use partialLoop which will have me create files like this:
//controller
$this->partialLoop('filename', $arrayRows);
<!-- view -->
<td>$this->number</td>
<td>$this->company</td>
I don't see a point of creating a file so small just for this little loop. What is a good way to implement the View Script in my case?
The primary use-case for partialLoop is already mentioned in the documentation (emphasis added):
The primary use is for reusable template fragments
The only reason to split markup into another template is for reusability. If you don't need to reuse the markup, there is no reason to do the extra mile and defining an extra template. This makes reading & maintaining the template only harder.
Instead it is perfectly fine to use a foreach loop in your view:
<script type="text/javascript">
function js_action(id)
{
// some JS code
}
</script>
<table>
<?php foreach ($this->arrowRows as $row) { ?>
<tr>
<td><?php echo $row['number']; ?></td>
<td><?php echo $row['company']; ?></td>
</tr>
<?php } ?>
</table>
Even when you have this snippet arround a couple of times, it might make sense to keep it in place instead of creating a such small view script. For me it would seem like over-optimization.
I usually follow these principles:
Only move something into a seperate template when I reuse it more than 2-3 times
Only move code that contains more complex logic that echoing some values into simple markup (e.g. conditional rendering)
Simple markup can always be embedded even when it is re-used (e.g. simple tables with few classes)
Never try to generalize partials where the parent view defines the behavior of the markup (e.g. the view defines extra classes to be used in the partial). This usually ends of making everything more complex and coupled than being helpfull.
I have a search result view that has a generated list of tables from another sites API. I'm trying to pass off the Artist ID to another next action via GET. The Artist ID will be then used to interact with the API.
I try to pass off the Artist ID like so but I receive a 'array_combine(): Both parameters should have an equal number of elements'.
The view file in question:
#foreach($parser->Artists->Artist as $Artist)
<table class = "table table-striped">
<thead>
{{ var_dump(strval($Artist['ID']))}}
<h3>{{ $Artist['ListName'] }}</h3>
</thead>
<tbody>
The vardump was to test that a string was in fact being passed off to the action(). I can confirm that it is, before it was a simple XML object.
Here's the corresponding route:
Route::get('/artist/detail/{$artist}','ArtistController#detail');
And the controller action:
<?php
// app/controllers/ArtistController
class ArtistController extends BaseController
{
public function detail($Artist) {
return 'Artist ID is ' . $Artist;
}
{
The problem was that Laravel was too smart. My $Artist variable was not read as a string but as a model because of the binding the routes file.
routes.php
Route::model('artist','Artist');
I changed $Artist from $Artist_ID and it worked just fine.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
How to extract data from single database table?
For example, i need data from table: categories, column: description with id 1 ?
As long as you are trying to write a Joomla component, I recommend you to start learning writing your code with MVC architecture. Joomla Documentation on this subject is available here. Anyhow, I'm gonna give you a simple but temporary solution and you have to rewrite it later using Joomla's MVC.
I presume that you want to select column1 and column2 data from your #__example_table and show then in a simple table.
First, you need to create a component with an empty view. You can use this online tool for creating a component at a glance; and of course it's free for creating components with empty views. After building, downloading and installing your component, let's call it com_mycomponent, there will be a folder called com_mycomponent in your /components folder. open it up and you'll see a views folder and inside it there's gonna be a folder for your view that I'm gonna call that myview.
In your view folder, there's a file called view.html.php which contains you view's class and also you can see a folder called tmpl which contains a default.php file for your view's template.
Now open view.html.php in an editor and create a public attribute called $items and getData() method after display() method like this:
<?php
class MycomponentViewMyview extends JView {
.
.
.
public $items;
public function display($tpl = null) {
.
.
.
$this->items = $this->getData();
parent::display($tpl);
}
public function getData() {
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select(array('column1', 'column2'));
$query->from('#__example_table');
$query->where('condition = 1');
$query->order('id DESC');
$db->setQuery($query);
$results = $db->loadObjectList();
if (!empty($results)) {
return $results;
}
return false;
}
}
In this example I've used Joomla's database API which are described here; and consider that dots means rest of the codes which you don't need to change.
Now open /components/com_mycomponent/views/myview/tmpl/defailt.php and delete everything here and write something like this:
<?php
defined('_JEXEC') or die; // No direct access
if (count($this->items)) {
?>
<table style="width: 100%">
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
</tr>
</thead>
<tbody>
<?php foreach ($this->items as $item) { ?>
<tr>
<td><?php echo $item->column1; ?></td>
<td><?php echo $item->column2; ?></td>
</tr>
<?php } ?>
</tbody>
</table>
<?php
} else {
echo 'Sorry! No data found...';
}
I think the example is quite clear and there's no need of explanation, but I'm gonna give you a brief explanation about what's happening. First of all we created an method to get data from database and store them in a variable which is accessible from outside. Then we call that method from display method which is somehow the constructor of the view class. Then in the view's template I used a loop for the records stored in $items variable and show them in table rows.
I tried to explain the solution in most simple possible way so that everyone could use it, and if it bothers you, I'm sorry.
Feel free to ask question and correct me.
I'm coming from CodeIgniter, and the terminology overlap between it and other MVC frameworks (particularly Zend) is giving me a mental block of some kind.
I want my users to visit http://mysite.com/do/this.
I understand that "do" is the Controller, and "this" is a function (well, method) within that Controller.
My site will have common elements like a header and sidebar; I understand that those go into a Layout, which will be incorporated into the final output.
I want the /do/this page to display three visual blocks of information (I'm deliberately not using the word "modules"). Let's call them BlockA, BlockB, and BlockC. Maybe one is a list of "new events" and another is a list of "new posts" and another is something else. Whatever. The trick is, these blocks of information will also be displayed on other pages of the site - say, http://mysite.com/did/that.
Both the "did" and the "do" Controllers (and the "this" and "that" methods, obviously) would be arranging BlockA, BlockB, and BlockC differently. Each Controller would have different criteria for what went into those blocks, too - one might be current information, while another might be archived information from the past.
I want to ensure that future programmers can easily alter the appearance of BlockA, BlockB, and/or BlockC without having to touch the code that populates their data, or the code which arranges them on each page.
So my general feeling is that BlockA, BlockB, and BlockC need to have their visual layout defined in a View - but that View wouldn't be specifically associated with either the "do" or the "did" Controllers. And the code which populates those blocks - that is, queries information from a database, selects the bits that are to be displayed, and whatnot - shouldn't reside entirely in those Controllers, either.
I started down the path of putting the logic - that is, assembling what will be displayed in each block - into Models. I feel I'm on the right path, there; both the "do" and "did" Controllers can thus summon the block-creation code via Models. But how (and where) do I abstract the visual element of those blocks, in such a way that the visual elements can also be shared by these two Controllers? Do the Models somehow load a View and output HTML to the Controllers (that doesn't feel right)? Or is there a way for the Controllers to run the Model, get the data to display, and then somehow feed it to a common/centralized View?
I know how I'd do this in CodeIgniter. But... what's the correct architecture for this, using Zend Framework? I'm convinced that it's very different than what CodeIgniter would do, and I want to start writing this application with the right architecture in mind.
One small naming thing: /:controller/:action/* => /do/this = this is an action (although also both a function and a method in the controller, action is the proper name)
Your blocks to me sound like "partial views". There are a few ways to approach this problem, and depending on how the views work, or what information they need to know, you adapt your strategy
Rendering Partials
You want to use this method when you have some view code you want to be used by multiple views. There are two different approaches using the view helpers Zend_View_Helper::render or Zend_View_Helper_Partial* The render($phtmlfile) view helper is more efficient, the partial($phtmlfile, $module, $params) view helper clones a new view, unseting all parameters, and setting the ones you pass in. An example of how to use them:
case/list.phtml:
<?php
$this->headTitle($this->title);
// works because our controller set our "cases" property in the view, render
// keeps our variables
echo $this->render("case/_caseListTable.phtml");
case/view.phtml
<?php
$this->headTitle($case->title);
?><!--- some view code showing the case -->
<?php if ($cases = $case->getChildren()): ?>
<h3>Children</h3>
<?php echo $this->partial("case/_caseListTable.phtml", "default", array(
"cases"=>$cases,
)); ?>
<?php endif; ?>
case/_caseListTable.phtml
// table header stuff
<?php foreach ($this->cases as $case): ?>
// table rows
<?php endforeach; ?>
// table footer stuff
Custom View Helpers
Sometimes the controller has no business knowing what information is being displayed in the block, and preparing it for your view would be silly, at this point you want to make your own view helpers. You can easily add them to the global view in application.ini:
resources.view.doctype = "XHTML1_STRICT"
resources.view.helperPath.My_View_Helper = APPLICATION_PATH "/../library/My/View/Helper"
I have a tendency to use this method for things that will require additional information from the model not provided by the controller, or blocks of reusable formatting code for the view. A quick example, from a project that I used: Olympic_View_Helper_Ontap grabs the draught beer list and renders it:
class Olympic_View_Helper_Ontap extends Zend_View_Helper_Abstract {
public function Ontap()
{
$view = $this->view;
$box = Olympic_Db::getInstance()->getTable('box')->getBoxFromName('Draught-Beer');
if ($box) $menu = $box->getMenu(); else $menu = null;
$content = "";
if ($menu)
{
$content = "<h1>".$view->escape($menu->title)."</h1>";
$content .= "<ul>";
foreach($menu->getItems() as $item) {
$content .= "<li>".$view->escape($item->name)."</li>";
}
$content .= "</ul>";
}
return $content;
}
}
Then in my layout:
<?php echo $this->ontap(); ?>
Your View Helpers can also accept arguments (of course), can call other view helpers (including partial). Consider them template functions. I like using them for short tasks that are required a lot, for instance $this->caseLink($case) generates a properly formatted <a href='/case/2' class='case project'>Project</a> tag.