Pergunta

I'm totaly new in mustache and this is my first project i'm trying it out. I use it with kohana 3.2 and Kostache module and PHP implementation of mustache.

I have a collection of sport tournaments and each of it has many events and each event has 3 entities that i call "outcome". My task is to show all of them in one table. Following template show how i need this table to be show.

{{#tournaments}}
    <h2>{{name}}</h2>
    <table class="event_list">
        {{#events.find_all}}
            <tr>
                <td>{{day}}</td>
            {{#outcomes.find_all}}
                <td class="outcome">{{name}}</td>
            {{/outcomes.find_all}}
            </tr>
        {{/events.find_all}}
    </table>
{{/tournaments}}

And now goes my problem and thus question. While showing "outcomes" i need to attach additional different classes to each . So i mean i have 3 "outcomes" for each event and thus i have 3 different CSS classes for each of them. But inside {{#outcomes.find_all}} loop i have no clue is it first entity or second or third. What can i do about this?

Trying to solve this I was thinking about using functions. I thought of adding function to this view's class that would render all events "outcomes" and this may look like this:

{{#tournaments}}
    <h2>{{name}}</h2>
    <table class="event_list">
        {{#events.find_all}}
            <tr>
                <td>{{day}}</td>
                {{print_outcomes}}
            </tr>
        {{/events.find_all}}
    </table>
{{/tournaments}}

But obviously i will need to pass collection of "outcomes" in that function and then i realized that i can't pass anything in that function. So how such problems solved in mustache?

Also if i have very simple function like this:

public function print_outcomes(){
    return "<td>aa</td>";
}

it will pass it trougth url_encode before put to output so that i will get

&lt;td&gt;aa&lt;/td&gt;

is that can be fixed?

Foi útil?

Solução

You can try with function in your view model similar to this:

public function outcomes()
{
    $outcomes = ORM::factory('outcome')->find_all();

    $result = array();

    foreach ($outcomes as $outcome) 
    {
        $push = $outcome->object();

        $push['name']  = $outcome->name;
        $push['class'] = 'class_'.$outcome->name;

        $result[] = $push;
     } 
     return $result;
}

Then in your mustache you will have something like this:

{{#outcomes}}
    <td class="{{class}}">{{name}}</td>
{{/outcomes}}

Outras dicas

Mustache is logic-less, meaning all logic you want (except for simple exist checks and loops) should be done by including the logic in the JSON you use as input.

Basically, you need to encode all variables (such as the css classes) into the json.

Following your example, see the below JSON and Template (untested but this should get you going)

JSON

{      
  tournaments:[
    {
      name: "tournamentA",
      events: [
        {
           day: "day1",
           outcomes:[
             {
                name: "outcomeTypeA",
                cssClass: "classA"
             },
             {
                name: "outcomeTypeB",
                 cssClass: "classB"
             },
             {
                name: "outcomeTypeC",
                cssClass: "classC"
             }
           ]
        },
        {
          //another event of tourA
        }
      ]
    }, 
    {
      //tournamentB, etc .
    }
  ] 
} 

TEMPLATE

{{#tournaments}}
 <h2>{{name}}</h2>
 <table class="event_list">
     {{#events}}
         <tr>
             <td>{{day}}</td>
             {{#outcomes}}
                <td class="outcome {{cssClass}}">{{name}}</td>
             {{/outcomes}}
         </tr>
     {{/events}}
 </table> 
{{/tournaments}}

Indeed you could use functions as well, in similar fashion: i.e: embed the functions in the json where you need them. In this case though this would be overkill imho.

But for ref something like:

JSON

{      
  tournaments:[
    {
      name: "tournamentA",
      events: [
        {
           day: "day1",
           outcomes:[
             {
                name: "outcomeTypeA",
                 cssClass: function(){
                    return "classA";
                 }
             },
             {
                name: "outcomeTypeB",
                 cssClass: function(){
                    return "classB";
                 }
             },
             {
                name: "outcomeTypeC",
                 cssClass: function(){
                    return "classC";
                 }
             }
           ]
        },
        {
          //another event of tourA
        }
      ]
    }, 
    {
      //tournamentB, etc .
    }
  ] 
} 

Since this would repeat a lot you could externalize it to a helper

JAVASCRIPT:

 var myHelper = function(param){
   return "class"+param;
 }  

JSON

 .... {
        name: "outcomeTypeA",
        cssClass: function(){
          return myHelper("A");
        }
     },....

Or probably better by inferring from 'name'

 .... {
        name: "outcomeTypeA",
        cssClass: function(){
          return myHelper(this); //this refers to object literal on this level 
                                 //containing 2 properties: 'name' and 'cssClass'
        }
     },....

And then:

 var myHelper = function(obj){
   var param = obj.name.substring(obj.name.length-2); //get last char from 'name'-prop
   return "class"+param;
 }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top