-
-Ader
TemplateEngine is a .NET class library (written in C#) for generating text output from source template and input parameters.
-It can be used in many scenarios: website page building, email generation, xml generation, source code generation, etc.
-It's idea is based on antlr stringTemplate (http://www.stringtemplate.org/), but the syntax is based on cold fusion language.
-
-
-Currently only .NET AderTemplateEngine works with .NET 2.0 only, but I have plans on making it work with .NET 1.0/1.1 and maybe Java.
-This document is for version 2.1 of the engine. You can see version 1
here.
-
-Ader TemplateEngine is released under GNU General Public License.
-
-
Here is a very simple template:
-
-Thank You for your order #order.billFirstName# #order.billLastName#.
-<br>
-Your Order Total is: #format(order.total, "C")#
-<br>
-<ad:if test="#order.shipcountry isnot "US"#">
-Your order will arrive in 2-3 weeks
-<ad:else>
-Your order will arrive in 5-7 days
-</ad:if>
-
-
-The templates can have expressions, if/elseif/else statement, foreach statement, for statement, set statement and other templates.
-
-
-
Templates API:
-There are 2 classes mainly used in Template Engine: Template and TemplateManager.
-
-Template holds a single instance of a template and TemplateManager is used for executing templates.
-
-Easiest way of creating Templates is by using static methods of Template or TemplateManager:
-
-Template template = Template.FromString(string name, string data)
-Template template = Template.FromFile(string name, string filename)
-
-then you use it to instantilate TemplateManager.
-
-TemplateManager mngr = new TemplateManager(template);
-
-or even easier:
-
-TemplateManager mngr = TemplateManager.FromFile(filename);
-TemplateManager mngr = TemplateManager.FromString(template);
-
-when using FromString method, the string passed contains template code. This method can be used
-to dynamically generate text without having templates in files.
-
-You use SetValue(string name, object value); to add values that can be used within the templates.
-
-Ex:
-
-mngr.SetValue("customer", new Customer("Tom", "Jackson"));
-
-
-then you can refer to customer within the template. You can use any type of object for value.
-When the value of variable is to be output ToString() method will be called.
-
-
-
-
- Expressions
-
-Expressions are enclosed with # (hash or pound) characters:
-
-ex.
-
-#firstName#
-
-
-This example will output value of first name. If you need to output # character, just escape it with another #.
-
-ex.
-
-Your SS## is #ssnumber#
-
-
-Inside of expression block you can output any variable:
-
-#somevar#
-
-
-access property or field of a variable:
-
-#somestring.Length#
-
-
-property name is not case senstivie. So you can call: #string.length# or #string.LENGTH#
-
-
-or call a function:
-
-#trim(somename)#
-
-You can nest property accesses:
-#customer.firstname.length#
-
-You can also call methods on any objects:
-
-#firstname.substring(0, 5)#
-
-or
-
-#customer.isValid()#
-
-Version 2.1 also allows you to use array access from indexed variables:
-#somearray[3]# - gets 3rd element of array
-#hastable["somekey"]# - gets value of "somekey" from hashtable.
-You can use array access with any object that has indexer property.
-
-
-There are several built in functions and additional functions can be easily added.
-The built in functions are:
-
-
equals(obj1, obj2) - invokes equals method on obj1 with obj2 as parameter. Returns boolean value.
-
-
-
notequals(obj1, obj2) - Returns !equals(obj1, obj2). Is equavilant to calling: not(equals(obj1, obj2))
-
-
-
iseven(num) - tests whether number is an even number
-
-
-
isodd(num) - tests whether number is an odd number
-
-
-
isempty(string) - test whether string has 0 characters. Same as equals(string.Length, 0)
-
-
-
isnotempty(string) - tests whether string has at least 1 character.
-
-
-
isnumber(num) - tests whether num is of numeric type
-
-
-
toupper(string) - converts string to upper case
-
-
-
tolower(string) - converts string to lower case
-
-
-
isdefined(varname) - tests whether variable named varname is defined
-
-
-
ifdefined(varname, value) - returns value if varname is defined. Especiall useful: #ifdefined("name", name)# - will output value of name if it's defined, otherwise will output nothing
-
-
-
len(string) - returns length of string
-
-
-
tolist(collection, property, delim) - will convert collection to string with delim as seperator. If you pass property,
- the value of the property will be evaluated on each element of collection. If you omit property, then the object itself
- will be used.
-
- Ex:
-
- suppose you have list as:
-
-
- ArrayList list = new ArrayList();
- list.Add("one");
- list.Add("two");
- list.Add("three");
- template.SetValue("mylist", list);
-
- then in your template:
-
- #toList(mylist, " & ")#
-
- the output will be: one & two & three
-
-
- suppose you have list as:
-
- list.Add(new Customer("Tom", "Whatever"));
- list.Add(new Customer("Henry", "III"));
- list.Add(new Customer("Tom", "Jackson"));
- template.SetValue("mylist", list);
-
- then in template:
-
- #toList(mylist, "firstName", ",")#
-
- the output will be: Tom,Henry,Tom
-
-
-
-
isnull(obj) - tests whether obj is null
-
-
-
not(boolvalue) - returns not (!) of boolean value
-
-
-
iif(booleanExpression, iftruevalue, iffalsevalue) - same as
- booleanExpression ? iftruevalue : iffalsevalue in C#
-
- Ex:
-
- #iif(isodd(i), "bgcolor=yellow", "bgcolor=red")#
-
- will output bgcolor=yellow if i is odd number and bgcolor=red if i is not odd number
-
-
-
-
format(object, formatstring) - will call ToString(formatstring) on object. Object has to implement
- IFormattable interface, otherwise ToString() will be called.
-
- Ex:
-
- (suppose total is decimal with value 1208.45)
-
- #format(total, "C")#
-
- will output: $1,208.45
-
-
-
-
trim(string) - will trim string object
-
-
-
-
filter(collection, booleanproperty) - will return new List from collection for those objects
- whose booleanproperty property evaluates to true
-
-
-
gt(obj1, obj2) - will return true if obj1 > obj2 (obj1 and obj2 must implement IComparable. All numeric types do)
-
-
-
lt(obj1, obj2) - will return true if obj1 < obj2 (obj1 and obj2 must implement IComparable. All numeric types do)
-
-
-
compare(obj1, obj2) - will return -1 if obj1 < obj2, 0 is obj1 == obj2, and 1 if obj1 > obj2 (obj1 and obj2 must implement IComparable. All numeric types do)
-
-
-
or(bool1, bool2) - will return true if either bool1 or bool2 are true
-
- ex:
-
- #or(equals(state, "IL"), equals(state, "NY"))# - returns true if state is either IL or NY
-
-
-
-
and(bool1, bool2) - will return true if both bool1 and bool2 are true
-
-
-
-
comparenocase(string1, string2) - will do case insenstive comparison of string1 and string2 and return true if they are equal
-
-
-
-
stripnewlines(string) - will return all \r\n instances and replace them with space
-
-
-
typeof(object) - will return string representation of the type of object. Ex: typeof("hello") return "string". typeof(3) returns int
-
-
-
cint(value) - converts value to integer (internally used Convert.ToInt32 from .net library)
-
-
-
cdouble(value) - converts value to double
-
-
-
cdate(value) - converts value to DateTime type. You can use this function if you want to create datetime objects.
-Ex: #cdate("2005-5-1")#
-
-
-
createtypereference(type) - you can use this function to create references to static types so that you can access static properties or call methods of a static object.
-It's most useful when combind with <ad:set tag (explained below)
-
-#createtypereference("System.Math").Round(3.39789)#
-#createtypereference("System.Math").PI#
-or
-<ad:set name="MyMath" value="#createtypereference("System.Math")#" />
-#MyMath.Round(3.3)#
-#MyMath.PI#
-
-
-
-Version 2.1 also adds some operators for common expressions:
-
is - same as calling function equals. Ex: #obj1 is obj2# will return true if obj1 is equal to obj2.
-
-
-
isnot - same as calling function notequals. Ex: #obj1 isnot obj2#
-
-
-
and - used in if expressions tests (same as && in C#)
-
-
-
or - same as || in c#
-
-
-
lt,
lte,
gt,
gte - less than ("<" in C#), less than or equal ("<="),
-greater than (">") and greater than or equal (">="). Both operands have to implement IComparable interface. When using numeric types, they have to be of the same type.
-If you want to compare int to double, you have to convert int to double first using cdbl function.
-
-
-#varOne lt 3#
-#varTwo lte cdbl(3)#
-#varThree gt varFour and varFive gte 5.0#
-
-
-
-
Built In Tags:
-
-
IF
-
-You can also conditionally output text based on some expression using special if tag:
-
-<ad:if test="#booleanexpression#">
-
-<ad:elseif test="#bool#">
-
-<ad:else>
-
-</ad:if>
-
-elseif and else are optional. If test of "if" evaluates to true, then block inside of "if" will be output, otherwise
-elseif will be tested (if exists) and then else.
-
-Ex:
-
-
-<ad:if test="#cust.country is "US"#">
-You are US customer.
-<ad:else>
-You are from: #cust.country# country.
-</ad:if>
-
-If cust.country is "US" then the output will be: You are US customer.
-
-
-
FOREACH
-
-You can loop through collection of elements (any object that implements IEnumerable interface) using FOREACH tag.
-
-<ad:foreach collection="#collection#" var="cust" index="i">
-#i#: #cust.lastname#, #cust.firstname#
-</ad:foreach>
-
-
-Suppose customers is array of customer objects: customers = Customer("Tom", "Jackson"), Customer("Mary", "Foo")
-
-The output will be:
-
-1. Jackson, Tom
-
-2. Foo, Mary
-
-
-During execution, variable name that is passed as var attribute will be assigned with element from the collection.
-Index attribute can be omitted, and is used to represent index variable for the loop. It starts with 1 and gets
-increments with each iteration.
-
-
-
FOR
-
-You can use FOR tab to loop through integer values by one.
-
-<ad:for from="1" to="10" index="i">
-#i#: #customers[i].name#
-</ad:for>
-
-
-
-
SET
-
-Set tag allows you to set values based on other expressions:
-<ad:set name="var" value="#someexpression#" />
-After set statement is executed you can use var as if it was a local variable.
-It might be useful when accessing complex object values.
-Instead of writing:
-#customers[i].address.firstname# #customers[i].address.lastname# #customers[i].address.address1#
-You can do:
-lt;ad:set name="add" value="#customers[i].address#" />
-#add.firstname# #add.lastname# #add.address1#
-
-It's especially useful with createtypereference function (see above)
-
-
-
Custom Templates:
-
-You can also create your own templates inside of template file that you can call.
-You do that using template tag:
-
-<ad:template name="ShowCustomer">
-#customer.lastname#, #customer.firstname#
-</ad:template>
-
-<ad:showcustomer customer="#cust#" />
-
-You can pass any attributes to the template, and you can use those inside of the template.
-The template can also access all variables that are defined outside of the template.
-When calling template you have to put trailing slash at the end, or put closing tag:
-
-<ad:showcustomer />
-
-or
-
-<ad:showcustomer></ad:showcustomer>
-
-
-The template also received special variable: innerText that is the content of executing the inner elements of calling template.
-
-<ad:template name="bold">
-<b>#innerText#</b>
-</ad:template>
-
-<ad:bold>#cust.lastname#, #cust.firstname#</ad:bold>
-
-the output will be:
-<b>Jackson, Tom</b>
-(if customer is Tom Jackson)
-
-
-You can also nest those:
-
-<ad:template name="italic">#innerText#</ad:template>
-
-<ad:bold><ad:italic>This will be bold and italic</ad:italic></ad:bold>
-
-
-You can also invoke templates based on the name using apply tag:
-
-<ad:apply template="#usetemplate#">this is content</ad:apply>
-
-If usetemplate is "bold" then "bold" template will be called.
-
-
-Templates can be nested inside other template:
-
-<ad:template name="doit">
- <ad:template name="colorme">
- <font color=#color#>#innerText#</font>
- </ad:template>
-
-<ad:colorme color="blue">colorize me</ad:colorme>
-</ad:template>
-
-colorme template can only be used within doit template.
-
-Templates can also be added programmatically:
-
-TemplateManager mngr = ...;
-mngr.AddTemplate(Template.FromString("bold", "<b>#innerText#</b>"));
-
-now bold template can be used anywhere within processing.
-
-
-Version 2.0 adds ability to create custom tags in C# (or any .net language) that can extend the TemplateManager with additional functionality.
-Together with the sources is Example 2 which includes 2 custom tags
email for sending email and
base64 for base64 encoding content.
-
-Once those tags are registered with TemplateManger you can call them like:
-
-<ad:email from="andrew@adersoftware.com" to="someuser@example.com" subject="Hello" server="127.0.0.1">
-Hello #customer.firstname# #customer.lastname#
-</ad:email>
-
-
-Version 2 also added ITemplateHandler interface for better interaction with template execution. You can than set templateManager's Handler property to a handler,
-and this handler will be called before and after manager is done processing the template. This handler is also available as
this object, and you can access
-any property or call methods of the handler from within the template. Example 2 includes "MyHandler.cs" as an example on how to use it.
-
-
--------------------------
-Here is a sample based on order confirmation.
-
-
-class Order
-{
- string firstname, lastname, address1, city, state, zip, country;
-
- public string Address1
- {
- get { return this.address1; }
- }
-
- public string City
- {
- get { return this.city; }
- }
-
- public string Country
- {
- get { return this.country; }
- }
-
- public string Firstname
- {
- get { return this.firstname; }
- }
-
- public string Lastname
- {
- get { return this.lastname; }
- }
-
- public string State
- {
- get { return this.state; }
- }
-
- public string Zip
- {
- get { return this.zip; }
- }
-}
-
-Order order = GetOrder();
-TemplateManager mngr = TemplateManager.FromFile("order-confirmation.st");
-mngr.SetValue("order", order);
-System.IO.StringWriter writer = new System.IO.StringWriter();
-mngr.Process(writer);
-
-string emailBody = writer.ToString();
-
--------------------------------------------
-
-order-confirmation.st
-
--------------------------------------------
-
-
-<ad:showitem>
-#item.sku# - #item.name#<br>
-<ad:if test="#equals(item.qty, 1)#">
-Price: #format(item.price, "C")#<br>
-<ad:else>
-You bought #item.qty# items for #format(item.price, "C")#
- (total: #format(item.total, "C")#)
-</ad:if>
-</ad:showitem>
-
-#order.firstname# #order.lastname#<br>
-#order.address1#<br>
-<ad:if test="#isnotempty(order.address2)#">#order.address2#<br></ad:if>
-#order.city#, #order.zip# #order.state#
-<br>
-<table>
-<ad:foreach collection="#order.orderitems#" var="orderitem" index="i">
-<tr>
- <td>#i#.</td>
- <td bgcolor="#iif(isodd(i), "##DEDEDE", "white")#">
- <ad:showitem item="#orderitem#" />
- </td>
-</tr>
-</ad:foreach>
-</table>
-Shipping: #format(order.shipping, "C")#<br>
-Taxes: #format(order.tax, "C")#<br>
-Order Total: #format(order.total, "C")#<br>
-
---------------------------------------------
-
-Description of order-confirmation.st
-
-First showitem template is defined which shows a single line item of the order.
-item is passed as attribute to showitem.
-
-Then address is shown. Note how if is used to conditionally display second line of address with ending <br> tag.
-
-Then each line item of order is looped through using ad:forech tag.
-iif function is used to color everyother line with #DEDEDE color.
-
-
---------------------------------------------------
-
-Example #2 for constructing complex SQL queries:
-
---------------------------------------------------
-
-
-string[] cols = new string[]{"id", "name", "email"};
-TemplateManager mngr = TemplateManager.FromFile(file);
-mngr.SetValue("colums", cols);
-mngr.SetValue("tablename", "customer");
-string query = mngr.Process();
-
-and the template file is:
-
-
-select #toList(columns, ",")# from #tablename#
-
-
-
----------------------------------
-
-Example 1 project has 2 sample templates that are used to process the same data.
-First it outputs it as a C# class to the screen, then it uses html template to create
-html file.
-
-There are more examples in the includes source code distribution. Look at directories: Example 1, Example 2 and Tester.
-
-If you have any questions, you can use AderTemplates forums at
-
http://www.adersoftware.com/adertools/
-
-
-
Download Source Code (440KB)
-- includes full source code for the library, example program and simple GUI for testing templates.
-Solution is for VS2005 beta 2.
-
-
-Download Library Only (18KB)
-- includes only dll for library. Works with .NET 2.0 only.
-
\ No newline at end of file
diff --git a/lib/TemplateEngines/NVelocity-1.1.1/ASL - Apache Software Foundation License.txt b/lib/TemplateEngines/NVelocity-1.1.1/ASL - Apache Software Foundation License.txt
deleted file mode 100644
index e259b58..0000000
--- a/lib/TemplateEngines/NVelocity-1.1.1/ASL - Apache Software Foundation License.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-Apache License, Version 2.0
-
-Apache License
-Version 2.0, January 2004
-http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
-"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
-
-"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
-
-"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
-
-"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
-
-"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
-
-"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
-
-"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
-
-"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
-
-"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
-
-"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
-
- 1. You must give any other recipients of the Work or Derivative Works a copy of this License; and
-
- 2. You must cause any modified files to carry prominent notices stating that You changed the files; and
-
- 3. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
-
- 4. If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
-
-You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
diff --git a/lib/TemplateEngines/NVelocity-1.1.1/Changes.txt b/lib/TemplateEngines/NVelocity-1.1.1/Changes.txt
deleted file mode 100644
index ab16374..0000000
--- a/lib/TemplateEngines/NVelocity-1.1.1/Changes.txt
+++ /dev/null
@@ -1,2779 +0,0 @@
-1.1.1 (2010-10-12)
-==================
-- Included the NET40 (CP) binaries on the release package
-
-1.1.0 (2009-09-28)
-==================
-- Applied Rasmus Toftdahl Olesen's patch fixing NVELOCITY-ISSUE-24
- "Improved enum support"
-
-- Applied Enzo Lombardi's patch fixing NVELOCITY-ISSUE-36
- "LRUMap Collection is not correctly synchronized"
-
-- Fixed the AssemblyResourceLoader so that it allows the loader assembly to be passed as a string
- instead of a List