EJS template expansion when a string variable getting expanded has <%= %> - yeoman

Below is EJS code where I have problem expanding 'myTemplate' variable:
<% for(var i = 0 ; i < largeObject.elementArray.length; ++i) {%>
<%-largeObject.elementArray[i].myTemplate%>
<%}%>
'myTemplate' string examples below:
largeObject.elementArray[i].myTemplate = '<%=largeObject.elementArray[i].variable_1 + largeObject.elementArray[i].variable_7 + largeObject.elementArray[i].variable_12%>'
or
largeObject.elementArray[i].myTemplate = '<%=largeObject.elementArray[i].variable_1 + largeObject.elementArray[i].variable_5 + largeObject.elementArray[i].variable_14%>'
This is since 'myTemplate' variable derivation is fairly complex and hence is a pre-calculated string - but then how do I expand 'myTemplate' string now.
My EJS knowledge is basic - I might be missing some technical correct terms explaining this problem.

whilst calculating 'myTemplate' variable - I had to do ejs.render(template,data).
largeObject.elementArray[i].myTemplate = ejs.render(complex_template,dataObject)
Then assign the 'myTemplate' in the for loop as is.
Below is EJS code where I have problem expanding 'myTemplate' variable:
<% for(var i = 0 ; i < largeObject.elementArray.length; ++i) {%>
<%-largeObject.elementArray[i].myTemplate%>
<%}%>

Related

Implementing preview for markdown text

I am working on Ruby on Rails project and I have implemented markdown syntax for some text descriptions in my project using redcarpet gem.
It works like charm allowing to convert markdown text to HTML as simply as
<%= markdown some_text_variable %>
But now I want to implement preview feature rendering just small part of the full text.
The following naive construction
<%= markdown some_text_variable[0..preview_length] %>
will not work because it can easily break down MD syntax resulting in confusing constructions (imagine, for example, spliting original string on the half of image link).
I came up with
<%= markdown some_text_variable[0..preview_length].split(/\r?\n/)[0..-2].join("\r\n")) %>
but it does not deal, for example, with code blocks.
Is there any way to implement such kind of preview for MD text?
Using markdown.js and / or showdown should work. Here's a StackO with the same question and answer. I personally have used showdown in an Ember app before to render a live preview of the text as it's being typed (via 2-way data binding), and it worked flawlessly.
In the fiddle below, I wrote a little Showdown parser that takes in a string of markdown, splits it on a newline (returns an array of tags), and iterates through the array. On each iteration, it removes the tags, checks the length of the resulting string, and then compares it to the max character count for the preview. Once the next iteration surpasses the max character count, it returns the preview. The do loop ensures that you will always get at least one blob of html as a preview.
Fiddle
$(function() {
var converter = new Showdown.converter();
var previewMax = 200;
$('button').click(function() {
var content = $('#markdown').val(),
charCount = 0,
i = 0,
output = '';
if (!content) {
return $('div.preview').html("Please enter some text.");
}
var mark = converter.makeHtml(content);
var mark_arr = mark.split('\n');
while (charCount < previewMax) {
var html = mark_arr[i];
var text = htmlStrip(html);
if ((charCount + text.length) > previewMax) {
var overflow = (charCount + text.length) - previewMax;
var clipAmount = text.length - overflow;
html = jQuery.truncate(mark_arr[i], { length: clipAmount });
}
output += html;
charCount += text.length;
i++;
};
$('div.preview').html(output);
$('div.full').html(mark);
});
function htmlStrip (html) {
var div = document.createElement('div');
div.innerHTML = html;
var text = div.textContent || div.innerText || "";
return text;
}
});
REVISION
I updated the function using jQuery Truncate to cut the final string into an elipses so that all your previews are the same length as the others. Also, I realized that the original function returned a long string of undefined' over and over when no text was entered, so there is a check to eliminate that. Since this loop will always return at least one html item now, I changed the do loop to a while loop for easier reading. Finally, if you want your truncation to always end at a word boundary, pass the words: true option when you call it. Obviously, this will not give you the same level of truncation for every preview, but it will improve legibility. That's it!
I want to share my preview version it was quite simple with showdown.js and prism.js syntax highlighting.
Prism.js is syntaxing easily with JavaScript and CSS. All you need to pick specific languages and download it to assets folder. Or you can specify it to specific pages.
This is going to happen in realtime preview, in a form.
In Rails form:
<div class="col-md-12">
<div class="form-group">
<%= f.label :body %>
<%= f.text_area :body, class: "form-control", rows: 10 %>
</div>
</div>
<div class="col-md-12">
<h1> Preview Markdown </h1>
<div class="form-group markdownOutput"></div>
</div>
And add this script right below a form page.
<script>
function mkdown(){
var converter = new showdown.Converter(),
$post_body = $("#post_body");
// This line will keep adding new rows for textarea.
function postBodyLengthDetector(post_body){
var lines = post_body.val().split("\n");
post_body.prop('rows', lines.length+5);
}
// Textarea rows in default '10', when focusing on this. It will expand.
$post_body.focus(function(){
postBodyLengthDetector($(this));
$('.markdownOutput').html(converter.makeHtml($post_body.val()));
});
// All simple magic goes here, each time when texting anything into textarea
//it will be generated to markdown. You are able to see preview right below of textarea.
$post_body.keyup(function() {
postBodyLengthDetector($(this));
var value = $( this ).val(),
html = converter.makeHtml(value);
$('.markdownOutput').html(html);
});
}
$(mkdown);
$(document).on("turbolinks:load", mkdown);
</script>

