Freemarker - replace & with & - freemarker

If i have the & symbol in some field (from a db, cannot be changed), and i want to display this via freemarker... but have the display (from freemarker) read &, what is the way to do so?
To reiterate, I cannot change the value before hand (or at least, I don't want to), i'd like freemarker to "unmark" &.
To double re-iterate, this is a value that is being placed with a lot of other xml. The value itself is displayed on its own, surrouded by tags... so something like
<someTag>${wheeeMyValueWithAnAmpersand}<someTag>
As a result, i don't want all ampersands escaped, or the xml will look funny... just that one in the interpolation.

Oh goodness.
I see the problem: the code was written like this:
<#escape x as x?xml>
<#import "small.ftl" as my>
<#my.macro1/>
</#escape>
and at which i'd assumed that the excape would excape all the calls within it - it is certainly what the documentation sort of implies
http://freemarker.org/docs/ref_directive_escape.html
<#assign x = "<test>"> m1>
m1: ${x}
</#macro>
<#escape x as x?html>
<#macro m2>m2: ${x}</#macro>
${x}
<#m1/>
</#escape>
${x}
<#m2/>
the output will be:
<test>
m1: <test>
<test>
m2: <test>
However it appears that when you import the file, then this isn't the case, and the escape... escapes!
SOLUTION:
http://watchitlater.com/blog/2011/10/default-html-escape-using-freemarker/
the above link details how to solve the problem. In effect, it comes down to loading a different FreemakerLoader, one that wraps all templates with an escape tag.
class SomeCoolClass implements TemplateLoader {
//other functions here
#Override
public Reader getReader(Object templateSource, String encoding) throws IOException {
Reader reader = delegate.getReader(templateSource, encoding);
try {
String templateText = IOUtils.toString(reader);
return new StringReader(ESCAPE_PREFIX + templateText + ESCAPE_SUFFIX);
} finally {
IOUtils.closeQuietly(reader);
}
}
which is a snippet from the link above. You create the class with the existing templateLoader, and just defer all the required methods to that.

Starting from FreeMarker 2.3.24 no TemplateLoader "hack" is needed anymore. There's a setting called output_format, which specifies if and what escaping is needed. This can be configured both globally, and/or per-template-name-pattern utilizing the template_configurations setting. The recommend way of doing this is even simpler (from the manual):
[...] if the
recognize_standard_file_extensions setting is true (which is the
default with the incompatible_improvements setting set to 2.3.24 or
higher), templates whose source name ends with ".ftlh" gets "HTML"
output format, and those with ".ftlx" get "XML" output format

Related

Removing Class Name of an element using element.className.replace method

var divfoo=document.getElementById("foo");
divfoo.className=" css-class css-class2 ";
divfoo.className=divfoo.className.replace(" css-class2 ", "");
The above code works. but I would like to make changes to last line of above code which is using replace method. Instead of writing the code like above, I would like to know why doesn't it work when written like below.
var divfoo=document.getElementById("foo");
divfoo.className=" css-class css-class2 ";
divfoo.className.replace(" css-class2 ", "");
Why should one assign to "divfoo.className" when applying replace method to the same "divfoo.className", why can't we just apply method directly like above code did?
Because of this should I hate javascript for not being logical?
enter code here
Element.className is a plain string representation of class HTML attribute.
String.replace method does not change the source string that is called on, just returns the result of replacement procedure.
If you want more "logical / functional" approach, look at Element.classList interface, namely the remove method.

Disallow DTD's while evaluating xpath

I have below code to evaluate xpath expression.
String inputXml = "<?xml version=\"1.0\"?><!DOCTYPE document SYSTEM \"test.dtd\"><Request><Header><Version>1.0</Version></Header></Request>";
String xpath="/Request/Header/Version";
XPathFactory xpf = new net.sf.saxon.xpath.XPathFactoryImpl();
final InputSource is = new InputSource(new StringReader(inputXml));
String version = xpf.newXPath().evaluate(xpath, is);
xpf.newXPath().evaluate throws error as test.dtd couldn't be found. I want to disallow DTD completely. I have been reading about setting SAXParser feature "http://apache.org/xml/features/disallow-doctype-decl" but not sure how to apply in this case or is there any other way to disallow/ignore DTD's.
I'm not quite sure what you want to achieve. If you want this to fail because there is a DTD referenced, then you already seem to be achieving that.
However, if you want to set a property on the XML parser, there are two ways you could achieve it:
(a) Supply a SAXSource rather than an InputSource; initialize the XMLReader in the SAXSource to the XML parser you want to use, and use the XMLReader's setFeature interface to configure it before you pass it to the XPath engine.
(b) Set the Saxon configuration feature http://saxon.sf.net/feature/parserFeature?uri=http://apache.org/xml/features/disallow-doctype-decl (that's a single string with no spaces or newlines) to the value true. You can do this using
xpf.getConfiguration().setConfigurationProperty(featureName, true);

How to return localized content from WebAPI? Strings work but not numbers

Given this ApiController:
public string TestString() {
return "The value is: " + 1.23;
}
public double TestDouble() {
return 1.23;
}
With the browser's language set to "fr-FR", the following happens:
/apiController/TestString yields
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">The value is: 1,23</string>
/apiController/TestDouble yields
<double xmlns="http://schemas.microsoft.com/2003/10/Serialization/">1.23</double>
I would expect TestDouble() to yield 1,23 in the XML. Can anyone explain why this isn't the case and, more importantly, how to make it so that it does?
It is because the conversion from double to string happens at different stage for each API. For the TestString API, double.ToString() is used to convert the number to a string using CurrentCulture of the current thread and it happens when the TestString method is called. Meanwhile, the double number which is returned by TestDouble is serialized to string during the serialization step which uses GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.Culture.
In my opinion, both should use InvariantCulture. On the consumer side, the values will be parsed and be formatted with the correct culture.
Update: this is only used for JsonFormatter. XmlFormatter doesn't have such a setting.
Update 2:
It seems (decimal) numbers need special converter to make it culture-aware:
Handling decimal values in Newtonsoft.Json
Btw, if you want o change data format per action/request, you can try the last piece of code of the following link: http://tostring.it/2012/07/18/customize-json-result-in-web-api/

Generate HTML documentation for a FreeMarker FTL library

I've a FreeMarker library that I want to ship with my product, and I'm looking for a way to generate a HTML documentation for it based on the comments in the FTL file (in a Javadoc fashion).
For example, a typical function in my library is written like:
<#--
MyMacro: Does stuff with param1 and param2.
- param1: The first param, mandatory.
- param2: The second param, 42 if not specified.
-->
<#macro MyMacro param1 param2=42>
...
</#macro>
I didn't find anything on that subject, probably because there is no standard way of writing comments in FreeMarker (Such as #param or #returns in Javadoc).
I don't mind rolling my own solution for that, but I'm keen on using an existing system like Doxia (since I'm using Maven to build the project) or Doxygen maybe, instead of writing something from scratch.
Ideally I'd like to write the comment parsing code only, and rely on something else to detect the macros and generate the doc structure.
I'm open to changing the format of my comments if that helps.
In case you decide to write your own doc generator or to write a FTL-specific front-end for an existing document generator, you can reuse some of FreeMarker's parsing infrastructure:
You can use Template.getRootTreeNode() in order to retrieve the template's top level AST node. Because macros and the responding comments should be direct children of the this top level node (IIRC), iterating over its children and casting them to the right AST node subclass should give you almost everything you need with respect to FTL syntax. To illustrate the approach I hacked together a little "demo" (cfg is a normal FreeMarker Configuration object):
Template t = cfg.getTemplate("foo.ftl");
TemplateElement te = t.getRootTreeNode();
Enumeration e = te.children();
while(e.hasMoreElements()) {
Object child = e.nextElement();
if(child instanceof Comment) {
Comment comment = (Comment)child;
System.out.println("COMMENT: " + comment.getText());
} else if(child instanceof Macro) {
Macro macro = (Macro)child;
System.out.println("MACRO: " + macro.getName());
for(String argumentName : macro.getArgumentNames()) {
System.out.println("- PARAM: " + argumentName);
}
}
}
produces for your given example macro:
COMMENT:
MyMacro: Does stuff with param1 and param2.
- param1: The first param, mandatory.
- param2: The second param, 42 if not specified.
MACRO: MyMacro
- PARAM: param1
- PARAM: param2
How you parse the comment is then up to you ;-)
Update: Found something called ftldoc in my backups and uploaded it to GitHub. Maybe this is what you are looking for...

Core Data - can't set empty string as default value for attribute

I have an entity in my datamodel with a string attribute that is currently optional, and I'd like to convert this to a required attribute with a default value of the empty string.
As others have discovered, leaving the default value blank in the Xcode Core Data data modeler results in validation errors (since the designer interprets this as NULL), but trying '', "", or #"" as the default value results in those literal characters being interpreted as the default, rather than the empty zero-length string, as desired.
I did find this thread on Google, however, apart from the solution being really ugly (model definition split between the .xcdatamodel and objc source), it also doesn't work for lightweight migrations because those migrations are done solely based on the .xcdatamodel files and the objc logic from your entity implementations isn't loaded.
Is there any way to achieve this in the data model designer?
This is a very interesting question. After some testing I don't think this is possible because of the way the text field in the data model is configured.
In principle, you could use the unicode empty-set character of \u2205 to represent a default empty string but the text field does not seem to accept any escapes so it converts any attempt to escape a unicode character code to the literal string of the code characters themselves e.g. entering '\u2205' ends up as the literal text '\u2205'.
In theory you could write a utility app to read in the graphically generated managed object model file and then programmatically set the attribute default to equal an empty string and then save the file back to disk. I say "in theory" because there is no documented way to way to save a managed object model file from code. You can read one and modify it in memory but not persist the changes.
Bit of an oversight, I think.
I don't think you have any choice but to set the default empty string pragmatically when the model first loads. That is simple to do but it's ugly and you'll have to remember you did (especially if you migrate versions) but I think right now that is the only choice.
Whip out your favorite XML editor (I just used Emacs) and dive down to the contents file inside the .xcdatamodel bundle inside the .xcdatamodeld bundle. Then just add a defaultValueString="" XML attribute to the <attribute>...</attribute> element inside the <entity>...</entity> brackets.
Here's an example:
<attribute name="email" attributeType="String" defaultValueString="" syncable="YES"/>
I can't speak to whether this survives migration since I haven't had to do that yet.
I resolved this by overriding the getter for my field - if it contains null, I return an empty string instead:
-(NSString *)unit {
if ([self primitiveValueForKey:#"unit"] == NULL) {
return #"";
} else {
return [self primitiveValueForKey:#"unit"];
}
}
So far it seems to be doing the trick, and I would imagine it wouldn't impact migrations (although I don't know enough about them to say for sure). I don't really care whether there's a null or an empty string in the db, after all - so long as I get "" instead of null when I ask for the field.
My approach to resolving this issue was to create an NSManagedObject subclass and handle the substitution of empty strings for NULL values in awakeFromInsert. I then set all entities as children of this subclass rather than children of NSManagedObject. The assumption here is that I want every string attribute within a given entity to be set to an empty string by default (it wouldn't work, or would at least require extra logic, if you wanted some to remain NULL within the same entity).
There's probably a more efficient way of doing this, but since it's only called upon entity creation, I don't think it is too much of a performance hit.
- (void)awakeFromInsert {
[super awakeFromInsert];
NSDictionary *allAttributes = [[self entity] attributesByName];
NSAttributeDescription *oneAttribute;
for (NSString *oneAttributeKey in allAttributes) {
oneAttribute = [allAttributes objectForKey:oneAttributeKey];
if ([oneAttribute attributeType] == NSStringAttributeType) {
if (![self valueForKey:[oneAttribute name]]) {
[self setValue:#"" forKey:[oneAttribute name]];
}
}
}
}
You can do it manually.
In your model class, override awakeFromInsert and set your strings to empty string
Swift:
override func awakeFromInsert()
{
super.awakeFromInsert()
self.stringProperty = ""
}
Objective-C
- (void) awakeFromInsert
{
[super awakeFromInsert];
self.stringProperty = #"";
}
A simpler solution based on Scott Marks answer to avoid syntax errors:
First, temporarily set the default value to be easy to find, something like here you are. Open with any text editor the contents file inside the .xcdatamodel bundle inside the .xcdatamodeld bundle. Then just do a search with replacing the string "here you are" with the "" in this file.
The migration took place without problems.
Here is the Swift solution based on David Ravetti's answer and edelaney05's comment. In addition, I added optionality check.
This solution works fine in my projects.
class ExampleEntity: NSManagedObject {
...
override func awakeFromInsert() {
super.awakeFromInsert()
for (key, attr) in self.entity.attributesByName {
if attr.attributeType == .stringAttributeType && !attr.isOptional {
if self.value(forKey: key) == nil {
self.setPrimitiveValue("", forKey: key)
}
}
}
}
...
}
Maybe I'm late with this answer, but I was Googling and found this forum.
The solution is very simple:
When you click on the xcdatamodelId (On the left screen)
Change the Entity View to Graph
Double Click on any Attribute you want and the menu will appear on the right.
All changes are easy.
Part 2
Part 3
This appears to have been fixed at some point. Using Xcode 13:
Null String, unchecked Default Value:
<attribute name="myAttributeName" optional="YES" attributeType="String"/>
Empty String, now shown in Xcode interface:
<attribute name="myAttributeName" defaultValueString="" optional="YES" attributeType="String"/>
Entering "" into the field seems wrong and produces """" in the XML:
<attribute name="myAttributeName" defaultValueString="""" optional="YES" attributeType="String"/>

Resources