I receive from my frontend a json with a string containing 1 or more HTML elements for example:
"textTop" : "<b>bold</b><div><i>italic</i>..."
I want to use this string to create Html elements inside a div, but I'm not really sure if I can do this with golang templates.
type FooBar struct {
TextTop string
}
So I'm currently storing the TextTop in a string, and then displaying it in html with:
<div>
{{.TextTop}}
</div>
But of course this produces the following result in the browser. just a div containing the string, I'm passing.:
So should I use a different type for TextTop inside Foobar struct instead of type string, which one? or can I use a golang function that reads all html elements from a string and renders them in the html as part of the DOM and not just a string?
To prevent escaping, declare the field as type template.HTML:
type FooBar struct {
TextTop template.HTML
}
See the linked documentation for information about the security risks of using template.HTML.
Related
I am learning Gatsby and trying to expand their tutorial, which leaves you with a blog-like site. Each post is generated from markdown files, queried with Graphql and processed via onCreateNode and createPages.
I'd like to create markdown files for author bios that can be included on these generated pages. Then if a bio changed, the markdown would be changed in one place, instead of manually changing each markdown file written by that author.
Is it possible to have a similar, generated workflow for components? Or could I pass the author's name/bio file name to a component that does a query and processes the resulting markdown?
Edit: As I've considered this, I don't see much benefit of a markdown for my bios vs a component. Would it be bad form to have a component AuthorBio for the format and several components like JohnDoeBio or JaneSmithBio that return an AuthorBio with some information passed in props to render for them? I am fairly certain I can reference these components from my markdown or let my template choose them based on frontmatter, though that might lead to a large switch...
I had the exact same thought process! This is how I solved it:
BlogPostTemplate.jsx
<Layout>
<ShortBio {...authorData} /> // show the author bio on top of the blog post
<div
className="blog-post"
dangerouslySetInnerHTML={{ __html: html }} // your markup as HTML
/>
</Layout>
ShortBio.jsx
export const ShortBio = ({ authorPic, authorName, datePublished, readingTime }) => {
const postInfo = `${readingTime} ยท ${datePublished}`;
return (
<AuthorDiv>
<ImageAvatars src={authorPic} alt={authorName} />
<TextStylesDiv>
<Typography>{author}</Typography>
<Typography>{shortBioText}</Typography>
<Typography>{postInfo}</Typography>
</TextStylesDiv>
</AuthorDiv>
);
};
GraphQL:
export const blogQuery = graphql`
query ($slug: String!) {
blog: markdownRemark(fields: {slug: {eq: $slug}}) {
html
frontmatter {
title
date(formatString: "DD MMMM YYYY")
author
}
excerpt(pruneLength: 165)
fields {slug}
wordCount {
words
}
}
}
`;
Use the power of Gatsby and GraphQL and determine the author by its metadata in the markup. Look at the GraphQL query: I have an author tag defined therefore I can dynamically set an author just in the markup of the blog post.
Or could I pass the author's name/bio file name to a component that
does a query and processes the resulting markdown?
Yes, use an author tag in the frontmatter of your markdown.
---
title: Hello World
date: "2018-01-15"
author: "Solid Snake"
---
Edit: As I've considered this, I don't see much benefit of a markdown
for my bios vs a component. Would it be bad form to have a component
AuthorBio for the format and several components like JohnDoeBio or
JaneSmithBio that return an AuthorBio with some information passed in
props to render for them? I am fairly certain I can reference these
components from my markdown or let my template choose them based on
frontmatter, though that might lead to a large switch...
Creating several static author components is fine if you can confidently state that the the amount of author stays small. Be pragmatic. Do it like you said.
Hello i am using this custom property pane control called PropertyFieldCodeEditor. what i want is to display the actual webpart code as the initial value of the code editor, then after i click save, the changes will be reflected on the webpart..
this is the code of PropertyFieldCodeEditor
PropertyFieldCodeEditor('htmlCode', {
label: 'Edit Code',
panelTitle: 'Edit Code',
initialValue: "",
onPropertyChange: this.onPropertyPaneFieldChanged,
properties: this.properties,
disabled: false,
key: 'codeEditorFieldId',
language: PropertyFieldCodeEditorLanguages.HTML
})
i tried to put this.domElement on initialvalue but it only accept string, also i cand find a way to convert this.domelement to string..
also what should i put inside
protected onPropertyPaneFieldChanged(path: string, newValue: string) {}
For initialValue, you should be able to use this.domElement.innerHTML or this.domElement.outerHTML. Both are strings representing the contents of domElement (note, domElement is really just an HTMLElement).
outerHTML will include everything, including one extra div layer on the outside:
<div style="width: 100%;">
<div class="helloWorld_d3285de8">
...
</div>
</div>
innerHTML is only the inside contents of that div:
<div class="helloWorld_d3285de8">
...
</div>
You'll probably want innerHTML, since that's what's initially used in the render method.
Once you set the initialValue, you would have accomplished copying your web part code into the PropertyFieldCodeEditor. Now you would need to get the PropertyFieldCodeEditor contents (which is stored in your property htmlCode) assigned back into this.domElement.innerHTML.
Unfortunately, in onPropertyPaneFieldChanged, this points to the PropertyFieldCodeEditor, not to the web part class anymore. You may or may not be able to do it here - I didn't look too deeply into it.
The easiest solution I figured was, in render, to assign this.domElement.innerHTML like so:
public render(): void {
this.domElement.innerHTML = this.properties.htmlCode || `
<div class="${styles.helloWorld}">
...
</div>`;
}
This way, the web part will initially render whatever comes after the ||. But as soon as you save a change to the PropertyFieldCodeEditor, it will start rendering the htmlCode instead. This only works because initially htmlCode is undefined. (Note it won't work exactly like this if you assign something truthy to it via your web part's preconfiguredEntries - you would have to write some further checks. The principle is the same, though.)
I am trying to create an Advanced PDF/HTML template that will display an image using a URL that is in a custom field. The custom field is a hyperlink and the field ID is {custitem_dp_image1}. I am using the image tag and referencing the {custitem_dp_image1} field as the src but I am unable to save the template due to the following error:
java.lang.StringIndexOutOfBoundsException: String index out of range:
0 java.lang.InternalError: java.lang.StringIndexOutOfBoundsException:
String index out of range: 0
I've also tried the following code:
<#if result.custitem_dp_image1?length != 0><img src="${result.custitem_dp_image1}" style="width: 100px; height: 100px;" /> </#if>
But I received the following error when I tried to view the Advanced PDF/HTML template from a Saved Search:
The template cannot be saved due to the following errors:
org.xml.sax.SAXParseException; lineNumber: 53; columnNumber: 28; The value of attribute "src" associated with an element type "img"
must not contain the '<' character.
*The template was stored as invalid.
How can I get this to work and display the image?
The solution is to change the custom field to type = Free-Form Text and use the following freemarker code:
<#if result.custitem_dp_image1?length != 0><img src="${result.custitem_dp_image1}" style="width: 100px; height: 100px;" /> </#if>
Instead of Hyperlink use image datatype for your custom field.
You can also use a workflow to link the Hyperlink custom field to a Free-Form text field with the Store Value field checked.
Look under SuiteAnswers ID: 89195
The Hyperlink field type will return an entire HTML tag when calling for the field like this: ${result.custitem_dp_image1}
image name
So if you add it to the HTML or tag, it would break because it would look something like this:
<img src="image name">
Freemaker has functions to trim data ?keep_after and ?keep_before
So you could use this to bring just the actual URL:
result.custitem_dp_image1?keep_after('href="')?keep_before('"')
In a nutshell, everything after the href=" and everything before the ":
BUT you cant use this inside the "src" tag as it would break the HTML code. You have double quotes inside the Freemaker function and HTML would think the src tag ended at that particular location.
So to circumvent that, I'll insert the code in a variable (either global or assign) and then use just the variable in the SRC tag.
<#global custom_url = result.custitem_dp_image1?keep_after('href="')?keep_before('"')>
<img src="${custom_url}">
Oh, just my 2 cents, Users will likely want to keep the Hyperlink field type as its clickable in the User UI.
I have an html template where i want to insert some JavaScript code from outside of template itself. In my template data struct i have created a string field JS string and call it with {{.JS}}. The problem is that everything in browser is escaped:
newlines are \n
< and > are \u003c and \u003e
" is \"
Same symbols inside of a template are fine. If I Print my JS field into console it is also fine. I have seen some similar problems solved by using template.HTML type instead of string. In my case it does not work at all.
EDIT 1
The actual context is
<script language="JavaScript">
var options = {
{{.JS}}
};
</script>
Either change the field's type to template.JS like so:
type Tmpl struct {
// ...
JS template.JS
}
Or declare a simple function that converts a string to the template.JS type like so:
func toJS(s string) template.JS {
return template.JS(s)
}
And then register the function with the Funcs method and use it in your template like so:
{{toJS .JS}}
Try setting the type of JS to template.JS:
import "html/template"
type x struct {
JS template.JS
}
Documentation can be found here.
i am trying to pull an html page into my javascript file, (essentaiily the webpage will consist of a JSON string) and then i would like to set that string to a js var for eval. i have tried the $.ajax method - currently to no avail.
jQuery.getJSON('my.json', function (obj) {
MyNS.Sub.doSomething(obj);
});