How would I use button in the following situation in grails?

I am returning a map value that contain multiple items. The map is as follows:
def myList = []
//Some code to obtain the List
List << ["Id": Id,"Name": Name,"Code": sCode, "RunType": x ]
return [items: List]
In my GSP page I am using the following code to print them out in my web page.
<%
def counter = 0
for (i in items) {
counter = counter + 1
println("<td>" + i + "</td>" + "\n")
if (counter == 1) {
println("</tr><tr>")
counter = 0
}
}
%>
And the output looks as follows:
[Id:i-d0f5, Name:es_test_1b_110.test.com, Code:16, RunType:On Demand]
[Id:i-7890, Name:namc-qc.test.com, Code:16, RunType:On Demand]
[Id:i-ee56, Name:abcdef.test.com, Code:16, RunType:On Demand]
[Id:i-c41e, Name:backup.grails.test.com, Code:80, RunType:On Demand]
What I need now is to add a button for each of the values printed (so if 6 servers are printed 6 buttons will show up and if 10 servers are printed 10 buttons will show up) i will be using the button to pass the Id to start and stop the server.
Grails has some powerful built-in GSP tags which come in quite handy here. For example:
<g:each in="${items}" var="i">
<tr>
<td>${i.Id}</td>
<td>${i.Name}</td>
<td>${i.Code}</td>
<td>${i.RunType}</td>
<td><a class="button" href="${createLink(controller: '<controllerName>', action: 'start', id: i.Id)}">Start</a></td>
</tr>
</g:each>
There are, of course, many other ways to approach this, but I hope this is a start. For more, see these sections in the Grails ref doc: each, createLink

Why does Pygment.rb not highlight <code> tags within <pre class="lang"> properly -i.e. Google Prettify friendly tags?

