Use same variable name as inherited block name in Mako? - bottle

I've stumbled upon a problem with inheritence in Mako. I'll try to illustrate the problem below using two template files...
base.tpl - has a named block title:
<title><%block name="title"></%block></title>
foo.tpl - inherits from base.tpl and sets the title:
<%inherit file="base.tpl" />
<%block name="title">${title}</%block>
The template is rendered (using Bottle) with:
...
return mako_template('foo', title="My title")
Now I expected the output to be
<title>My title</title>
but instead it becomes:
<title><function render_title.<locals>.title at 0x0346A1E0></title>
Any clues? Using a different variable name than the block works.. but I'd like to use the same if possible!

Using this instead works:
<%block name="title">${context["title"]}</%block>
Does anyone know why?

Related

Property Binding: How to Concatenate String Literals and Binding Value

I have a StandardItemList in UI5 like this
new sap.m.StandardListItem({
title: "{BOM/#text}",
description: "Version: " + "{REVISION/#text}"
})
How can I achieve getting the description like "Version: ValueOfTheVersion"?
When I delete the word "Version" in the description it works very well.
To enable complex binding syntax, the recommended way is to add the bootstrap configuration option compatVersion with the value "edge". E.g. in index.html:
data-sap-ui-compatversion="edge"
This replaces the need for sap-ui-xx-bindingSyntax since "edge" sets the binding syntax automatically to "complex". Adding bindingSyntax makes only sense if the compatVersion is lower than "1.28". Options with xx should be avoided anyway because they're experimental.
With the complex binding syntax enabled, we can make use of
sap.ui.model.CompositeBinding which includes Expression Binding
as well as plain "{path: '...'}" syntax in XML UI definitions (views or fragments).
Thanks to Rahul!
Adding
data-sap-ui-xx-bindingSyntax="complex"
to the bootstrap in your index.html will do the trick
Full Solution
<script src="/sapui5/resources/sap-ui-core.js"
id="sap-ui-bootstrap"
data-sap-ui-xx-bindingSyntax="complex"
data-sap-ui-libs="sap.m,sap.ui.layout,sap.ui.commons,sap.ui.table"
data-sap-ui-theme="sap_bluecrystal">
</script>

Using the output of a partial as a variable in main template

Out of this question: Random image with v:iterator.random | cache issue
I use a partial to render non-cacheable stuff (in this case a random image).
I do this with this code in the main-template:
{v:render.uncache(partial: 'Random-Image', arguments: {iterator: images})}
Have this directly in the template outputs the right thing (the url to an image, for example fileadmin/upload/abc.jpg). But if I want to use this as a variable for the src from <f:image it does not work:
<f:image src="{v:render.uncache(partial: 'Random-Image', arguments: {iterator: images})}" alt="alt text" />
Also set as a variable it with v:variable.set does not work.
All I get is: <!--INT_SCRIPT.0081e57d9fd92c925bb35d79fd9d3f79-->
Also when I debug it:
<f:debug>
{v:render.uncache(partial: 'Random-Image', arguments: {iterator: images})}
</f:debug>
I get <!--INT_SCRIPT.0081e57d9fd92c925bb35d79fd9d3f79-->
So, is it possible to use the output of a partial as a variable? Or is it possible to set a variable in the partial and use it in the main-template?
I think you mixed up two things a bit, so I would like to separate your questions:
1) Is it possible to use the output of a partial as a variable?
Yes, like the way you wanted it. Actually you did it.
But let see a test:
There is a Partial : Test/Message
With the content: "It is a test"
Then in the main template you can use something like this:
<div class="test">
<f:if condition="{f:render(partial:'Test/Message')}
== 'It is a test'">
<f:then>Passed</f:then>
<f:else>Failed</f:else>
</f:if>
</div>
In this case you would see "Passed" and if you change the Partial to "It should failed" then you will get "Failed" rendered.
2) Why do you see <!--INT_SCRIPT.0081e57d9fd92c925bb35d79fd9d3f79--> ?
This is a not cached content, so like COA_INT or USR_INT objects in TypoScript.
You can find a function in the typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php its name is INTincScript_process. It is responsible to find such lines in the code and replace them with the not cached content.
It means, if you render your Template, that partial renders only a reference to a not cached object, but not the content itself.
Finally to suggest a solution to the original problem, try to render the whole image inside the partial not just the path to it. So include the into the partial where the v:iterate.random ViewHelper is used. Then the v:render.uncache should mark the whole image block as not cacheable.

Using ViewHelper inside a partial path

