Sharing non-layout templates between apps using Meteor - templates

I have two meteor apps. Each one has a smart-package that implements a certain feature, lets say user management, in an app-specific way. I also have a third meteor smart package that lives in a shared package directory. This third package has user management templates that are common to both apps. I use iron-router.
I need to combine the shared templates with the app templates. Iron-Router has the yield keyword. This is useful for combining templates. The problem is that this only works for special, nominated layout templates.
How do you combine, or nest, templates that are not layout templates using meteor and iron-router?
Example
In the simplified example below you can see three packages and their corresponding templates. The app-*:user packages implement app specific user templates and the shared:user package implements a shared user template.
app-1:users
appUser.tpl.jade
p This is some App-1 specific text
app-2:users
appUser.tpl.jade
p This is some App-2 specific text
shared:users
user.tpl.jade
h1 This is a shared title
+appUser
routes.coffee
Router.route '/user', name: 'user'
The problem here is that the nested template must be called appUser in both the dependent smart packages. This not only prevents the templates name being appropriately descriptive for the app but, more worryingly, tightly couples the template name and makes for fragile code.
It is to prevent this tight coupling of templates that iron-router allows us to use the yield keyword, but since we cannot use the yield keyword in this context (can we?) then I am left wondering if this truly is the only way to implement shared templates?

You're probably going to benefit from dynamic templates. These are templates whose name can be passed in via a helper (defined globally or tied to the parent template) and whose data context can even be set by a helper.
{{> Template.dynamic template=myTemplate [data=myData] }}
Your code supplies myTemplate and myData dynamically here and the kerbobble (html, helpers, event handlers) then gets stuffed into the parent template.

Related

Retrofitting inheritance into a Sitecore template