I am calling it in my view like this:
<%= markdown question.body %>
This is what my ApplicationHelper looks like:
module ApplicationHelper
class HTMLwithPygments < Redcarpet::Render::HTML
def block_code(code, language)
Pygments.highlight(code, lexer:language)
end
end
def markdown(text)
renderer = HTMLwithPygments.new(hard_wrap: true)
options = {
autolink: true,
no_intra_emphasis: true,
fenced_code_blocks: true,
lax_html_blocks: true,
strikethrough: true,
superscript: true
}
Redcarpet::Markdown.new(renderer, options).render(text).html_safe
end
end
But, when it encounters tags like this:
<pre class="lang-cpp prettyprint-override">
It doesn't apply the color highlights to that code. Why is that?
P.S. This is generated, for instance, by Stack Overflow by doing this: <!-- language: lang-cpp -->
Edit 1
Or more specifically, it seems that it won't format the <code> tags that are within <pre> tags. Once <code> is not within <pre> it seems to format it fine. How do I remedy that?
Edit 2
The problem seems to be the data that Pygment.rb is acting on. It is HTML, as can be seen in this gist - https://gist.github.com/marcamillion/14fa121cf3557d38c1a8. So what I want to be able to do is to have Pygment properly format the code returned in the body attribute of that object in my gist.
How do I do that?
Edit 3
This is the HTML code that I would like Pygment.rb and Redcarpet to perform syntax highlighting on:
<p>Here is a piece of C++ code that shows some very peculiar performance. For some strange reason, sorting the data miraculously speeds up the code by almost 6x:</p>
<pre class="lang-cpp prettyprint-override"><code>#include <algorithm>
#include <ctime>
#include <iostream>
int main()
{
// Generate data
const unsigned arraySize = 32768;
int data[arraySize];
for (unsigned c = 0; c < arraySize; ++c)
data[c] = std::rand() % 256;
// !!! With this, the next loop runs faster
std::sort(data, data + arraySize);
// Test
clock_t start = clock();
long long sum = 0;
for (unsigned i = 0; i < 100000; ++i)
{
// Primary loop
for (unsigned c = 0; c < arraySize; ++c)
{
if (data[c] >= 128)
sum += data[c];
}
}
double elapsedTime = static_cast<double>(clock() - start) / CLOCKS_PER_SEC;
std::cout << elapsedTime << std::endl;
std::cout << "sum = " << sum << std::endl;
}
</code></pre>
<ul>
<li>Without <code>std::sort(data, data + arraySize);</code>, the code runs in <strong>11.54</strong> seconds.</li>
<li>With the sorted data, the code runs in <strong>1.93</strong> seconds.</li>
</ul>
<hr>
<p>Initially I thought this might be just a language or compiler anomaly. So I tried it in Java:</p>
<pre class="lang-java prettyprint-override"><code>import java.util.Arrays;
import java.util.Random;
public class Main
{
public static void main(String[] args)
{
// Generate data
int arraySize = 32768;
int data[] = new int[arraySize];
Random rnd = new Random(0);
for (int c = 0; c < arraySize; ++c)
data[c] = rnd.nextInt() % 256;
// !!! With this, the next loop runs faster
Arrays.sort(data);
// Test
long start = System.nanoTime();
long sum = 0;
for (int i = 0; i < 100000; ++i)
{
// Primary loop
for (int c = 0; c < arraySize; ++c)
{
if (data[c] >= 128)
sum += data[c];
}
}
System.out.println((System.nanoTime() - start) / 1000000000.0);
System.out.println("sum = " + sum);
}
}
</code></pre>
<p>with a similar but less extreme result.</p>
<hr>
<p>My first thought was that sorting brings the data into cache, but my next thought was how silly that is because the array was just generated.</p>
<p>What is going on? Why is a sorted array faster than an unsorted array? The code is summing up some independent terms, the order should not matter.</p>
You can see the current way that this particular question is being rendered at: http://boso.herokuapp.com
It is the most popular question on that site, the first one that you see. You will notice that the code simply has a grey background and is indented. There is no pretty highlighting like Pygment.rb promises and does on other code snippets (similarly to how #rorra has illustrated in other examples in his answer).
I can't strip out the HTML - because I want to parse it properly (i.e. make sure the spacing, etc. is included properly). The only difference that I want, is to get syntax highlighting on the code represented in the body of the question.
Is there something else you can add in order to reproduce the issue? Like the content of question.body?
If I do something like this on the controller:
class HomeController < ApplicationController
def index
#data = <<EOF
~~~ cpp
#include <fstream.h>
int main (int argc, char *argv[]) {
return(0);
}
~~~
EOF
end
end
and the on the view:
<pre class="lang-cpp prettyprint-override">
<%= markdown #data %>
</pre>
it works totally fine, I can see the parsed code without any problem. What's the content of question.body? And can you save the content of the web page (from your browser) and save it on a gist so we can debug?
Thx
Regarding your last comment, its a simple css issue, on your stylesheet, you can add:
.code {
color: #DD1144 !important;
}
and it will work, the problem is that you have a css rule written like:
pre .code {
color: inherited;
}
and that's using the color #333333 inherited from the body class
Here's a screen on how it looks like with the css updated:
The sample app with your code runs totally fine, I would need a sample app code app, or a sample code where we can reproduce the issue you are having (not having the right css/stylesheets for the formatted code).
This is an example of how the sample app looks like:
Final edit, the problem is not the library, and its not the way you are rendering the question, its the content you are rendering, check the body of your questions, this is one of the questions I got with the body that actually is rendered as the library should render, but its not rendering as you are expecting :)
#data = <<EOF
<p>I've been messing around with JSON for some time, just pushing it out as text and it hasn't hurt anybody (that I know of), but I'd like to start doing things properly.</p>
<p>I have seen <em>so</em> many purported "standards" for the JSON content type:</p>
<pre><code>application/json
application/x-javascript
text/javascript
text/x-javascript
text/x-json
</code></pre>
<p>But which is correct, or best? I gather that there are security and browser support issues varying between them.</p>
<p>I know there's a similar question, <em>What MIME type if JSON is being returned by a REST API?</em>, but I'd like a slightly more targeted answer.</p>
EOF
And this is another one I just copied/pastle from stackoverflow, that renders with all the syntax highlighted, do you notice the difference? So update your crawler to get the questions in the right format and it will work
#data = <<EOF
Here is a piece of C++ code that shows some very peculiar performance. For some strange reason, sorting the data miraculously speeds up the code by almost 6x:
<!-- language: lang-cpp -->
#include <algorithm>
#include <ctime>
#include <iostream>
int main()
{
// Generate data
const unsigned arraySize = 32768;
int data[arraySize];
for (unsigned c = 0; c < arraySize; ++c)
data[c] = std::rand() % 256;
// !!! With this, the next loop runs faster
std::sort(data, data + arraySize);
// Test
clock_t start = clock();
long long sum = 0;
for (unsigned i = 0; i < 100000; ++i)
{
// Primary loop
for (unsigned c = 0; c < arraySize; ++c)
{
if (data[c] >= 128)
sum += data[c];
}
}
double elapsedTime = static_cast<double>(clock() - start) / CLOCKS_PER_SEC;
std::cout << elapsedTime << std::endl;
std::cout << "sum = " << sum << std::endl;
}
- Without `std::sort(data, data + arraySize);`, the code runs in **11.54** seconds.
- With the sorted data, the code runs in **1.93** seconds.
----------
Initially I thought this might be just a language or compiler anomaly. So I tried it in Java:
<!-- language: lang-java -->
import java.util.Arrays;
import java.util.Random;
public class Main
{
public static void main(String[] args)
{
// Generate data
int arraySize = 32768;
int data[] = new int[arraySize];
Random rnd = new Random(0);
for (int c = 0; c < arraySize; ++c)
data[c] = rnd.nextInt() % 256;
// !!! With this, the next loop runs faster
Arrays.sort(data);
// Test
long start = System.nanoTime();
long sum = 0;
for (int i = 0; i < 100000; ++i)
{
// Primary loop
for (int c = 0; c < arraySize; ++c)
{
if (data[c] >= 128)
sum += data[c];
}
}
System.out.println((System.nanoTime() - start) / 1000000000.0);
System.out.println("sum = " + sum);
}
}
with a similar but less extreme result.
----------
My first thought was that sorting brings the data into cache, but my next thought was how silly that is because the array was just generated.
What is going on? Why is a sorted array faster than an unsorted array? The code is summing up some independent terms, the order should not matter.
EOF

