4

In phalcon templating engine volt (which is similar to twig) you can fetch all records by :

{% for product in products %}
    Name: {{ product.name }}
    Description: {{ product.description }}
    price: {{ product.price}}
{% endfor  %}

So, in my scenario, I'm building a crud template which will be used for different kind of models. What I wanted to achieve in this template is that every columns in this view are not hard-coded. So I store the columns I wanted to show into an array (defined in the controller, passed to the view) :

$cols = ['name','description','price']

In the view, to make it display all columns :

{% for product in products %}
   {% for col in cols %}
       {{ col }}: {{ product.col }}
   {% endfor  %}
{% endfor  %}

Obviously, this will result in error, because there is no "col" in product.

Is there any solution or alternative for this ?

AzDesign
  • 1,169
  • 1
  • 8
  • 18
  • 2
    I don't think that's possible (yet). But luckily you can extend Volt http://docs.phalconphp.com/en/1.2.6/reference/volt.html#extending-volt – Gerben Jacobs Mar 25 '14 at 14:15
  • 2
    I believe than this can help: [link](http://docs.phalconphp.com/en/1.2.6/reference/volt.html#id3). I dont tested, so not posted a answer. Create a funcion and pass the parameters like: `{% funcName({{product}}, {{col}}) %}` – gabrieloliveira Mar 25 '14 at 14:31
  • Thanks, I look up the documentation and still confused of where to start. I know I have to create a function, 1st argument accept an array, and 2nd argument as its key, return the value which the key match in the array. But, where should I put the code, do I have to make separate file for custom code, I don't really know. The documentation showing different example without any clarification of the details... – AzDesign Mar 25 '14 at 18:44
  • Look at this http://docs.phalconphp.com/en/latest/reference/volt.html#id3. Basically you need to change your bootstrap file, where services are being registered (like here https://github.com/phalcon/invo/blob/master/public/index.php#L77) – jodator Mar 26 '14 at 09:02
  • Can't you use generalized field names for that? since you are using CRUD and your template looks the same, feels like you can use the same field names across the models. – deb0rian Mar 26 '14 at 14:47
  • Just curious, did you already checked the [**phalcon-devtools**](https://github.com/phalcon/phalcon-devtools)? There's a CRUD application to kick start that kind of implementation or at least serve as reference on how to deal with models in a abstract way. – cvsguimaraes Mar 26 '14 at 19:08
  • @Fratyr field names are differ from each model, cant do that. I did start with devtools, now I'm going to replace all those separate views and controllers into a single crud controller & view set. I managed to register a custom function but stuck on the "value-passing". I don't really understand why there are $resolvedArgs & $exprArgs. The array (1st arg) and key (2nd arg) which I passed on this function are not properly passed (read as the exact variable name instead of its values). I'm still tinkering with it – AzDesign Mar 27 '14 at 06:45

2 Answers2

2

While frustrated tinkering with volt extension, I found a simpler solution :

  1. Convert the model object into array. In the controller : $products->toArray()

  2. Simply, in the view, to display specific value of specific key from an array : {{ product[key] }}

Problem solved, though because it is now not in form of object, I can't access object property using dot like {{ product.some_field }}, instead {{ product['some_field'] }}.

AzDesign
  • 1,169
  • 1
  • 8
  • 18
2

You should use the readAttribute() function: http://forum.phalconphp.com/discussion/1231/volt-access-to-object-property-using-variable

{{ product.readAttribute(col) }}
Yvan
  • 2,539
  • 26
  • 28
  • Not working at all. Error message: `Fatal error: Call to undefined method stdClass::readAttribute()`. – Haozhe Xie May 10 '15 at 15:49
  • If the error says `stdClass`, that clearly means that you didn't give a model object, as in Phalcon all objects inherit from Phalcon\Mvc\Model constructor. And the initial question clearly implies it: `fetch all records`. – Yvan May 11 '15 at 16:11
  • I have inherit the model class from `Phalcon\Mvc\Model`. And I'm using Phalcon 2.0. – Haozhe Xie May 12 '15 at 02:48
  • I really doubt that: https://github.com/phalcon/cphalcon/blob/2.0.0/phalcon/mvc/model.zep#L3145 => the method exists, and you have «stdClass» in your error description, which means that you're dumping a default class, not a Phalcon object. Try a `{{ dump(product) }}` in volt, you'll see that's not a Phalcon object. – Yvan May 13 '15 at 07:29
  • Yes, you're right. Because I get the object using `{% set i18nCategoryName = courseCategory['courseCategoryName'] | json_decode %}`. And I want to get the attribute `{language}` (is a variable) of the `i18nCategoryName`. So this method doesn't work for me. – Haozhe Xie May 13 '15 at 09:05
  • You may use `defined` in this case, perhaps it would work as expected: `{% if i18nCategoryName.property is defined %}` ... `{% endif %}` – Yvan May 17 '15 at 05:58