Loop through a list of items

If you have an advanced integration setup that is sending data in an array or JSON object, you can setup loops in your document to print that information. Examples include line items on an invoice or a list of items for a report.

From a technical standpoint, your data will look like this for HTTP POST (name/value pairs)

items[0][Name]=Shirt&items[0][Quantity]=2&items[0][Price]=19.95&items[1][Name]=Jeans&items[1][Quantity]=3&items[1][Price]=89.99

Or JSON:

{"items": [{"Name":"Shirt", "Quantity":"2", "Price":"19.95", "Total":"39.90"},{"Name":"Jeans", "Quantity":"3", "Price":"89.99", "Total":"269.97"}]}

Create a Simple List

If you have a list of items that you would just like to print in your document, you can use the following {foreach} code

{foreach from=$items item=_row}
{$_row.Quantity} x {$_row.Name} = ${$_row.Price|number_format:2}
{/foreach}

Create a Table

If you're generating an invoice, you're probably looking to create a table that loops through each of the line items and prints them on a new row in the table.  No problem!  We've added a new "tablerow" tag that you can use and it tells our system to treat the table row as a loop.  The tag works exactly like a "foreach" loop, so all you need to do is use "tablerow" instead of "foreach" and we'll handle the rest.

Here's an example:

Name Quantity Price Total
{tablerow from=$products item=_product}{$_product.Name} {$_product.Quantity} {$_product.Price} {$_product.Total}{/tablerow}

The data that you send through to a table row loop needs to be an array (ie and array of products) that can be easily looped through.  The part after the dot in the variable name is the individual property for that element in the array.

If you'd like to skip items in the list, you can use an if statement in your table like this:

Name Quantity Price Total
{tablerow from=$products item=_product}{tableif $_product.Type == 'shirt'}{$_product.Name} {$_product.Quantity} {$_product.Price} {$_product.Total}{/tablerow}

 

Create a Bulleted/Numbered List

You can also use special "listrow" code to loop through items in a list to create a bulleted list.  Like this:

  • {listrow from=$products item=_product}{$_product}{/listrow}

 

Sort Your List

If you would like to sort your items based on a certain "key" you can do so using the "sort" modifier in this format "|sort:[KEY]:[asc or desc]" (asc is default). For example:

{foreach from=$items|sort:"Name" item=_row}
{$_row.Quantity} x {$_row.Name} = ${$_row.Price|number_format:2}
{/foreach}

To sort by price in descending order:

{foreach from=$items|sort:"Price":"desc" item=_row}
{$_row.Quantity} x {$_row.Name} = ${$_row.Price|number_format:2}
{/foreach}
Have more questions? Submit a request

