Pipes

Pipes are an important concept in PBars that have been strongly inspired by Markup.js. The idea behind pipes is, that values can be processed in a standard way providing a simple extension mechanism. Pipes conceptually work like pipes in dos/unix shells. You put values in and get transformed values out. Here is a simple example of how to use a pipe in a data expression:

Template:

{{FirstName | ToUpper}}

Pipes are delimited by the | character and individually evaluated. The above template will take the value of the FirstName field, send it as an input to the ToUpper pipe and return the output. You can concatenate as many pipes as you like.

Template:

{{FirstName | ToUpper | Trim}}

Pipe parameters

Pipes may also be parameterized.

Template:

{{FirstName | PadRight 20}}

Each pipe defines it's parameters. Pipes parameters are delimited by spaces. If a parameter value has spaces, it can be quoted (the outer quoutes will be removed), either by using " or ' characters. The other quote character can then be used in the string. PBars distinguishes in between literals and data context parameters. A literal parameter is just a string (like "20" in the prior example). Data context parameters point to a value in the data context (see Data expressions in the basics section). Pipes define a preference, how to interprete a parameter. In addition parameters can explicitly be marked as literals or data expressions. A template expression does not explicitly state, that the first parameter. It assumes, that it's a literal.

{{#template SubTemplate.txt}}

Making it an explicit literal would look like this:

{{#template "SubTemplate.txt"}}

You could also explicitly say, that the parameter is not a literal, but a data expression by putting it in square brackets:

{{#template [TemplateName]}}

Predefined pipes

PBars comes with a fair amount of standard pipes out of the box and it's quite easy to implement your own (this will be discussed in a later chapter).

Aggregates

Count

Returns the number of elements in a collection.

{{People | Count}}  

Even

Returns true for even elements in a collection and false for odd ones.

{{#each People}}
{{(this) | Even}}
{{/each}}

Odd

Returns true for odd elements in a collection and false for even ones.

{{#each People}}
{{(this) | Even}}
{{/each}}

IsFirst

Returns true for the first element in a collection, otherwise false.

{{#each People}}
{{(this) | IsFirst}}
{{/each}}

IsLast

Returns true for the last element in a collection, otherwise false.

{{#each People}}
{{(this) | IsLast}}
{{/each}}

Reverse

Returns the collection in reverse order.

{{#each People | Reverse}}
{{FirstName}}
{{/each}}

Strings

PadLeft

Fills a string with a character (by default space) on the left side, until it reaches the given length.

{{FirstName | PadLeft 20}}

To specify another character, specify it behind the string length:

{{FirstName | PadLeft 20 _}}

You can optionally specify to truncate the string if it is longe than the indended length:

{{FirstName | PadLeft 20 _ truncate}}

PadRight

Fills a string with a character (by default space) on the right side, until it reaches the given length.

{{FirstName | PadRight 20}}

To specify another character, specify it behind the string length:

{{FirstName | PadRight 20 _}}

You can optionally specify to truncate the string if it is longe than the indended length:

{{FirstName | PadRight 20 _ truncate}}

Center

Fills a string with a character (by default space) on the left/right side, until it reaches the given length, effectively centering the string.

{{FirstName | Center 20}}

To specify another character, specify it behind the string length:

{{FirstName | Center 20 _}}

ToLower

Converts a string to lower case.

{{FirstName | ToLower}}

ToUpper

Converts a string to upper case.

{{FirstName | ToLower}}

TrimLeft

Removes spaces on the left hand side of the string.

{{FirstName | TrimLeft}}

TrimRight

Removes spaces on the right hand side of the string.

{{FirstName | TrimRight}}

Trim

Removes spaces on the left and right hand side of the string.

{{FirstName | Trim}}

Other

Not

Inverts the value of a boolean.

{{#IsPublished | Not}}

Truesy

Converts a type to a boolean. The logic here is:

Converters

By default, PBars will use the .ToString() method on values that are not string to get the string representation. This may make sense in many cases, however when it comes to dates, decimal numbers and booleans, it makes more sense to perform explicit formatting. For this, the concept of converters comes into play. It converter is a specialized pipe, that is annotated with the type that it converts from and the name. All converters can be called without explicit parameters, most however offer additional parameters. By default - converters are registered for most primitive types. In addition you can add your own and replace existing ones. The CompilerOptions class has a property ConverterSettings that specifies the behavior of the default converters. In addition to implicitly using converters you can just specify them as explit pipes like this:

{{#Price | DecimalConverter}}

Number converters

Format strings are in the format used in string.Format: string.Format("{0:FormatString}",value) The culture specified in the ConverterSettings is used (defaults to CultureInfo.CurrentCulture).

Name Source type Parameters
DoubleConverter double format string (string.format); otherwise uses ConverterSettings.DecimalFormatString.
ByteConverter byte format string (string.format); otherwise uses ConverterSettings.IntegerFormatString.
DecimalConverter decimal format string (string.format); otherwise uses ConverterSettings.DecimalFormatString.
FloatConverter float format string (string.format); otherwise uses ConverterSettings.DecimalFormatString.
IntegerConverter integer format string (string.format); otherwise uses ConverterSettings.IntegerFormatString.
LongConverter long format string (string.format); otherwise uses ConverterSettings.IntegerFormatString.
SByteConvter sbyte format string (string.format); otherwise uses ConverterSettings.IntegerFormatString.
ShortConverter short format string (string.format); otherwise uses ConverterSettings.IntegerFormatString.
UIntConverter uint format string (string.format); otherwise uses ConverterSettings.IntegerFormatString.
ULongConverter ulong format string (string.format); otherwise uses ConverterSettings.IntegerFormatString.
UshortConverter ushort format string (string.format); otherwise uses ConverterSettings.IntegerFormatString.
LongConverter long format string (string.format); otherwise uses ConverterSettings.IntegerFormatString.

Date / time converters

Format strings are in the format used in string.Format: string.Format("{0:FormatString}",value) The culture specified in the ConverterSettings is used (defaults to CultureInfo.CurrentCulture).

Name Source type Parameters
DateTimeConverter DateTime format string (string.format); otherwise uses ConverterSettings.DateTimeFormatString.
DateTimeOffsetConverter DateTimeOffset format string (string.format); otherwise uses ConverterSettings.DateTimeOffsetFormatString.
TimeSpanConverter TimeSpan format string (string.format); otherwise uses ConverterSettings.TimeSpanFormatString.

Other converters

Format strings are in the format used in string.Format: string.Format("{0:FormatString}",value)

Name Source type Parameters
GuidConverter Guid format string (string.format); otherwise uses ConverterSettings.GuidFormatString.
BooleanConverter bool True display text, False display text; otherwise uses settings from ConverterSettings.

Encoders

Encoders allow to process the result of data expressions before rendering it to output. The most obvious use case here is HTML encoding. Encoders themselves are regular pipes. Predefines encoders are: HtmlEncode and UrlEncode. If you are using an auto encoder (next section). You need to combine the explicit encoding with the Raw pipe to prevent doulbe encoding.

Auto encoder

By default PBars does not assume that you want to safely encode for usage in HTML or any other markup style. However you can register an auto encoder which is applied against the output of data expressions before they are rendered into the document. Auto encoding happens at the end of the pipeline (after converters). If you want automatic HTML encoding, you may set the encoder on the CompilerOptions. As you may have already guessed, an autoencoder is just a pipe itself.

compilerOptions.AutoEncoder = new HtmlEncodePipe();

If you want to suppress the auto encoder explicitly, use the Rawpipe.

{{HtmlMarkup | Raw}

Nested templates and template registries

As shown in the basic usage section, templates can be nested using the {{#template}} directive. To be able make use of nested templates, you need to provide a template registry. Template names use a forward slash as a path delimiter and should alway have a file extension. The template registry is set on the CompilerOptions. Templates are only compiled once. Meaning you do not have a performance hit, when using the same template multiple times. PBars comes with two template registry implementations out of the box:

FileSystem

This registry will pull templates off the file system. The path will be translated relative to a given root directory.

compilerOptions.TemplateRegistry = new FileSystemTemplateRegistry(@"c:\");

This will set the root path of the registry to c:\. Let's assume, we embed a template like this:

{{#template myTemplates/template.txt}}

In this case the template registry will resolve to c:\myTemplates\template.txt.

EmbeddedResource

This registry will read templates from embedded resources inside an assembly. When initializing, you specify a "marker type", that defines the assembly and the root namespaces of all templates. Slashes will be translated to . effectively nesting namespaces.

compilerOptions.TemplateRegistry = new EmbeddedResourceTemplateRegistry(typeof(MarkerClass);

Assuming this template directive, template.txt will be pulled off the namespave below the MarkerClass type.

{{#template myTemplates/template.txt}}