Populate a html tag like <h2> from AEM dialog - aem

I'm trying to allow an author to change the heading size in the markup based on a dropdown in the dialog with the options "h1, h2, h3, h4". If none is selected, it should default to h2.
I'm trying to do this with ternary code like I would for dynamic classes or content, but when I do this it just prints the code out on the page. The result of the following should be <h2> Heading </h2> or have h2 replaced by a dialog selection
<${properties.headingSize ? properties.headingSize : 'h2'}>
${properties.heading}
</${properties.headingSize ? properties.headingSize : 'h2'}>
The result of this code in Inspect Element is
<${properties.headingSize ? properties.headingSize :="h2" }>Heading <!--${properties.headingSize-->
Is this not a recommended way to accomplish dynamic markup? Or is there a way to get the ternary to work correctly?

The recommended way to solve your problem is to make use of the data-sly-element statement to replace your element name. Sample usage is shown below.
<h2 data-sly-element="${properties.headingSize || 'h2'}">${properties.heading}</h2>
For more information on the acceptable values for data-sly-element as well as the available block statements that can be used in HTL, kindly refer this official documentation

Related

How to apply colors that are stored in mongodb to ejs templates?

I am storing colors codes as a input from user into mongodb through mongoose. I tried to apply those codes into ejs template parts for styling. Can't figure it how can i do that.
I tried this way but it is showing error mark here :
Please my image :
colors are applying but the problems is error mark. I should remove that error mark.How can i do that?
Please don't send code as screenshot. It appears that you're being warned by the VSCode that you have syntax error but it appears ok, unless you have misspelled the variable name Primarycolor
<button style="background-color: <%= Primarycolor %>!important">Send a free request</button>
Have you tried to render that page?

Pre-populating form fields with model data in Sightly/HTL

I've tried all the HTL context parameters (even 'unsafe'). When I inspect the input, I can see the value intact, but you can't see the value pre-populated in the field. I tried different types of values, different contexts, and different types of input fields. [AEM 6.2]
<input type="email" name="senderEmail" value="${userProfile.email # context='text'}"/>
If the value is rendered in page source and also visible in browser inspector, could it be that it's hidden by some weird CSS? Something like color:transparent
There are many possible causes. I'll pitch in one, to help get you thinking. Is userProfile available via the use api?
I've made this mistake before:
<div data-sly-use.bean="com.beans.Bean">
${bean.value}
</div>
// ... other code
${bean.value}
The "Bean" isn't available later, outside it's host element.
If I understand your question correctly this isn't actually about HTL, but rather about the HTML input element itself. You have an input element with a value attribute set, yet that value is not displaying in the box. If that's correct, then I'd recommend doing some investigation around HTML input value not displaying when set, rather than sightly context issues.
Some possible answer would include css styles hiding the input text or javascript clearing out the values after page load. There are certainly more potential causes, but we'd need to know more about your page to provide a better answer.
To do some of your investigation you can try loading a component with only that input in it and see if that works, that would eliminate any css or js executing elsewhere on the page.

Generate dynamic key in i18n AEM

I have requirement for having a dynamic key for getting value in i18n. I am using sightly. i would be having the initial part of the key but the last part i have to attach dynamically and then allow sightly to get the value for the same. Could you please help me on it.
I guess best practice would be to have a getter at some component-bean to avoid as much programming logic within the markup as possible. If you like/need to put the logic into the html anyway try something similar to this:
<p data-sly-test.keyPostfix="${isTrue ? 'true text' : 'false text'}"
data-sly-test.i18nKey="${['some.i18n.key', keyPostfix] # join='.'}"
data-sly-text="${i18nKey # i18n}">This text will be replaced by sly-text!</p>

CQ Dialog: Possible to provide placeholder in text?

We have a requirement wherein a section of a page will be part authorable and part dynamic. What I mean by this is "You have 6 visits left out of 16." The 6 and 16 in the sentence are coming from a REST service call but the text "You have...visits left out of.." has to be authorable through dialog. Also, we are using AEM 6.
Thanks in advance
Maybe this solution will help others looking for simple placeholder text for their dialog textfields (OP not so much). Use an emptyText attribute...
<dialogText fieldLabel="AEM CLassic UI Text" jcr:primaryType="cq:Widget"
name="./nameOfText" emptyText="THIS IS THE PLACEHOLDER" xtype="textfield"/>
Perhaps you can start by extending foundation/components/text, where the user would be expected to enter a valid formatable string (i.e. "You have %d visits left out of %d").
In your component you would be implementing text.jsp therefore overriding the default behavior of foundation/components/text, in which you can do something like
<cq:text property="text" escapeXml="true"
placeholder="<%= Placeholder.getDefaultPlaceholder(slingRequest, component, null)%>"
tagName="span"
tagClass="myformatedmessage" />
You use tagName and tagClass which will wind up putting the formattable text in a <span class="myformatedmessage">...</span>. Then use jQuery to find it and populate the format placeholders after getting the data via ajax. All that jQuery code you can probably put into a clientlib folder within the same component you extended.
Based on your description, I think you are looking for replacement or substitution instead of placeholders.
"placeholder" generally refers to display text inside a form input that is displayed until the user enters data in the field (such as hint data).
You generally have 3 options for replacing parts of the data:
Server-side (prevents page from being cacheable in dispatcher). Requires parsing authored content & replace some kind of tags with desired REST data, such as "You have ${x} visits left out of ${y} total". Other ways of "tagging" substitution data could look like "You have %x% visits left out of %y%"
client-side JavaScript DOM manipulation once REST data returns. ie $el.html(newDomContentString)
client-side JavaScript templates (handlebars, dust, etc). Takes more initial setup in JS, but generally scales better.

Prevent EPiServer from wrapping content in <p> tags

I'm working on a site in EPiServer, and whenever I create a page property with the type set to "XHTML string" (which uses the WYSIWYG content editor in Edit mode), it wraps all content in <p> tags.
Is there any way to prevent this from happening? I can't remove the paragraph margins universally through my CSS (e.g. p {margin: 0 !important;}) since I do need the margins for actual paragraphs of text. I've even tried going to the HTML source view in the editor and manually deleting the <p> tags that it generates, but it immediately adds them back in when I save!
It doesn't happen when the property type is either a long or short string, but that's not always an option since the content might contain images, dynamic controls, etc.
This is becoming a real nuisance since it's very hard to achieve the layout I need when basically every element on the page has extra margins applied to it.
As Johan is saying, they are there for a reason - see more info here. That being said, it's not impossible to remove them. It can be done in one of two ways (taken from world.episerver.com:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
myEditor.InitOptions["force_p_newlines"] = "false";
}
or
<script type="text/javascript">
tinyMCE.init({
force_p_newlines: false
});
</script>
You can add your own custom TinyMCE-config that removes P-elements or strip them out using regular expressions either when saving the page or when rendering the property/page.
I think it's a bad idea though. P-elements are what the editors generate the most and in most cases their content is also semantically correct. Better to wrap your property in a div with a class and adjust margins using CSS like you mention.
If you're using a version of EPiServer with TinyMCE editors, you can insert <br /> elements instead of <p> elements if you type shift-enter instead of enter. This should eliminate your margin problems.
More info at the link below:
http://www.tinymce.com/wiki.php/TinyMCE_FAQ#TinyMCE_produce_P_elements_on_enter.2Freturn_instead_of_BR_elements.3F
EDIT: My comment below answers his question better.
I discovered that while I can't remove the <p> tags from the source view (because it adds them back in automatically), if I replace them with <div> tags, it'll leave things alone. It does mean that I've got an extra <div> wrapping some elements that I don't really need, but at least a <div> doesn't add margins like a <p> does, so...good enough!