68 Comments

  • Avatar
    Chuck Pirie

    I want to create sign-in sheets for registered event guests using MS Word. There will be a variable number of guests per event. Is it possible to do this using ItDuzzIt to send the data?

  • Avatar
    Jeremy Clarke

    Hi Chuck,

    I'm not 100% sure if itDuzzit will send over the data in an array/list, but if you create a support ticket, we can explore the options with you.

    Thanks!

  • Avatar
    Rafaela Campos Benatti
    And if I need to print only some products from array/list, how can I do this? Is it possible to use if inside tablerow??
  • Avatar
    Jeremy Clarke
    Hi Rafaela, Yes, you can use an if statement like this in your first cell of the table row: {if $product.type != 'shirt'}{continue}{/if}
  • Avatar
    Rafaela Campos Benatti
    Hi Jeremy, I did that, but it returns an empty row (in fact only one empty cell, the others columns does not appears). Example: my list has 15 items but only 10 matches the condition. In the way you mencioned it returns 15 lines but only 10 has data showing, the 5 remaining are empty. I need it to show only 10 lines, how can I do? By the way, my document was made in Word format.
  • Avatar
    Rafaela Campos Benatti
    Can you please write for me the example in this article but using if?
  • Avatar
    Jeremy Clarke
    Hi Rafaela, Sorry, I mispoke - you need to use the {tableif} tag like in the example table in the article above.
  • Avatar
    Rafaela Campos Benatti
    Thanks Jeremy!
  • Avatar
    Jessica Momentum

    Hi Jeremey!

    Is there a chance to see an example of a syntax for {tablerow} with 'if' condition and 'sort'?

  • Avatar
    Jeremy Clarke

    Hi Jessica,

    There's an example above that shows the {tablerow} tag with the {tableif} tag in there as well and then you can add the sort to the tablerow tag like this:

    {tablerow from=$products|sort:"price" item=product}

  • Avatar
    Phillip Percy

    Hi Jeremy.

    What do I need to use to output multiple lines of data (with in multiple fields/columns) as separate rows in Excel? The {tablerow} tag throws up a syntax error when I load the Excel template into Webmege.

  • Avatar
    Jeremy Clarke

    Hi Phillip,

    We now support the {tablerow} code in Excel templates!

    Edited by Jeremy Clarke
  • Avatar
    Erin Ward

    Hi Jeremy,
    Does the {foreach} code work for repeatable sections in a form. Forms with a field that has a "+" to add information for multiple individuals, such as children, in a form. Every field that is in the Repeatable Section field is repeatable and will come up when the user clicks on the 'Add' or '+' button. Will this code work?
    {foreach from=$sellerrepeat sellerrepeat=_row}
    {$cosellerfname} {$cosellerlname}
    {/foreach}

  • Avatar
    Jeremy Clarke

    Hi Erin,

    Yes, it will work, but it depends on how the data is formatted. Please turn on Debug Mode to confirm what the data looks like, but here's what your foreach will look like:

    {foreach from=$sellerrepeat item=_row}
    {$_row.cosellerfname} {$_row.cosellerlname}
    {/foreach}

  • Avatar
    Anton

    Hi Jeremy,
    Great articles, thanks! I still have a question about the loop. Can I somehow create multiple pages while looping? E.g. I have an invoice with different groups of items and I want to separate them per page, but I don't know how many groups will be in an invoice (maybe 1, maybe 15).

  • Avatar
    Jeremy Clarke

    Hi Anton,

    Yes, you can add a page break inside your {foreach} ... {/foreach} loop and then it will put in a page break for each group. Please submit a ticket for more detailed help :)

  • Avatar
    Radek Zajkowski

    Do you support nested loops?

  • Avatar
    Jeremy Clarke

    Hi Radek,

    Yes, you can do nested loops:

    {foreach from=$products item=product}
    {foreach from=$product.sizes item=size}
    {$size.name}
    {/foreach}
    {/foreach}

  • Avatar
    John Lamano

    Jeremy,

    How about in instances where the data to loop contains only one item? Can this loop catch that?

  • Avatar
    Jeremy Clarke

    Hi John,

    Yes, as long as the data is still an array/list with 1 item, the loop will work :)

  • Avatar
    Shade Factor

    Hi Jeremy,

    One thing I haven't been able to do is reference the foreach's (or tablerow's) index/counter to appear on the document which is being prepared (i.e. a column where the iteration of the loop is shown, as "1" for the first pass, "2" for the second, and so on.

    For example:
    {foreach from=$products item=product}
    {$product.iteration} {$product.name} {$product.price}
    {/foreach}

    Is this possible?

    (many thanks in advance)

  • Avatar
    Jeremy Clarke

    Hi Andreus,

    You can use the "key" of the loop. Something like this:

    {foreach from=$products item=product key=_k}
    {$_k + 1} {$product.name} {$product.price}
    {/foreach}

  • Avatar
    Shade Factor

    Jeremy, many thanks for the swift response. This is exactly what I needed! :)

  • Avatar
    Julian Kirkness

    I have tried to follow the table rows approach - what I did was create a table with the required 3 columns and then entered the following into the columns:

    Column1

    {tablerow from=$projectHoursItems item=projectHoursItem}{$projectHoursItem.dateused}

    Column 2

    $projectHoursItem.Notes

    Column 3

    $projectHoursItem.hours {/tablerow}

    This is what the example above looks like you need to do but it gives the following error:

    There is an error in your document: Syntax Error in template "string:" on line 6 "
    {$projectHoursItem.dateused}
    " - Unexpected "/"

    Where am I going wrong??

    Julian

  • Avatar
    Jeremy Clarke

    Hi Julian,

    Just to confirm, you are using brackets in column 2 and 3, right? IE {$projectHoursItem.Notes} and {$projectHoursItem.hours}. If that doesn't fix it, please create a support ticket and we'll help you from there. It might be something else in your template.

    Thanks!

  • Avatar
    Julian Kirkness

    Hi

    Thanks for that - It's amazing how blind you can become after staring at a screen for ages!!

    Julian

  • Avatar
    Julian Kirkness

    mmm...

    I thought it was going to work because I didn't have the brackets for some reason but still no joy - I'll set up a support ticket.

  • Avatar
    Aravind S

    What is the key to send the JSON data

  • Avatar
    Jeremy Clarke

    Hi Aravind,

    You need to do an HTTP POST with the JSON data as the body of the request, then you need to set the Content-Type header to "application/json". Here's an example PHP/CURL call: https://support.webmerge.me/hc/en-us/articles/206526106-Send-Data-with-PHP

  • Avatar
    Markwood Fields

    Hi Jeremy,
    Is it possible to do this through Zapier?

    Looking to push records from TrackVia through Zapier.

    Is it possible to send a string formatted to look like a JSON array through Zapier, and have WebMerge interpret it as a JSON array (as opposed to a string)?

Please sign in to leave a comment.
Powered by Zendesk