Many template engines start out with a desire to separate presentation from logic. They allow users to push or pull values into the template and then they get stuck. Design is far more complex than setting a couple of values. Users need simple logical constructs and loops, maybe even variables, blocks and scopes, functions to reuse code, and so on ... In the end run, the template engine incorporates an entire language (JSP) or creates a new one (PHP). All this is based on the assumption that the logic provides data which is then decorated and rendered from within the template. However, a fundamental step is missing in the engine design, resulting in an overly complex model that doesn't separate presentation from logic anymore.
When data has been injected into a design, a template engine should allow external logic to retrieve the result and use the concrete version of the layed-out data for output and manipulation. This means that together with incorporating data, a template engine should also provide results and be able to work in a bidirectional fashion instead of the limited common unidirectional approach.
Now the template engine has become extremely simple, no need to integrate any kind of logical constructs or loops. The same logic that provided the data is able to select or repeat results easily. It can extract and combine them and if the template engine is powerful enough, use it as a scratchpad to assemble all the pieces of the layout in an efficient manner. All the required information is already available in the logic. There's also no need to worry anymore about how much logic can bleed into a template and how much has to stay out of it. The entire template becomes totally language independent and designer-friendly.