ActionLink only if a certain condition is met

If s = "N/A" then I don't want to use the ActionLink. In other words, if the inventory item is not currently being used on a project, then don't provide the link (just show N/A instead). Also, how do I send the link to Projects/Details? Right now, it will go to "Nails/Projects/Details" instead, because I'm using the NailsController class.
<td class="table-normal-data">
<% Dim l As Integer = InStr(item.CurrentProject, " [")
Dim s As String = item.CurrentProject
Dim projectID As String = ""
If l > 0 Then
s = Mid(item.CurrentProject, 1, l - 1)
projectID = Mid(item.CurrentProject, l + 2, Len(item.CurrentProject) - l - 2)
Else
s = ""
End If
%>
<%: Html.ActionLink(s, "Projects/Details", New With {.id = projectID}) %>
</td>
I'm much more familiar with MVC3/Razor and C#, but I often do something like this in my views:
#if( Model.Flag )
{
<span>n/a</span>
}
else
{
#Html.ActionLink(....
}
Basically, you output different stuff through the view depending on the state of the model.

asp.net mvc razor multiply two item and convert to string

When I write #(line.Quantity * line.Product.Price).ToString("c") the result is
39,00.ToString("c")
and #line.Quantity * line.Product.Price.ToString("c") result is
2 * line.Product.Price.ToString("c")
How can i multiply two values and convert it to string in a razor view?
try
#((line.Quantity * line.Product.Price).ToString("c"))
The problem is that razor do not know when the output string ends since # is used to display code in HTML. Spaces switches razor back to HTML mode.
Wrapping everything into parenthesis makes razor evaluate the entire code block.
Although the most proper way would be to introduce a new property in your model:
public class MyModel
{
public double Total { get { return Quantity * Product.Price; }}
//all other code here
}
and simply use:
#line.Total.ToString("c")
this is an old question but I have just had the same issue and here is the resolution for it.
If you need to perform a calculation on a razor view, you can do it the following way:
if you are outside of c# block (such as #foreach or #if ):
you can wrap your calculation into #{ } and they won't be rendered.
<p>Some text</p>
#{ var x = Model.Y * Model.Z; }
<p>X equals #x.ToString()</p>
if you are inside of a c# block:
you can simply put your calculations in { }.
<p>Some text</p>
#foreach (var x in Model.Y)
{
{ var z = x * 2; }
<p>Z equals #z.ToString()</p>
}

Resources