NetSuite Advanced PDF/HTML - Displaying images with URL from custom field - freemarker

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.

Related

TinyMCE 5 extended_valid_elements

In input HTML I have the element:
<img id="p_W_1" name="{1234}" class="po" src="../tinymce/plugins/myplugin/img/icon.png" data-mce-src="../tinymce/plugins/myplugin/img/icon.png" style="" data-mce-selected="1">
in editor init function
extended_valid_elements:'img[id|src|class|data-mce-src|data-mce-selected|role|name]',
in otuput HTML no tags id, name
<img src="../tinymce/plugins/myplugin/img/icon.png" class="po" />
When I changed into
extended_valid_elements:'img[id|src|class|data-mce-src|data-mce-selected|role]',
on result still no name
<img id="p_W_1" src="../tinymce/plugins/myplugin/img/icon.png" class="po" />
extended_valid_elements only allows valid HTML5 attributes, and name is not allowed on <img> tags, so name is removed.
Attributes like data-mce-src are internal to tinymce and shouldn't be used, so they are also stripped out.
Please see this example and choose View > Source Code on the editor:
https://fiddle.tiny.cloud/YShaab/5
However, if you add name to extended_valid_elements, you can see that id gets removed too:
https://fiddle.tiny.cloud/YShaab/7
This seems like a bug and I'll report it to the Tiny devs.

SharepointFramework - how to set the actual webpart code as initial value in PropertyFieldCodeEditor

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.)

Ckeditor in Drupal 8 : how to remove <span> tags if they don't have class attributes?

I'm using the "Allowed html tags" filter in Ckeditor - Drupal 8.
I want Ckeditor to keep <span> tags that have specific classes or IDs, and to remove if it has no attribute.
For example :
Keep span: <span class="apple">text sample</span>
Keep span : <span id="fruit">text sample</span>
Remove span : <span>text sample</span> -> text sample
Actually, when I configure a text format, I have this code in the allowed tags field :
<p><sup><sub><span id class="apple"><a href !href accesskey id rel target title>
It keeps <span> with IDs or wanted classes, but I cannot get rid of the unwanted <span> with no attribute.
Is there any way to solve this problem with code input?
Thanks in advance,
Emilie
So here is the custom module I wrote to make it work and to get around this major bug in CKEDITOR :
<?php
use Drupal\editor\Entity\Editor;
function MODULENAME_editor_js_settings_alter(array &$settings) {
foreach ($settings['editor']['formats'] as $name => $value) {
$settings['editor']['formats']['machine_name_of_your_text_editor_profile']
['editorSettings']['allowedContent'] =
'p sup h1 h2 h3' +
'span[!id];
span(!foo);
span(!bar);
span(!jane);
span(!doe);'
;}
}
Result : spans are totally deleted if there is no ID, or if you use a class that is not mentionned in this list (foo, bar, jane or doe). You must declare all elements you need to be displayed, because this config will overwrite all previous inputs in the ACF field.
For this solution, I was inspired by :
The ACF Custom doc : https://ckeditor.com/docs/ckeditor4/latest/examples/acfcustom.html
A tread about hook_editor_js_settings_alter : https://drupal.stackexchange.com/questions/268311/hook-editor-js-setting...
Note : Limit allowed HTML tags and correct faulty HTML filter (in /admin/config/content/formats) does not act consistently with the Ckeditor API. Only a part of the options are really implemented in this field, and uses of "!" don't work. This is why the solution provided uses "hook_editor_js_settings_alter".
function MODULENAME_editor_js_settings_alter(array &$settings) {
$formats = ['basic_html', 'full_html'];
foreach ($formats as $format) {
$settings['editor']['formats'][$format]['editorSettings']['allowedContent']['span']['attributes'] = '!class';
}
}
allowedContent is an array when loaded by Drupal. Instead of replacing it with a string, you can use the ACF rules to specify whether attributes are required. This allows the config from the UI to still apply.

How do I insert unique meta tags per page using docpad events

