2

I have a temple that render a table using a struct that represents all the data.

The template look like this.

<div class="card shadow mb-4">
<div class="card-header py-3">
  <h6 class="m-0 font-weight-bold text-primary">DataTables Example</h6>
</div>
<div class="card-body">
  <div class="table-responsive">
    <table class="table table-bordered" id="dataTable" width="100%" cellspacing="0">
      <thead>
        <tr>
          #for(colums in page.table.columns) {
              <th>#(colums)</th>
          }
        </tr>
      </thead>
      <tfoot>
        <tr>
          #for(colums in page.table.columns) {
              <th>#(colums)</th>
          }
        </tr>
      </tfoot>
      <tbody>
          #for(row in page.table.rows) {
            <tr>
            #for(data in row.datas) {
               <td>#(data)</td>
            }
            </tr>>
          }
      </tbody>
    </table>
  </div>
</div>
</div>

For this scenario this works. But let's say in another page I have a different data structure. So not page.table but page.grid.table how can I still use this template?

My initial though was to change the template ta use table.columns instead of page.table.columns and then "assign" the the table variable right before I embed the template. This way you could also have multiple table if you like and just re-assign the table before you embed it.

I'm not very experience with web-development so maybe I'm just thinking of this wrong.

Terrick Mansur
  • 147
  • 1
  • 10

1 Answers1

2

This is rather simple if you use a conditional to check if the variable exists or not.

#if (page.table != nil) {
    #for(row in page.table.rows) {
        <tr>
             #for(data in row.datas) {
                 <td>#(data)</td>
             }
        </tr>>
    }
}else {
    #for(row in page.grid.table.rows) {
        <tr>
             #for(data in row.datas) {
                 <td>#(data)</td>
             }
        </tr>>
    }
}

This is just an example, you can make the code a little bit more you but the base is the same, check if the variable exists and then use it.

Edit: You can use a Wrapper class that stores the same type of variables, for example. In the code above you hace an matrix of I guess strings, you can make something like this:

class Wrapper: Content {
   let table: [[String]]

   init(table: [[String]]){
       self.table = table
   }
}

and then for if you have page.table you cast it to the wrapper like:

let wrapper = Wrapper(table: page.table)

// Or if you have page.grid.table
let wrapper = Wrapper(table: page.grid.table)

And use it in Vapor leaf like this:

#for(row in wrapper.table) {
     <tr>
         #for(data in row.datas) {
              <td>#(data)</td>
         }
     </tr>>
}
Juan Carlos
  • 578
  • 5
  • 22
  • I understand you can do this, but this does not solve my problem. What i'm trying to do is re-use the same template in the same page, but with different data. So let's say you have two table in one page, or two or more of anything on one page. Here is a better example: `for(profile in profiles) { #embed("profile", profile) }` Is this possible? – Terrick Mansur Jan 19 '20 at 18:22
  • well, in that case you can use a Wrapper, create a class that can store the same type of information and cast your 2 types of data to that Wrapper. – Juan Carlos Jan 20 '20 at 17:29
  • Yes, this is the conclusion I reached as well. I ended up creating a container class that has optionals for every Component in my code. The component provides a type and based on this type you can switch to fetch the correct component in the object and use the correct template. I put these containers an an array and loop through them and embed the correct leaf file. – Terrick Mansur Jan 20 '20 at 20:41