I'm working on a new extension and my model has the attribute 'type' which can get different strings from the TCA form. Strings only!
The name of the partial that my template should load is inside the 'type' attribute from my model. So here comes my problem. Since TYPO3 4.7.x the .html file names for fluid have to start with an uppercase letter. Inside the 'type' attribute the name of the partial that should be loaded is always lowercase. For that, I wrote a simple view helper that contains only this method:
public function render($string) {
return ucfirst($string);
}
Inside my template I tried to use this view helper for the path to the partial:
{namespace vh=Tx_MyExtension_ViewHelpers}
<f:for each="{obj.subObjects}" as="sub">
<f:render partial="OtherObject/{vh:String.UpperFirstCharacter(string:'{sub.type}')}" arguments="{sub:sub}" />
</f:for>
If I try to load this in the fontend, nothing from my extension will be rendered and there are no error messages anywhere. The problem depends on my view helper, 'cause even if I try to load only this:
{vh:String.UpperFirstCharacter(string:'test')}
{vh:String.UpperFirstCharacter(string:'{sub.type}')}
There is nothing comming back. If I only output {sub.type} it shows me the string that I want, but in lowercase.
Obviously your problem is that you're ViewHelper doesn't do what you want it to do.
First of all, ViewHelper names are to be written in lowerCamelCase.
Second, you don't need to place sub.type in curly braces:
This syntax...
{vh:string.upperFirstCharacter(string:sub.type)}
... should be sufficient.
Fluid will then look for a ViewHelper named
Tx_MyExtension_ViewHelpers_String_UpperFirstCharacter
or namespaced
\My\Extension\ViewHelpers\String\UpperFirstCharacter
Please check that this is the case.
So I found the issue. Fluid can't handle namespaces. So first my ViewHelper looked like this:
<php
namespace TYPO3\MyExtension\ViewHelpers\String;
class UpperFirstCharacterViewHelper ...
Now I changed the name of my class and removed the namespace:
<php
class Tx_MyExtension_ViewHelpers_String_UpperFirstCharacterViewHelper ...
This is how it works. At the moment I work with TYPO3 6.1.6.
Thank you anyway lorenz for your help!
EDIT:
I went fully retarded! Fluid CAN handle namespaces. I just had to set the namespace the right way.
That's how you set the namespace inside the template:
{namespace vh=TYPO3\MyExtension\ViewHelpers}
On top of this comment you can see how my ViewHelper looks like with a namespace.

Set class or ID on <h:inputHidden> in JSF

I'm trying to set a class or id parameter on a <h:inputHidden> in JSF. The code looks like this:
<h:inputHidden value="#{getData.name}" class="targ" />
But in the browser, the class isn't set:
<input type="hidden" name="j_idt6" value="j_idt6">
I need to set a class to this parameter, because I have a JavaScript autocomplete function for a <h:inputText> that sets a value in the hidden input, which needs to be passed in the next page.
Any ideas? Thanks!
I know it's a little bit late, but it can help someone in the future.
As inputHidden shows nothing in the browser there's no sense to allow it to have a class.
You can use the Id but as the Id could change as you change the component parents using it would bring some headache.
I'd suggest as a workaround, you can give it a parent so you can manipulate it by javascript.
Exemple:
JSF
<h:panelGroup styleClass="someCssClass">
<h:inputHidden id="someId" value="someValue" />
</h:panelGroup>
Javascript (using jQuery, you could use pure javascript also)
$('.someCssClass input[type=hidden]').val('yourNewValue');
None of these answers here satisfied my needs (need the PrimeFaces component, need class not ID, wrapping is too much work), so here's what I came up with:
Use pass-through attributes: https://www.primefaces.org/jsf-2-2-pass-through-attributes
Use pass:hidden-class="blah" (in my case, it's xmlns:pass up top)
Use [attribute=value] selector:
https://www.w3schools.com/cssref/sel_attribute_value.asp
document.querySelector multiple data-attributes in one element
That basically boils down to using something like this (because h:inputHidden becomes a regular input): document.querySelector("input[hidden-class=" + blah + "]")
Please, see similar question - How can I know the id of a JSF component so I can use in Javascript
You can sed "id" property, but in final html code it can be not the same, but composite: for example, if your input with id="myhidden" is inside form with id="myform", final input will have id="myform:myhidden".
In the end, I used a standard HTML <input type="hidden"> tag, as I had no advantages for using the JSF one. If you're trying to set a value in a hidden input with JavaScript, I recommend using this workaround.

Why bindings do not work?

<textbox id="nextTitleTextbox" readonly="true" value="#bind(ivm.inventory.successorTitleName)" />
<button id="nextTitleButton" label="..." mold="trendy" onClick="#command('chooseFormerOrSuccessor', isFormer = false)"/>
<a id="nextTitleHrefView" href="/inventory_new.do?method=edit&docUID=${ivm.inventory.successorTitleName}">view</a>
<a id="nextTitleHrefHistory" href="javascript:showRenamingHistory(${ivm.inventory.successorTitleName},${ivm.inventory.successorTitleName})">history</a>
The problem is in 'a' tags. Textbox and buttons works fine, but links in 'a' tags do not catch information from binding, so link there looks like /inventory_new.do?method=edit&docUID=. I really don't understand what's wrong here, because I tried a lot of combination and something similar is working on other pages. Where is mistake in this binding?
I even tried to put string from zscript
<zscript>
String successorTitleHref = "/inventory_new.do?method=edit&docUID=" + ivm.inventory.successorTitleName;
</zscript>
But got exception:
Typed variable declaration : Class or variable not found: ivm.inventory.replacementTitleName.
Also, it's supported controls, that locates in separate file, and every control adding with use derective.
Binding in ZK has nothing to do with variable replacement. #bind() doesn't mean you can use ${...}. The two are completely separate concepts even though both are called "EL Expression" in the manual. But binding EL Expression and ZUML EL Expressions are two different things.
To allow access to ivm in a zscript, you need to define this variable somewhere in the script. One way is to instantiate it:
IVM ivm = new IVM();
or you can use a custom variable resolver.