I'm trying to write a docpad plugin that will allow me to insert meta tags unique to each page, for example og:title or og:description. I've been able to accomplish this globally with the populateCollections event for global values, but have not been able to do this per page.
I'd like for this to work without the need for a template function so that the meta tag is inserted automatically based on the document's meta. One way might be to grab the contentRendered value in the writeBefore event and do string manipulation that way, but that seems hacky.
Any ideas?
This worked for what I needed. Basically, I'm getting the rendered content right before the file is written using the writeBefore event, and doing a very simple string replace which adds the meta tags and their unique values, which is pulled from the model in the collection.
writeBefore: (opts) ->
docPad = #docPad
templateData = docpad.getTemplateData()
siteUrl = templateData.site.url
for model in opts.collection.models
if model.get('outExtension') == 'html'
url = #getTag('og:url', siteUrl+model.get('url'))
title = #getTag('og:title', model.get('title'))
content = model.get('contentRendered')
if content
content = content.replace(/<\/title>/, '</title>'+url+title+description)
model.set('contentRendered', content)
# Helper
getTag: (ogName, data) ->
return "\n <meta property=\"#{ogName}\" content=\"#{data}\" />"
Great answer David, leaving this one if someone faced the same issue I did.
Check if meta tag is broken, if it is - don't render:
renderBefore: (opts) ->
for model in opts.collection.models
if model.get('date').toLocaleDateString()=='Invalid Date'
model.set('write', false)
docpad.log model.get('title')+' has broken date format!\n\n\n\n\n'
false
I am using partials in with collections. Adding what is needed in the document like this:
```
title: Meetings and Events
layout: page
description: "This is my custom description."
tags: ['resources']
pageOrder: 3
pageclass: rc-events
```
I needed a custom CSS class by page. Then you can call it in your default template like this.
<div id="main" class="container <%= #document.pageclass %>">
Should be the same for meta
<meta name="description" content="<%= #document.description) %>" />
or check your docpad.coffee file and put together helper function for prepared content based off of a default site value combined with a #document value. Then you can just call something like the default:
<meta name="description" content="<%= #getPreparedDescription() %>" />
Which is built by this helper function:
# Get the prepared site/document description
getPreparedDescription: ->
# if we have a document description, then we should use that, otherwise use the site's description
#document.description or #site.description

Getting raw text using #Html.ActionLink in Razor / MVC3?

Given the following Html.ActionLink:
#Html.ActionLink(Model.dsResults.Tables[0].Rows[i]["title"].ToString(), "ItemLinkClick",
new { itemListID = #Model.dsResults.Tables[0].Rows[i]["ItemListID"], itemPosNum = i+1 }, ...
Data from the model contains HTML in the title field. However, I am unable to display the HTML encoded values. ie. underlined text shows up with the <u>....</u> around it.
I've tried Html.Raw in the text part of the ActionLink, but no go.
Any suggestions?
If you still want to use a helper to create an action link with raw HTML for the link text then I don't believe you can use Html.ActionLink. However, the answer to this stackoverflow question describes creating a helper which does this.
I would write the link HTML manually though and use the Url.Action helper which creates the URL which Html.ActionLink would have created:
<a href="#Url.Action("ItemLinkClick", new { itemListID = #Model.dsResults.Tables[0].Rows[i]["ItemListID"], itemPosNum = i+1 })">
#Html.Raw(Model.dsResults.Tables[0].Rows[i]["title"].ToString())
</a>
MVCHtmlString.Create should do the trick.
Using the actionlink below you do not need to pass html in the model. Let the css class or inline style determine how the href is decorated.
#Html.ActionLink(Model.dsResults.Tables[0].Rows[i]["title"], "ItemLinkClick", "Controller", new { #class = "underline", style="text-decoration: underline" }, null)
those are the cases that you should take the other path
#{
string title = Model.dsResults.Tables[0].Rows[i]["title"].ToString(),
aHref = String.Format("/ItemLinkClick/itemListID={0}&itemPosNum={1}...",
Model.dsResults.Tables[0].Rows[i]["ItemListID"],
i+1);
}
#Html.Raw(title)
Remember that Razor helpers, help you, but you can still do things in the HTML way.
You could also use this:
<a class='btn btn-link'
href='/Mycontroler/MyAction/" + item.ID + "'
data-ajax='true'
data-ajax-method='Get'
data-ajax-mode='InsertionMode.Replace'
data-ajax-update='#Mymodal'>My Comments</a>

Resources