Using Play 2 I am realising a simple REST API, the output is plain text. My template looks like this:
#(items: Map[String,String])
#for((key, value) <- items) {
#value
#key
}
In the controller:
return ok(views.html.bla.render(itemsMap)).as("text/plain");
This gives the following output:
(empty line)
(empty line)
value
key
(empty line)
value
key
I want to get rid of the first 2 empty lines - is that possible?
Putting the for in the first line removes one of the empty lines at the top, however one still remains and for in the first line makes the template hard to read ): Thanks for any hint!
First off, if you use plain text, you should use txt templates (bla.scala.txt). They also automatically set text/plain; charset=utf-8 content type.
To trim the content, you can return the rendered content directly:
return ok(views.txt.bla.render(itemsMap).body().trim());
In case you want to render HTML content you'd need to change this manually:
return ok(views.html.ble.render().body().trim()).as("text/html; charset=utf-8");
If you are generating plain text output from a map, why do you use views at all? They don't provide any benefit in your case.
You can write the render function in pure Scala. Something like
items.map{ case (k,v) => v + '\n' + k}.mkString('\n')
Related
I need help to parse, modify and show a string on an Android App (Java language, max API level 22)
This is a example string I'm getting from an API which contains only custom tag:
<BOLD> Something <RED> went wrong </RED> </BOLD> <NEWLINE> Server unreachable </NEWLINE>
I need to remove all this custom tags then format its content based on the tags that were wrapping that substring (so I'm expeting, for example, to get "went wrong" in red color and bold). I already tried looking up for similar problems but can't get to the final result.
The string (cleaned and formatted) will then be used to set the Text of a TextView inside a List View
One way of doing this is like this....
String testString="<BOLD> Something <RED> went wrong </RED> </BOLD> <NEWLINE> Server unreachable </NEWLINE>";
testString=testString.replaceAll("<BOLD>","<font> <b>");
testString=testString.replaceAll("</BOLD>","</b> </font>");
testString=testString.replaceAll("<RED>","<font color =\"#FF0000\">"); //#FF0000 is hex code for red color
testString=testString.replaceAll("</RED>","</font> ");
testString=testString.replaceAll("<NEWLINE>","<br>");
testString=testString.replaceAll("</NEWLINE>","");
TextView textView=findViewById(R.id.text);
textView.setText(Html.fromHtml(testString));
Output :
Using Regex (Regular Expressions)
Just give your string to the Regex Pattern and it removes all the extra tags for you.
Kotlin
This removes all the HTML tags inside your String:
val result = yourString.replace(Regex("(<[a-z]*>)|(<.[a-z]*>)"), "")
Java
String result = yourString.replaceAll("(<[a-z]*>)|(<.[a-z]*>)", "");
I've created a method which returns the contents of a particular XML element. The list returned is as follows:
data/13-Apr-2017-17:08:46-usage
archive/13-Apr-2017-17:08:58-usage
data/13-Apr-2017-17:09:04-usage
data/13-Apr-2017-17:11:47-bandwidth
archive/13-Apr-2017-17:11:47-operation
archive/13-Apr-2017-18:42:05-bandwidth
data/13-Apr-2017-18:42:05-operation
archive/14-Apr-2017-09:57:18-usage
debug/14-Apr-2017-13:45:46-usage
How do I then filter this to only return elements that begin with data, and contain the text usage? A further step might be to only return the value with the most recent date/time.
Ah, I think I got it. Something along these lines:
if(eElement.getElementsByTagName("Key").item(0).getTextContent().startsWith("data")){
System.out.println("Key: " + eElement.getElementsByTagName("Key").item(0).getTextContent());
}
I've a few other bits to work out but should get it from here.
I've some tags in a word file which looks like <tag>.
Now I get the content of the Word file with docx4j and loop through every line and search for this tag. When I find one, then i replace it with a String. But this code i tried doesn't work and now i really don't know how i can realise it!
Here's the code i've already tried:
WordprocessingMLPackage wpml = WordprocessingMLPackage.load(new File(path));
MainDocumentPart mdp = wpml.getMainDocumentPart();
List<Object> content = mdp.getContent();
String line;
for (Object object : content) {
line = object.toString();
if (line.contains("<tag>")) {
line.replace("<tag>", "<newTag>");
}
}
Any tips or solutions how i can achieve it?
One of your problems is that you modify String line which has no effect on anything. line.replace("<tag>", "<newTag>"); result of this operation is ignored. you would definitely want to do sth with that, right?
Also, if object in your loop is not an instaneOf String, then line and object are pointing to different objects.
You need to modify contents but not the way you're doing this. Please read getting started
Also there are lots of examples (sample code) in source code download section
If you have any concrete problems after reading the getting started, we'll be happy to help you.
The things in your List will be org.docx4j.wml.P (paragraphs), or Tbl (tables) or other block level content.
Paragraphs contain runs, which in turn contain the actual text.
For the suggested way of doing what you want to do, see the VariableReplace sample.
Better yet, consider content control data binding.
Otherwise, if you want to roll your own approach, see the Getting Started guide for how to traverse, or use JAXB-level XPath.
First you should use replaceAll() instead of replace().
Then you should store this String into an object you can serialize back after modification to the Word file.
Furthermore I think that it would also be good to handle closing tags (if there some) ...
String (line) is immutable, therefore replace("<tag>", "<newTag>") does not modify your line it creates a new modified one.
Your code shoudl do something like this:
for (Object object : content) {
line = object.toString();
if (line.contains("<tag>")) {
line= line.replaceAll("<tag>", "<newTag>");
}
writeLineToNewFile(line);
}
or shorter:
for (Object object : content) {
writeLineToNewFile(object.toString().replace("<tag>", "<newTag>");
}
I have a Struts form which contains a Map:
private Map<Long, String> questionAnswers = new TreeMap<Long, String>();
I have the normal getter and setter for this variable (not shown here), and I also have the getter and setter required for Struts to work (using String/Object):
public Object getQuestionAnswer(String questionId) {
return getQuestionAnswers().get(questionId);
}
public void setQuestionAnswer(String questionId, Object answerText) {
String answer = (answerText == null) ? "" : answerText.toString();
getQuestionAnswers().put(Long.valueOf(questionId), answer);
}
In my JSP, I am dynamically generating the textareas that are used to enter the values for the map. This is all working fine. However, when the form is invalid, I need to dynamically generate the textareas again, and put the user text back into the textareas. I am currently repopulating the textareas like so:
<c:forEach items="${myForm.questionAnswers}" var="questionAnswer">
var textareaBoxName = "questionAnswer(" + '${questionAnswer.key}' + ")";
var textareaBox = document.getElementsByName(textareaBoxName)[0];
if (textareaBox) {
$('textarea[name=' + textareaBoxName + ']').val('${questionAnswer.value}');
}
</c:forEach>
This works fine, except if you enter a newline in the textarea. Then a JavaScript error complains about an "Unterminated string constant". I am guessing the newlines are being performed instead of just read.
In the setQuestionAnswer method, I put in some debugging and found that a newline entered in the textarea is being read as 2 characters, which converted into ints are 13 and 10 (which I believe are \r and \n). I tried replacing the the "\r\n" with just "\n" in the setQuestionAnswer method (using the String replaceAll method), but the same error occurred. I then tried replacing the "\r\n" with "%0A" (which I believe is the JavaScript newline). While this got rid of the JavaScript error, the textareas now have the "%0A" displayed instead of a newline. I tried all sorts of escaping and unescaping with no luck (note, I also want special characters to be preserved).
Does anyone have any idea on how to preserve newlines and special characters in the textarea boxes on invalid submits? I need this to work in IE. And I would like to avoid anything hacky like using some special character/string to "represent" a newline which I then replace in JavaScript, etc.
Since ${questionAnswer.value} is put inside a JavaScript String literal, you need to escape it as you would do if you wanted a newline in a JavaScript literal: the lines Hello and World must be written as 'Hello\nWorld'. Look at commons-lang StringEscapeUtils escapeECMAScript method. In iddition to escaping the newlines, it will also escape tabs, apostrophes, etc.
Make this method an EL method, and use it directly into your JSP:
$('textarea[name=' + textareaBoxName + ']').val('${myFn:escapeJs(questionAnswer.value)}');
You might also generate the text areas statically instead of generating them using JavaScript:
JQuery code is as follows:
alert(jQuery.i18n.prop('message.key'));
The value is specified in the properties file as:
message.key=value is after newline\nValue here
Following output is expected from javascript alert():
value is after newline
Value here
The actual output is:
value is after newline\nValue here
I tried different methods by changing value stored in properties file to:
message.key=value is after newline\\nValue here
message.key=value is after newline\u000DValue here
But it doesn't work. It displays "\\n" instead
What changes are required to be made to get the desired output?
EDIT: Following code gives desired output in javascript:
alert('value is after newline\nValue here')
But I need to use jquery.i18n.properties for localization
I'm pretty sure you can just go like this (the plugin supports multi-line properties):
message.key1=value is after newline
Value here
message.key2=next value