How to extract react-i18next translation using function call? - i18next

Given the following code:
<Trans i18nKey="error" ns="login">
<p className="error">
{React.string("Incorrect username/password combination.")}
<br />
{React.string("Is Caps Lock turned on?")}
</p>
</Trans>
Notice the React.string function calls.
Is there a way to make this work with i18next? What would this key's value look like in the JSON file?
Update
In my translations JSON file, how should the above code look?
"error": "<1>???</1>"

I'm not sure what is this React.string method, but the whole purpose of Trans is to integrate style tags in a text.
The text should be in the translation (json) file.
Your usage should look like:
<p className="error">
<Trans i18nKey="error" ns="login" />
</p>
{
"error": "Incorrect username/password combination.<br />Is Caps Lock turned on?"
}
BTW, for line break you can avoid Trans component, you can use white space and css, for more info read this answer: React i18n break lines in JSON String

Related

ASP.NET Core Razor Page: Passing value from Foreach to a JavaScript function

I'm trying to pass the value from a C# object to a JavaScript function.
But I am getting an error:
#foreach (var Item in Model.Student)
{
<input id="btnAdd" type="button" value="Add" onclick="AddTextBox(JSON.parse(#Html.Raw(Item)))"/>
}
The Model.Student property returns a Student object, which is defined as follows:
public class Student
{
public int Id { get; set; }
public string name { get; set; }
}
You need to do three things to resolve this issue:
Serialize your Student object (Item) to JSON using Json.Serialize(),
Encode your JSON as a JavaScript string using HttpUtility.JavaScriptStringEncode(), and
Wrap your JSON in apostrophes so that JSON.parse() is correctly interpreting it as a string.
Your final Razor markup should look like the following:
<input id="btnAdd" type="button" value="Add" onclick="AddTextBox(JSON.parse('#Html.Raw(HttpUtility.JavaScriptStringEncode(Json.Serialize(Item).ToString()))'))"/>
Continue reading for a deeper understanding of how to troubleshoot these types of issues in the future, as well as why each one of these steps is necessary.
Debugging
Before diving in, it's worth taking a step back to revisit some troubleshooting principles. Remember that ASP.NET Core MVC is simply rendering an HTML page. After that, it's up to the browser to parse and execute both the HTML and the JavaScript. When you're combining Razor, HTML, and JavaScript in the same line, but only looking at the errors generated by JavaScript, it's easy to miss the underlying issue. Given this, what you want to do is view the source code in your browser to see what HTML is being generated.
Issue #1: Serializing Classes
The most immediate issue is that when you call #Html.Raw(Item), the Item's ToString() method is going to be called to create a string representation of your Student object. If your Student object is a class, this will just be the fully-qualified name of the class (e.g., MyNamespace.Student).
This will output something like:
<input id="btnAdd" type="button" value="Add" onclick="AddTextBox(JSON.parse(MyNamespace.Student))"/>
That's obviously not valid JSON, nor does it include any of your data. To resolve this, you need to wrap the call to Item in Json.Serialize(), which will serialize it from a C# object to a JSON string:
<input id="btnAdd" type="button" value="Add" onclick="AddTextBox(JSON.parse(#Html.Raw(Json.Serialize(Item))))"/>
This will output something closer to what you want:
<input id="btnAdd" type="button" value="Add" onclick="AddTextBox(JSON.parse({"Id"=1,"name":"John"}))"/>
Issue #2: Encoding JSON
If you attempt to execute the above code, you're going to encounter a JavaScript error, such as the following:
Uncaught SyntaxError: Unexpected end of input
Do you see the problem? The quote around Id is going to close your onclick handler, resulting in malformed markup. From the browser's perspective, it ends up seeing the following attributes, trailed by invalid markup:
id: btnAdd
type: button
value: Add
onclick: AddTextBox(JSON.parse('{
To remedy this, you need to encode the JSON string so that it can be embedded within a JavaScript call. Fortunately, ASP.NET Core supplies us with the HttpUtility.JavaScriptStringEncode() method that does just that:
<input id="btnAdd" type="button" value="Add" onclick="AddTextBox(JSON.parse(#Html.Raw(HttpUtility.JavaScriptStringEncode(Json.Serialize(Item).ToString()))))"/>
Note: The JavaScriptStringEncode() method requires a string, so we need to call ToString() on the Json.Serialize() call, which otherwise outputs an IHtmlContent object.
This will now output something like the following:
<input id="btnAdd" type="button" value="Add" onclick="AddTextBox(JSON.parse({\"Id\"=1,\"name\":\"John\"}))"/>
Issue #3: Converting to a JSON object
There are still problems here. The JSON.parse() method expects a string, but we're passing it raw JSON notation. As such, if you execute this code, you'll now receive a variation on the original error:
Uncaught SyntaxError: Invalid or unexpected token
This can be resolved by simply wrapping the JSON in apostrophes, denoting that it's a string:
<input id="btnAdd" type="button" value="Add" onclick="AddTextBox(JSON.parse('#Html.Raw(HttpUtility.JavaScriptStringEncode(Json.Serialize(Item).ToString()))'))"/>
This will now output something like the following:
<input id="btnAdd" type="button" value="Add" onclick="AddTextBox(JSON.parse('{\"Id\"=1,\"name\":\"John\"}'))"/>
If you click on this element, this should finally work—assuming, of course, your AddTextBox() is functioning correctly.
Conclusion
As mentioned at the top, when working with Razor, HTML, and JavaScript, you really need to pay close attention to what HTML is being rendered from the Razor page, prior to it being parsed by the browser or executed by the JavaScript engine. In this case, most of these issues stem from malformed markup that either the browser or the JavaScript engine aren't able to properly parse.

Google script code formatted,colored and beautiful indent

I wrote a container-bound script and now want to make a report from it, by inserting the code into a Google Docs file. The problem is that with copy & paste from the Script Editor, the code is no longer colored or indented. I will need your help because I don't know how to make it well done.
I have this code :
createAndSendDocument() {
// Create a new Google Doc named 'Hello, world!'
var doc = DocumentApp.create('Hello, world!');
// Access the body of the document, then add a paragraph.
doc.getBody().appendParagraph('This document was created by Google Apps Script.');
// Get the URL of the document.
var url = doc.getUrl(); // Get the email address of the active user - that's you.
var email = Session.getActiveUser().getEmail();
}
As tehhowch said you'll need to write your own javascript code to do syntax formatting and then use the output of that.
You can use this https://www.w3schools.com/howto/tryit.asp?filename=tryhow_syntax_highlight they already have the script in place you only need to encode your html and put inside div id="myDiv" and run the javascript code.
<div id="myDiv">
Your encoded html goes here
</div>
Example
<div id="myDiv">
<!DOCTYPE html><br>
<html><br>
<body><br>
<br>
<h1>Testing an HTML Syntax Highlighter</h2><br>
<p>Hello world!</p><br>
<a href="https://www.w3schools.com">Back to School</a><br>
<br>
</body><br>
</html>
</div>
Make sure you first encode your html. [< -> &lt, > -> &gt, etc]
Then you can use the output of that . Sample : https://docs.google.com/document/d/1h8oDOZ0ReTgwxnYt2JKflHWJdlianSWWuBgbWcSdJC0/edit?usp=sharing
Reference and further reads : https://www.w3schools.com/howto/tryit.asp?filename=tryhow_syntax_highlight

Apply vue-katex to content loaded from static folder

I'm trying to make a blog using Vue as laid out in the excellent demo here. I'd like to include some mathematical formulas and equations in my blog, so I thought I'd try to use vue-katex. vue-katex formats my mathematical notation perfectly when I put all my KaTeX HTML directly into my Vue templates, but to create a useable blog I need to keep my content separate from my templates (as shown in the demo).
I can't get vue-katex to format HTML content in the static folder. That's what I'd like help with.
Setup
I cloned the github repo for the demo.
I added vue-katex to package.json:
"vue-katex": "^0.1.2",
I added the KaTeX CSS to index.html:
<!-- KaTeX styles -->
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.9.0-alpha2/katex.min.css"
integrity="sha384-exe4Ak6B0EoJI0ogGxjJ8rn+RN3ftPnEQrGwX59KTCl5ybGzvHGKjhPKk/KC3abb"
crossorigin="anonymous"
>
I added the import statement to src/App.vue:
import Vue from 'vue'
import VueKatex from 'vue-katex'
Vue.use(VueKatex)
and I added a simple line of HTML with KaTeX to the BlogPost template:
<p>Here's an equation in the actual Vue template: <div class="equation" v-katex="'X \\sim N(\\mu, \\sigma^2)'"></div></p>
As I said, this works - I see formatted mathematical notation in my blog post (URL http://localhost:8080/read/neque-libero-convallis-eget):
However, I need different equations for every blog post, of course.
So I tried adding KaTeX HTML to the "content" field in the JSON for the first blog post: static/api/post/neque-libero-convallis-eget.json. I changed the "content" line to:
"content": "Here's an equation in the static folder: <div class=\"equation\" v-katex=\"'X \\sim N(\\mu, \\sigma^2)'\"></div>",
This content appears on the page, but the equation doesn't render. I see this: (the text appears but no equation is shown)
When I use Developer Tools to inspect the HTML on the page, I see this:
You can see that vue-katex has been applied to the equation I put in the template directly: it has parsed the HTML I typed into lots of spans with all the mathematical symbols, which are showing perfectly.
However the KaTeX HTML I've added to the "content" in the static folder has simply been placed on the page exactly as I typed it, and is therefore not showing up as an equation on the page. I really need to keep my blog post content in this static folder - I don't want to have to create a different .vue file for each blog post, that defeats the point!
My question is: is there a way to manually "apply" vue-katex to the HTML I place in the static folder, when it loads? Perhaps there is something I can add to the plugins/resource/index.js file, since this contains the function that loads the data from the static folder?
Many thanks in advance for any help.
*Disclaimer: I'm definitely no expert / authority on what I'm about to explain!
One thing to remember is that Vue reads the templates you write, and then replaces them as reactive components. This means that although you often write Vue attributes like v-for, v-html or in this case v-katex these attributes are only useful up until the app or component is mounted.
With this in mind, if you have a Vue app that ajax loads some html, its not going to be able to rerender itself with those Vue bindings in place.
I have somewhat ignored your current set up and set about solving the issue in another way.
Step 1: Reformat your data from the server side
I've put the posts into an array, and each post contains the template (just a string of html) and the equations separately as an array. I've used [e1] in the post as a placeholder for where the katex will go.
var postsFromServer = [{
content : `<div>
<h2>Crazy equation</h2>
<p>Look here!</p>
[e1]
</div>`,
equations : [
{
key : 'e1',
value : "c = \\pm\\sqrt{a^2 + b^2}"
}
]
}];
Step 2: When the post is rendered, do some work on it
Rather than just use v-html="post.content", I've wrapped the html output in a method
<div id="app">
<div v-for="post in posts" v-html="parsePostContent(post)">
</div>
</div>
Step 3: Create a method that renders all the katex, and then replaces the placeholders in the post
methods : {
parsePostContent(post){
// Loop through every equation that we have in our post from the server
for(var e = 0; e < post.equations.length; e++){
// Get the raw katex text
var equation = post.equations[e].value;
// Get the placeholder i.e. e1
var position = post.equations[e].key;
// Replace [e1] in the post content with the rendered katex
post.content = post.content.replace("[" + position + "]", katex.renderToString(equation));
}
// Return
return post.content;
}
}
Here is the whole set up, which renders Katex:
https://codepen.io/EightArmsHQ/pen/qxzEQP?editors=1010

Concordion: How get the parameter value inside #TEXT

I am using Concordion to test some java components.
I will write something like
<pre concordion:execute="someFunction(#TEXT, #a)">
{
id:123,
name:<span concordion:echo="#b"/>
}
</pre>
I want to value of #b is calculated and substituted dynamically.
But instead of value #b in someFunction comes an empty string.
Similarly, if use
name:<span concordion:execute="getBValue()"/>
If someone has done something like this, could you please help.
Thanks.
I think Concordion was not design for the purpose of this use case. It is not a template engine. You can transfer the text elements of your specification as input into your automated tests. Additionally, you can use the values inside your specifications as reference to compare the actual outputs of the system under test.
When you want to transfer the result of some method getBValue() into another method someFunction() you have probably several option:
What about calling getBValue() inside your someFunction()?
Or you could transfer the result of getBValue() into a variable and call some Function with this variable:
<pre concordion:execute="someFunction(#TEXT, #a, #b)">
{
id:123,
name:placeholder-for-value-b
}
</pre>
Then inside of someFunction() you could replace the placeholder:
public void someFunction(String text, String aValue, String bValue) {
text.replace("placeholder-for-value-b", bValue);
//continue logic of someFunction
}
you could use the execute command to initialize the variable #name:
<span concordion:execute="#name=getBValue()"/>
followed by the echo command:
name: <span concordion:echo="name" />
or have you tried to call your method directly within the echo command?
name: <span concordion:echo="getBValue()" />
Could your problem be related with the html structure?
When you are using nested elements such as
<pre concordion:execute=...> <span concordion:assert-equals=...>...</span> <span concordion:set=...>...</span> </pre>
Concordion uses the following execution order:
all "standard" commands such as set, echo, etc.
the execute command
assert commands such as assert-equals
This is the way Concordion handles unusual sentence structures.
What about putting the execute-command inside a dedicated span-tag?
<pre> <span concordion:execute=...>...</span> <span concordion:echo=...></span> </pre>

Passing a GET parameter to ActionLink in ASP.NET

Sorry but I am new to C# and ASP.NET and I saw alot of posts about this problem but I quite didn't get it. I am trying to understand how to pass a GET parameter to an action thru HTML.ActionLink:
here is the the URL:
http://localhost:36896/Movies/SearchIndex?searchString=the
and my CSHTML page should look like this:
<input type="Text" id="searchString" name="searchString" />
#Html.ActionLink("Search Existing", "SearchIndex", new { searchString = "the"})
this hard coded parameter "the" is actually working, but how can I select the input element with id=searchString, with something like document.getElementById("searchString").value
Thanks,
If the value you want to send as GET parameter is not known on the server you cannot use the Html.ActionLink helper to add it. You need to use javascript to manipulate the existing link and append the parameter.
It looks like you have an input field that contains a search string and you want to send the value entered in this field to the server. A better way to handle this scenario is to use an HTML form with method="GET" instead of an ActionLink. This way you don't need to use any javascript - it's part of the HTML specification:
#using (Html.BeginForm("SearchIndex", "Movies", FormMethod.Get))
{
#Html.EditorFor(x => x.SearchString)
<button type="submit">Search</button>
}
Now when you click on the Search button the value entered in the SearchString field will automatically be sent to the SearchIndex action:
http://localhost:36896/Movies/SearchIndex?searchString=the
But if you absolutely insist on using an ActionLink you will have to write javascript to manipulate the href of the existing link when this link is clicked in order to append the value to the url. It's an approach I wouldn't recommend though because the HTML specification already provides you this functionality throughout HTML forms.
This makes the #Html.EditorFor refer to the Title field of the object, kinda in a random way but it works!
#using (Html.BeginForm ("SearchIndex", "Movies", FormMethod.Get))
{
#Html.EditorFor( x => x.ElementAt(0).Title)
<button type="submit">Search</button>
}
Still couldn't pass input parameter to the URL in the GET.
EDIT:
FINAL SOLUTION:
#Html.TextBox("SearchString")
<button type="submit">Filter</button>
and on the controller side, switch the input parameter. Basically it will automatically recognize the passed parameter.
public ActionResult SearchIndex(string searchString)
{
...
}