first excuse my bad english, I am not a native speaker. Also, the code
examples below could be formatted wrong. I have done a couple of Cake-
based applications in the last few years, but always had a problem
with the arrays Model::find() and other Model-Methods return me. In
the last projects, I tried different ways to "fix" this issue (which I
know is not a bug in Cake, but is very verbose in views when looking
at the examples provided):
Config for the testcases (Note this is not code from a actual product,
but just for a better understanding of what i try to archive):
Model: Product (has 6 fields for testing: id, name, description,
image, created, modified)
Controller: ProductsController:
.....
public function show($id) {
$product = $this->Product->find('first', array(
'conditions' => array('Product.id' => (int) $id)
));
$this->set(compact('product'));
}
public function showall() {
$products = $this->Product->find('all');
$this->set(compact('products'));
}
.....
The view (without any error or whatever management):
------------------------------------------------------------------------------------------------------------------------
1. Project: "Regular" CakePHP Syntax
<?php // Action: show() ?>
<h1><?php echo $product['Product']['name'] ?></h1>
<div class="description">
<?php echo $product['Product']['description'] ?>
</div>
------------------------------------------------------------------------------------------------------------------------
So far so good, there is nothing special in here. But if I need to
call this in a loop....
<?php // Action: showall() ?>
<h1>All products</h1>
<?php foreach($products as $product): ?>
<div>
<h2><?php echo $product['Product']['name']</h2>
<p><?php echo $product['Product']['description'] ?></p>
</div>
<?php endforeach; ?>
The syntax is understandable, but it is still far too verbose for me
(e.g. calling the array index 'Product' again even if I know I just
have the product). So, I know I could use something like Set::Combine
to flatten the array, but the problem would still be there: I always
have this ugly array syntax. So my second approach was defining a
helper function:
------------------------------------------------------------------------------------------------------------------------
2. Project: Using a Helper for getters and clearer syntax
/app/views/helpers/product.php (Simplified)
......
public function getItem($item) {
$this->item = $item['Product'];
}
public function getName() {
return $this->item['name'];
}
......
<?php // Action: show() ?>
<?php $this->Product->setItem($product['Product'] ?>
<h1><?php echo $this->Product->getName() ?></h1>
<div class="description">
<?php echo $this->Product->getDescription() ?>
</div>
<?php // Action: showall() ?>
<h1>All products</h1>
<?php foreach($products as $product): ?>
<?php $this->Product->setItem($product) ?>
<div>
<h2><?php echo $this->Product->getName() ?></h2>
<p><?php echo $this->Product->getDescription() ?></p>
</div>
<?php endforeach; ?>
------------------------------------------------------------------------------------------------------------------------
This approach is (imho) much more readable (and, this is the plus for
me, is much easier to use for our frontend developers), but adds
complexity to the application. The next problem is that the given
helper only holds the reference to the last called product, so you
cant do something like:
------------------------------------------------------------------------------------------------------------------------
<?php // Action: showall() ?>
<h1>All products</h1>
<?php
// Main product is a single product we want to call here and later as
example
$this->Product->setItem($mainproduct);
echo $this->Product->getName(); // -> Returns Main Product
<?php foreach($products as $product): ?>
<?php $this->Product->setItem($product) ?>
<div>
<h2><?php echo $this->Product->getName() ?></h2>
<p><?php echo $this->Product->getDescription() ?></p>
</div>
<?php endforeach; ?>
<?php echo $this->Product->getName(); // -> Returns last product in
foreach, but I want my main product :(
------------------------------------------------------------------------------------------------------------------------
The next drawback is that you have to define all the getters manually
and need one helper for each model you want to parse this way. But
with all the drawbacks, it still is a better approach than the regular
array syntax. As I am not very happy with it (because of the
complexity it adds).
The question is: Would it make sense (from a MVC pov as much as from a
performance and useability-standpoint for my poor frontend-guys) to
make this even easier? What I would like to do is something like:
------------------------------------------------------------------------------------------------------------------------
// 1. in app_model::afterFind():
... get the model schema and automagically create getters for our
"ViewObject" (dont know how to call this, as I dont want to use the
Model-Object directly but a own object with only some getter
functions, so the users in the views cant call Model-Actions
directly):
the Product Model has, as described above some fields, so we would end
with an object like this:
class ProductViewModelWhatever {
public function getId() return $this->id;
public function getName() return $this->name;
}
This could be used in the view directly like:
------------------------------------------------------------------------------------------------------------------------
<?php // Action: showall() ?>
<h1>All products</h1>
<?php
// No longer needed
/*$this->Product->setItem($mainproduct);
echo $this->Product->getName(); // -> Returns Main Product*/
echo $mainproduct->getName() // -> Returns mainproducts name
<?php foreach($products as $product): ?>
<div>
<h2><?php echo $product->getName() ?></h2>
<p><?php echo $product->getDescription() ?></p>
</div>
<?php endforeach; ?>
<?php echo $mainproduct->getName(); // -> Returns our mainproducts
name. Yippie! :)
------------------------------------------------------------------------------------------------------------------------
The question is: What would be the drawbacks of such a technique? What
do you think of the idea generally? If you have any other tips or
ideas for accomplishing the same (or a similiar task) I would be happy
if you would share them with me.
Greetings from Germany,
Chris
--
Our newest site for the community: CakePHP Video Tutorials http://tv.cakephp.org
Check out the new CakePHP Questions site http://ask.cakephp.org and help others with their CakePHP related questions.
To unsubscribe from this group, send email to
cake-php+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/cake-php
No comments:
Post a Comment