Can anyone tell me if its possible to retrofit inheritance into a Sitecore template?
I have a task to add a new page field into multiple existing templates and I think this should be in a base template.
I've also noticed that the existing templates have fields that should be moved to a base template and then inherited from. Is this possible and if so will there be any side effects with existing code / data?
Yes, it's absolutely ok to add extra base templates to existing Sitecore templates.
E.g. if you already have multiple "page" templates and you need to add extra token for some tracking, you can create new template (let's say "ICustomTracking") and then add it to base templates of your page templates.
To answer your second question: you can "extract" base templates from the existing templates. If you don't want to loose any data, the order of your actions is:
Create new base template
Set this template as a base template for all templates you want it to inherit from.
Move field item from the inheriting template to the base template.
Make sure you move the field item. If you remove the field, and add a new one later, most probably all the data will be lost.
Also it's not recommended to build too complex inheritance structures. It won't be easy to maintain that in the future.

How does Django handle template name clashes?

...when several apps define similarly named templates outside of a proper hierarchy. Thank you.
The template loaders are applied in the order you've defined in settings.TEMPLATE_LOADERS.
For example, if you have the app_directories loader running AFTER the filesystem loader and your template is located in the filesystem loader, the app_directories loader will never be used.
If you're talking about the app_directories loader specifically, it searches your app template folders in the order they are defined in INSTALLED_APPS.
If you have conflicting template names that are not on purpose (not some kind of override hierarchy), chances are you are better off prefixing each template folder with the app name.
# this is standard
myapp/templates/myapp/index.html
myapp2/templates/myapp2/index.html
Not exactly clear on what you mean. When you are specifying a template you should name it appropriately and specify it exactly. If you mean something like the admin that chooses the "best" template from a list of templates, it's uses a simple algorithm to find the best match. It does this simply by passing a list of templates to loader.select_template and the first one that is valid is used.

How to implement an adapter framework in C++ that works in both Linux and Windows

Here is what I am trying to do:
I am developing a cross-platform IDE (Linux and Windows) that supports plug-ins. I need to support extensibility using an adapter framework similar to the one that Eclipse provides. See here for more details, but basically I need the following:
Let Adaptee and Adapted be completely unrelated classes which already exist and which we are not allowed to change in any way. I want to create an AdapterManager class which has a method
template <class Adaptee, class Adapted> Adapted* adapt( Adaptee* object);
which will create an instance of Adapted given an instance of Adaptee. How exactly the instance is created depends on an adapter function which will have to be registered with AdapterManager. Each new plug-in should be able to contribute adapter functions for arbitrary types.
Here are my thoughts about a possible solution and why it does not work:
C++11's RTTI functions and the type_info class provide a hash_code() method which returns a unique integer for each type in the program. See here. Thus AdapterManager could simply contain a map that given the hash codes for the Adaptee and Adapter classes returns a function pointer to the adapter function. This makes the implementation of the adapt() function above trivial:
template <class Adaptee, class Adapted> Adapted* AdapterManager::adapt( Adaptee* object)
{
AdapterMapKey mk( typeid(Adapted).hash_code(), typeid(Adaptee).hash_code());
AdapterFunction af = adapterMap.get(mk);
if (!af) return nullptr;
return (Adapted*) af(object);
}
Any plug-in can easily extend the framework by simply inserting an additional function into the map. Also note that any plug-in can try to adapt any class to any other class and succeed if there exists a corresponding adapter function registered with AdapterManager regardless of who registered it.
A problem with this is the combination of templates and plug-ins (shared objects / DLLs). Since two plug-ins can instantiate a template class with the same parameters, this could potentially lead to two separate instances of the corresponding type_info structures and potentially different hash_code() results, which will break the mechanism above. Adapter functions registered from one plug-in might not always work in another plug-in.
In Linux, the dynamic linker seems to be able to deal with multiple declarations of types in different shared libraries under some conditions according to this (point 4.2). However the real problem is in Windows, where it seems that each DLL will get its own version of a template instantiation regardless of whether it is also defined in other loaded DLLs or the main executable. The dynamic linker seems quite inflexible compared to the one used in Linux.
I have considered using explicit template instantiations which seems to reduce the problem, but still does not solve it as two different plug-ins might still instantiate the same template in the same way.
Questions:
Does anyone know of a way to achieve this in Windows? If you were allowed to modify existing classes, would this help?
Do you know of another approach to achieve this functionality in C++, while still preserving all the desired properties: no change to existing classes, works with templates, supports plug-ins and is cross-platform?
Update 1:
This project uses the Qt framework for many things including the plug-in infrastructure. Qt really helps with cross platform development. If you know of a Qt specific solution to the problem, that's also welcome.
Update 2:
n.m.'s comment made me realize that I only know about the problem in theory and have not actually tested it. So I did some testing in both Windows and Linux using the following definition:
template <class T>
class TypeIdTest {
public:
virtual ~TypeIdTest() {};
static int data;
};
template <class T> int TypeIdTest<T>::data;
This class is instantiated in two different shared libraries/DLLs with T=int. Both libraries are explicitly loaded at run-time. Here is what I found:
In Linux everything just works:
The two instantiations used the same vtable.
The object returned by typeid was at the same address.
Even the static data member was the same.
So the fact that the template was instantiated in multiple dynamically loaded shared libraries made absolutely no difference. The linker seems to simply use the first loaded instantiation and ignore the rest.
In Windows the two instantiations are 'somewhat' distinct:
The typeid for the different instances returns type_info objects at different addresses. These objects however are equal when tested with ==. The corresponding hash codes are also equal. It seems like on Windows equality between types is established using the type's name - which makes sense. So far so good.
However the vtables for the two instances were different. I'm not sure how much of a problem this is. In my tests I was able to use dynamic_cast to downcast an instance of TypeIdTest to a derived type across shared library boundaries.
What's also a problem is that each instantiation used its own copy of the static field data. That can cause a lot of problems and basically disallows static fields in template classes.
Overall, it seems that even in Windows things are not as bad as I thought, but I'm still reluctant to use this approach given that template instantiations still use distinct vtables and static storage. Does anyone know how to avoid this problem? I did not find any solution.
I think Boost Extension deals with exactly this problem domain:
http://boost-extension.redshoelace.com/docs/boost/extension/index.html
(in preparation for this library's submission to Boost for review)
In particular you'd be interested in what the author wrote in this blog post: "Resource Management Across DLL Boundaries:
RTTI does not always function as expected across DLL boundaries. Check out the type_info classes to see how I deal with that.
I'm not sure whether his solution is actually robust, but he sure gave this thought, before. In fact, there are some samples using Boost Extensions that you can give a go, you might want to use it.

Editing T4 poco template to implement custom interface

I am using the Poco generator with EF4 and I am wondering if it is possible to edit the T4 template to force all of my entity classes to implement a custom interface. Since the pocos get blown away and recreated each time the custom tool is run, I would have to add this upon each update - I would sure like to avoid that.
I realize I could create partial classes for each poco and implement the interface there, but I was hoping to avoid all that boilerplate code.
Any suggestions would be welcome.
I think I am getting closer to a solution. I am editing the tt template by adding the implemenatation to the signature that is generated.
<#=Accessibility.ForType(entity)#> <#=code.SpaceAfter(code.AbstractOption(entity))#>partial class <#=code.Escape(entity)#> : IEntity<#=code.StringBefore(" , ", code.Escape(entity.BaseType))#>
But I have hit a bit of a snag. Some of my entities have base classes (table inheritance) that I designated in the edmx design. I have need to force all the entities to implement an interface called IEntity. The IEntity contract has no methods so there really is nothing to implement. I will need to rely on all of the entities having a common base. This is due to a completely separate implementation of a custom validation framework. I am getting the proper signatures for most of the entities, however, the entities that already have a base class are throwing a wobbly because you cant implement an interface before you inherit a base class. :IEntity, BaseClass is not allowed. I need to swap those but am not sure how I would pull that off in the template.
On perusing the code in the CodeGenerationTools class that the T4 template uses (found in the include file EF.Utility.CS.ttinclude), I came across this function StringAfter(string value, string append). Therefore, the answer is quite simple, since you state all your entities have to implement IEntity, the following should do the trick:
<#=Accessibility.ForType(entity)#> <#=code.SpaceAfter(code.AbstractOption(entity))#>partial class <#=code.Escape(entity)#> : <#=code.StringAfter(code.Escape(entity.BaseType), "," )#> IEntity
In fact, I know it does because I've tested it :-)
After the T4 template is added to your application, it becomes part of your app and as any other part of the app, you can do whatever you want with it. If for some reason, you don't want to modify the VS added template, make a copy of it and update this to include only the interface implementation. The second way would produce another set of partial files with the custom interface being implemented.
Dont know if this is near what you need but....
I´ve created a Nuget Package that scaffold tiers from T4-templates.
There are default templates for all interfaces (Repository Pattern and UnitOfWork), but you can edit these templates yourself and re-scaffold your system.
To keep it short.. You just install the package (Install-Package CodePlanner) and then define your domainmodel.. And then run "Scaffold CodePlanner.ScaffoldAll"
Its open source (codeplanner.codeplex.com)
Demo: http://average-uffe.blogspot.com/2011/11/codeplanner-011-released-on-nuget-and.html
Edit: The codeplanner package is built for MVC3!
Regards
Uffe

Django templatetag scope forcing me to do extra queries

The problem is that if I call a templatetag into a block
and it fills me a variiable with the usual context[varname]=something,
then if I need that variable into another block, I have to call the
templatetag again. This for me means extra db queries, which is really
something I'm trying to avoid.
This templatetag is called in a base template which is extended by
many other templates, so I can't just change all the views to pass
something to the context, it makes no sense (WET principle?)
Even a context processor would be not good because I don't want to
call it for every page rendered in the site, even the ones not based
on that template.
I was thinking about writing a templatetag which would use the
internal context structures to put the variable in a global context,
but I'd feel too guilty doing it.
How would you solve this problem?
You said, "This templatetag is called in a base template which is extended by many other templates."
The question is: is this tag called from within a named block? If it is then you have a couple of potential problems.
{% block %} pushes a new dict on the Context stack and pops it off when it reaches the matching `{% endblock %}'. This means any context value created while in the block has essentially gone out of scope on block exit.
If this block is overridden by some other template that extends the base template, the value may not be available at all unless you do a {{block.super}}, and even then I'm not certain the value will be available to the template doing the extending.
If the tag is not called from within a {% block %} then the context value should be available to all of the code that follows it, either in the base template, any included templates and (I think) any extending templates.
This is one of those cases where building a set of careful tests will probably save you time and tears.
Alternatively, if you are always accessing this value, you could just put it in a context processor so that its availability is guaranteed.
Update for comments: OK, time to bring in the big guns! One of the most irritating, long-standing bugs in Django templates is that callables (ie. functions) that are top-level context values (as opposed to functions that are dict-values/methods of context values) are not called! This ticket is over 2 years old and takes about 10 lines of code to fix. We have several heavy-weight DB calls that we only want to happen if the template cache has expired. So we a) MonkeyPatched the template _resolve_lookup() code to fix the callable problem, and then b) curry functions to have all of the necessary parameters if needed, because you can't pass params to functions in the template "language".
I think you've accurately described the limitations in this situation. The most maintainable solutions will likely involve some restructuring of your template inheritance chain, though its hard to say without knowing the details. Can you introduce a new template in the inheritance hierarchy, probably somewhere near the top of the pyramid but so it only is inherited by templates that need this data, with a single block that encompasses the entire region within which you need this data? That big block can then be subdivided into smaller blocks that inheriting templates will override. If you call your templatetag at the beginning of that block, all blocks within it (including in inheriting templates) will have access to the data.
Update: I can't say much without seeing your templates, but introducing a new template in the middle of an inheritance chain very rarely involves "changing all the templates," in a sane inheritance structure it often can be done with changes to only one or two other templates. And I think what I am suggesting is actually not a hack, it's just better design. If you need a certain piece of data in certain parts of your site and not other parts, there should be a specific single template you can point to and say "this template represents the logical layer at which this piece of data is introduced, and encompasses the parts of the site where that data is needed."
Are you just trying to keep down the number of database queries or are you looking for a clever solution?
If it's the former, I would definitely go with caching. Would fragment caching work in your case? If not, perhaps you could put the caching in the template tag code (assuming it's not one of Django's own template tags your using)?
Just came across this trick from Liviu, Agile Bear (all credit goes to him)
Instead of doing
context['some_var']='some value'
do
context.dicts[0]['some_var']='some value'
May not be a by-the-book-coding-practice but works well enough