• blog
  • portfolio
  • about
  • contact
 
Mimeo - Conditional Tokens
In the last post of this series on Mimeo, I talked about block tokens and how to use them. In this post, I'll cover conditional tokens.

This post is a part of a series:

  1. Introducing: Mimeo
  2. Mimeo - Block Tokens
  3. Mimeo - Conditional Tokens
  4. Mimeo - Interpolation
  5. Mimeo - Theming Your ASP.NET MVC3 Application
  6. Mimeo - Design Philosophy

It may be desirable to conditionally render a block in a template. Mimeo supports this with the TokenizeIf() method. I may change the name of this method at some point. The order of the parameters is subject to change as well.

In the last post we continued building on a console application. This time, let's add shipping information to the order class:

public ShippingInformation ShipTo { get; set; }

Here's the class definition:

public class ShippingInformation
{
    public string Street1 { get; set; }
    public string Street2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
}

example

This time, we'll modify the template configuration to optionally support a shipping address for an order. The following snippet is a subset of the token builder code.

order.TokenizeIf(o => o.ShipTo, "@ShipTo", o => o.ShipTo != null, shipto =>
{
    shipto.Tokenize(s => s.Street1, "@Street1");
    shipto.Tokenize(s => s.Street2, "@Street2");
    shipto.Tokenize(s => s.City, "@City");
    shipto.Tokenize(s => s.State, "@State");
    shipto.Tokenize(s => s.Zip, "@Zip");
}).EndsWith("@EndShipTo");

The syntax looks similar to what we've seen so far. There's a mapping to a property, a string token identifier (which, in this case, is the beginning of the block to be rendered), and a child context. The only different part of this is the condition parameter:

o => o.ShipTo != null

Before the library will render this block, it executes this delegate using the context. If the method returns true, it is allowed to proceed with rendering the block. Otherwise, it skips it and moves on.

The condition parameter is a Func<TModel, bool>. In this case, the order object is passed in, and tested for a null ShipTo property.

template

We'll use the same template from before, this time adding the ShipTo block.

==== Order Report ======
@FirstName @LastName is a Person who is @Age years old.
    Submitted On | Amount
@Orders
    @DateSubmitted     | @Amount
    @ShipTo Shipped To:
        @Street1
        @Street2
        @City @State, @Zip
    @EndShipTo
@EndOrders
========================

Here's some sample output from this template. There are three orders, and only the second order has shipping information.

==== Order Report ======
John Nelson is a Person who is 24 years old.
    Submitted On | Amount

    1/1/2011     | $10.00


    1/2/2011     | $20.00
     Shipped To:
        123 Main St
        Apt B
        Pittsburgh PA, 15203


    1/3/2011     | $30.00


========================

Here is a complete listing of the sample code in this post:

using System;
using System.Collections.Generic;
using Mimeo;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            const string template = @"
==== Order Report ======
@FirstName @LastName is a Person who is @Age years old.
    Submitted On | Amount
@Orders
    @DateSubmitted     | @Amount
    @ShipTo Shipped To:
        @Street1
        @Street2
        @City @State, @Zip
    @EndShipTo
@EndOrders
========================";

            var mimeographs = new Mimeographs();

            var mimeograph = new Mimeograph<Person>(builder =>
            {
                builder.Tokenize(p => p.FirstName, "@FirstName");
                builder.Tokenize(p => p.LastName, "@LastName");
                builder.Tokenize(p => p.Age.ToString(), "@Age");
                builder.Block(p => p.Orders, "@Orders", order =>
                {
                    order.Tokenize(o => o.Amount.ToString("c"), "@Amount");
                    order.Tokenize(o => o.DateSubmitted.ToShortDateString(), "@DateSubmitted");
                    order.TokenizeIf(o => o.ShipTo, "@ShipTo", o => o.ShipTo != null, shipto =>
                    {
                        shipto.Tokenize(s => s.Street1, "@Street1");
                        shipto.Tokenize(s => s.Street2, "@Street2");
                        shipto.Tokenize(s => s.City, "@City");
                        shipto.Tokenize(s => s.State, "@State");
                        shipto.Tokenize(s => s.Zip, "@Zip");
                    }).EndsWith("@EndShipTo");
                }).EndsWith("@EndOrders");
            });

            mimeographs.Add(mimeograph);
            mimeographs.CreateStencil<Person>("person-template", template);

            var person = new Person
            {
                FirstName = "John",
                LastName = "Nelson",
                Age = 24,
                Orders = new List<Order>
                {
                    new Order { Amount = 10m, DateSubmitted = new DateTime(2011,1,1)},
                    new Order
                        {
                            Amount = 20m,
                            DateSubmitted = new DateTime(2011,1,2),
                            ShipTo = new ShippingInformation 
                            {
                                Street1 = "123 Main St",
                                Street2 = "Apt B",
                                City = "Pittsburgh",
                                State = "PA",
                                Zip = "15203" 
                            }
                        },
                    new Order { Amount = 30m, DateSubmitted = new DateTime(2011,1,3)}
                }
            };

            var result = mimeographs.Render("person-template", person);

            Console.WriteLine(result);

            Console.ReadKey();
        }
    }

    public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
        public IEnumerable<Order> Orders { get; set; }
    }

    public class Order
    {
        public int Id { get; set; }
        public decimal Amount { get; set; }
        public DateTime DateSubmitted { get; set; }
        public ShippingInformation ShipTo { get; set; }
    }

    public class ShippingInformation
    {
        public string Street1 { get; set; }
        public string Street2 { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string Zip { get; set; }
    }
}
Posted on 04/13/2011 07:49:44

johncoder
I'm a C# programmer living in the Pittsburgh area. I love what I do.
extras