Integrating

From NDjango
Jump to: navigation, search

By itself NDjango is just a text processing engine. Given a template name it locates the template source and gives you back a text stream you can use to get the rendering result. No more no less. NDjango engine does not know or care about HttpRequests, HttpResponses, Urls, or anything else web - specific. It just interprets the template it has and generates the output stream substituting the data elements from the context as dictated by the template.

Sometimes this is all you need. If this is the case, refer to the Library page for detailed information on how to use the NDjango engine standalone.

It is more likely though, that you just want to use NDjango in some existing web environment. Currently out of the box NDjango supports two: Bistro and ASP.MVC.

Common Integration Points

Regardless of how or into what environment the NDjango engine is integrated, the following four pieces of information have to be provided:

  • Template loader - it knows where the template source can be found given the template name
  • Custom Tags - if any
  • Custom Filters - if any
  • Custom settings - if you are not happy with the defaults

If you use NDjango standalone, it is your reponsibility to do all four. For ready to use integration projects all of the four are preset in a way suitable for a specific environment. In particular, template loader in both ASP.MVC and Bistro, treat template names as relative urls. Also for both environments all you need to do to add custom tags/filters is to call method WithLibrary on the template manager provider for the dll(s) with the tag/filter implementations. See Customizing NDjango section for more details

Bistro

NDjango ships with an integration assembly named NDjango.BistroIntegration. Placing this assembly in the /bin folder of your application is all that is necessary to enable NDjango support.

Implementation note
To track the official django implementation, session values are exposed to the django context unqualified. That means that if your request context has a value named foo and so does your session, the NDjango integration will throw a runtime exception notifying you of the collision. This is a construct that bistro allows, and NDjango does not.
Something to remember
Bistro preloads the contents of the /bin directory, and then scans loaded assemblies. Be sure the NDjango integration assembly is present there, or explicitly loaded by your user code. If this is not done, Bistro will not see the assembly.
Implementation note
The bistro-specific format of the {% url %} tag is as follows: {% url path_expr [var_expr1,...,var_exprN] [as name] %}, where path_expr is an expression (string literal or variable) that returns a string formattable by String.Format, and var_expr1..N are expressions that supply parameters to the format placeholders, e.g. - {% url "hello/{0}" "world" as v %} {{ v }}, which will yield /virtualDir/hello/world

ASP.MVC

With version 0.9.8.0 ASP.MVC integration was changed to support new features. If you are still using 0.9.7 version of NDjango or older, here is a description of how to integrate with old releases of NDjango.

To integrate NDjango as a view engine for ASP.MVC you'll need to add a reference to the NDjango.ASPMVCIntegration40 or NDjango.ASPMVCIntegration40 assembly and make a small change to your Global.asax.cs:

  • Add a public member called DjangoTemplateManager:

<source lang="csharp"> public class MvcApplication : System.Web.HttpApplication { public NDjango.Interfaces.ITemplateManager DjangoTemplateManager { get; set; }

... } </source>

  • Add the following line inside Application_Start method

<source lang="csharp"> protected void Application_Start() { ...

ViewEngines.Engines.Insert(0, new NDjango.ASPMVC.DjangoViewEngine()); } </source>

You can also easily plug in your own tag library (-ies):

<source lang="csharp"> protected void Application_Start() { ...

ViewEngines.Engines.Insert(0, new NDjango.ASPMVC.DjangoViewEngine( provider => provider.WithLibrary("ASPMVCSampleLibrary.NDjangoExtension40") )); } </source>

... aand that's it. This will register the NDjango ASPMVC View Engine, and allow you to both infer view paths from controllers (standard behavior), and specify explicit template paths via ViewResult View(string viewName); instead of ViewResult View();. ".django" extension must be omitted.

Implementation note for 'url' tag
The asp.mvc-specific format of the {% url %} tag is as follows: {% url action_expr [controller_expr] [as name] %}, where action_expr is an expression (string literal or variable) that returns a valid action, and controller_expr is an optional expression that returns a controller name. These values are then fed into UrlHelper.Action(action[, controller]), e.g. - {% url "index" "home" as v %} {{ v }}, which will yield /virtualDir/home/index
You can also use 'action-link' tag which works the same as the standard Html.ActionLink method. This tag is defined in ASPMVCSampleLibrary.NDjangoExtension40.dll library which is provided with the NDjango setup.
Strongly typed views with a view model
Use tag 'model' for strongly typed views.The format of the tag : {% model <model_alias>:<namespace>.<class> %}
Use <model_alias>(for example, 'Model') in the template's body to reference its public members. Note you should specify fully qualified name for the model class not just the class name for the Intellisense in NDjango Editor to be available

Monorail (Castle Project)

You can get NDjango from the castle project contrib SVN: http://svn.castleproject.org:8080/svn/castlecontrib/viewengines/. You can get the source code from the src subfolder or the ready to use binaries from the bin subfolder.

To configure NDjango as a view engine for your Castle Monorail project make the following modifications to the web.config file:

  • In the <Monorail> section add <viewEngine> tag for the NDjango view engine as follows:

<source lang="xml"> <monorail ...> ... ... <viewEngines viewPathRoot="Views"> <add xhtml="false" type="Castle.Monorail.Views.NDjangoView.NDjangoViewEngine, Castle.Monorail.Views.NDjangoView"/> </viewEngines> </monorail> </source>

  • To prevent direct template browsing add the following entry to the /System.web/httpHandlers:

<source lang="xml"> <system.web> <httpHandlers> <add verb="*" path="*.django" type="System.Web.HttpForbiddenHandler"/> </source>

You'll also have to add to project references (or drop to the bin directory) the following assemblies:

  • Castle.Monorail.Views.NDjangoView.dll
  • NDjango.Core.dll
  • NDjangoFilters.NDjangoExtension.dll
  • FSharp.Core.dll (2.0.0.0)
  • FSharp.PowerPack.dll

These files can be found in the bin directory of the contribution project.

Also check out the sample project for an example of django templates including a very basic example of template inheritance.

Implementation notes

1. NDjango template inheritance provides a powerful way for template reuse. In our opinion it is a great alternative to way to implement functionality currently provided by Layouts and partial rendering support. Because of this in the current implementation

  • Layouts are not supported
  • Partial rendering is not supported

2. There is no special support for JavaScript templates – if necessary standard NDjango techniques can be used to template JavaScript files.

3. NDjango filters provide functionality very similar to the one of Monorail helpers In the cases if standard filters are insufficient, a new filter can be easily added. Combined with ability to call parameterless methods and properties on the context objects caused us to not include in the current implementation Castle helpers.

See also

How to integrate with old releases of NDjango

Customizing NDjango