Disable component editing in CQ/AEM - aem

I've got a variety of situations where I have a component A which uses cq:include to include component B. Both A and B are editable and have dialogs. However, when B is included in A, I'd like to disable direct editing of component B - I'll manage the authoring through A's dialog. I've seen a couple methods that accomplish this. The first is
<% IncludeOptions.getOptions(request, true).forceSameContext(true); %>
and the second is
<% slingRequest.setAttribute(ComponentContext.BYPASS_COMPONENT_HANDLING_ON_INCLUDE_ATTRIBUTE, true); %>
<% slingRequest.removeAttribute(ComponentContext.BYPASS_COMPONENT_HANDLING_ON_INCLUDE_ATTRIBUTE); %>
My understanding is that the first forces the child component into the parent's editing context, and the second just creates no editing context for the child at all. But I'm not sure what the difference really means. As far as I can tell, the only major difference is that the first one only affects the next component include, while the second one affects all includes between the two lines. There's also a minor difference in the markup generated. But beyond that, the dialogs seem to behave the same way. It's possible that my POC is just too simple to see the differences...are there values in a cq:EditConfig node that would be affected? Some other difference?
Thanks

You can also just swtich off edit mode for an include with the WCMMode:
<%WCMMode prevMode = WCMMode.DISABLED.toRequest(request);%>
<cq:include path="b" resourceType="B" />
<%prevMode.toRequest(request);%>
This will render B like it would be rendered on a publish server without any edit functionality.

Related

How to use selector

Let's say, I have a template A and sling:resourceType is /apps/myproject/components/basePage. In this component I've body.html and header.html and footer.html script included through slightly in body.html.
Now I am creating another template B, and sling:resourceType is /apps/myproject/components/compB and sling:resourceSuperType of compB is /apps/myproject/components/basePage.
In /apps/myproject/components/compB I have added content.html and selector.html
If I create a page (mytest.html) of type template B, then header and footer script is included correctly but when I hit this mytest.selector.html then header and footer script is not included. I want template B will have two different view based on selector.
Please let me know where I am missing.
I believe you are trying to include multiple scripts within same template to achieve different views. This is correct approach todo in AEM. But missing part is the moment you create the second script (selector.html in this case), it becomes another template and you need to code to include your entire page scripts into this script as well.
When you override scripts from /libs/wcm/foundation/components/page component, they ll work fine when your custom script names matches to parent component. For example your body.html will override /libs/wcm/foundation/components/page/body.html and page will render how it is coded. When you create selector.html it becomes independent script as there is no /libs/wcm/foundation/components/page/selector.html.
You need to define all behavior (to include header, footer script etc) explicitly against your custom script. In this case you need include header/footer scripts explicitly into your selector.html
Using a selector means that you're using some special implementation of your component. For instance, your component may have several charts and you want to encapsulate those in your selectors and use it through AJAX from browser, and reuse those selectors in your main component as well.
Currently, you're trying to achieve is to use your header and footer to another component which breaks the encapsulation rule. Rather do this, take out your header.html and footer.html and make those individual components and you it in your basePage as well as your child pages.
See the snippet below:
<div data-sly-resource="${'header' # resourceType='/apps/myproject/components/header'}">
<p>Your body and anything you want to put here</p>
<div data-sly-resource="${'footer' # resourceType='/apps/myproject/components/footer'}">
This way, you can reuse your headers whereever you want even in your selectors.

AngularJS - Wrapping nested <select> in a <div> in a form makes its control not be bind anymore

I'm doing a kind of select2 but with much less functionality and we want the form that is above to know about this Control (so we can use $dirty and $invalid).
But I've noted that if you wrap the select that is in the directive's HTML with a div, the $dirty and $invalid of that control stop working. Any idea why ?
Try it out on this http://plnkr.co/edit/UV425G2SMcqRYeX2N4qw?p=preview, go to the select.html file and turn
<select class='form-control' ng-model='selectedval' ng-attr-name='{{name}}' ng-options='item as item.name for item in options' required><option value=''>-- select --</option></select>
into
<div>
<select class='form-control' ng-model='selectedval' ng-attr-name='{{name}}' ng-options='item as item.name for item in options' required><option value=''>-- select --</option></select>
</div>
Ok I asked this as well in https://github.com/angular/angular.js/issues/6862 and got this answer by #caitp:
So your test case is actually running an old version of angular, which
A) does not support the ng-attr-* directives, and B) has a broken
isolate scope implementation.
This is still broken, but in different ways, using angular 1.2.15. You
have a priority issue with the ng-attr-name directive, regardless of
where the control is, and so it gets added to the form
control with the name you aren't expecting.
The reason this "works" with 1.0.8 and without wrapping it in a div,
is because with replace: true in your directive, we merge the
attributes from the directive's compile node (which does contain
name="...") into the root node of the template, so you're sort of
accidentally taking advantage of a poorly documented behaviour of the
compiler, in that case.
Unfortunately, there isn't really a good way to have dynamic form
control names yet (and this is really the root of the problem you're
having), there are a number of PRs adding support for this, and I've
written a hack to decorate the ngModel controller to make this work
(although it might not work anymore, depending on if the new
$interpolate api landed yet or not), you can see that at
http://plnkr.co/edit/hSMzWC?p=preview
So, Matias has an alternative solution for this, it's not clear which
one is going to land --- but in any case, that's about what your issue
is.
In the future it would be good to ask about these on
http://webchat.freenode.net/?channels=angularjs or
https://groups.google.com/forum/#!forum/angular to get answers to
these kinds of support questions (this is not a bug, per se, although
the "issue" you're seeing might be documented better, so PRs welcome
for clarifying that in the compiler docs).

How to stop MooTools stripping element IDs when clicked in Joomla 2.5.x using the 'modal' class [duplicate]

I have a form in a module that I want to appear in a modal window. Depending on the id the window may be blank, or if it does show any content all classes and ids are removed, so I can't validate or style the form.
Truncated Code:
...
<div id="feedback">
<div class="feedbackinner">
<!-- form module -->
<div id="contact-wrapper">
<!--form elements with ids and classes-->
</div>
<!-- end module -->
</div><!-- end .feedbackinner -->
</div><!-- end #feedback -->
This triggers the modal window without any ids or classes (using Firefox Web Developer outline current elements):
Click for ugly unstyled form that won't validate
This triggers a blank modal window:
Click if you like staring at a blank white box
So most importantly how do I keep all the ids and classes inside the modal window, and why won't calling the parent div work?
( As a work around I moved the form to a component view then called it using handler: 'iframe' instead of clone. I still want to know what's going on with the modal window. )
Thanks!
not seen the code but implications of using Element.clone on an element are apparent. By nature of HTML, id is meant to be unique. This means you are not really supposed to have more than one element with the same id injected into the DOM at the same time.
MooTools mirrors the sentiment correctly by implicitly removing the id from any element it creates a clone of:
https://github.com/mootools/mootools-core/blob/master/Source/Element/Element.js#L860
the .clone method accepts optional arguments which allow you to override stuff:
clone: function(contents, keepid){ - see http://mootools.net/docs/core/Element/Element#Element:clone as well.
cloned elements also lose all the events you may have assigned to them (but cloneEvents can help with that).
I would recommend looking at the squeezebox implementation and double check that the clone is implemented in the intended way. A better practice may be to adopt and re-attach the elements instead - or to copy the whole innerHTML (though this will once again cause non-delegated events to fail).

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!

Do you use <%: %> or <%= %> for html helpers in ASP.NET MVC 2.0?

I know they now have this in ASP.NET MVC 2.0 <%: Model.CustomerName %>
So when you make HTML helpers is it better to use this way now (provided that you do not want to do HTML encoding)?
Using <%: %> should be used whenever you display user entered/submitted data to make your web pages safer.
But sometimes it's just not viable to HTML encode everything. What if you do want to preserve some HTML formatting? In this case you will have to use the regular <%= %> statement. Let's think of an example where this is the case.
Real-life example
Let's say you have some web content where users can submit their comments. You would like to provide the ability to preserve some formatting (at least line breaks). In this case you will have to preserve <br/> elements when later displaying these comments. You have two choices:
Cleanup and format comments when you store them in the DB - in this case you would strip all HTML tags from submitted comments and then replace all new lines (\n) with <br/>. When you would like to display this comment you could then call <%= Comment %>
Cleanup and format comments when you display them - in this case you would most probably call this <%= Html.Encode(Comment).Replace("\n", "<br/>") %>
Which one is better/safer depends on each particular case, but cleaning up HTML tags is always a nice step to include in any of the two. Everything also depends on allowed formatting definition. Should those be entered as regular tags or something similar to markdown or something completely different depends on you and the code in the end will most certainly depend on it.
Second approach advantages/disadvantages
advantage
Let's say that you do provide some formatting capabilities but after about a year or so you decide to change formatting rules or something related to them (which is quite common). If you use the second approach the new rules will work with old comments as well, because they were stored as is, while the first approach will loose its significance with old data. One example would be if you'd auto-detect web links in these comments in the cleanup/formatting phase. Using the first approach all links in old comments would stay unclickable, but if you used the second one even older comments with links would format them as clickable.
disadvantage
Second approach uses much more processing than the first one, because every comment would have to be preprocessed each time it's displayed, while in the first approach they're processed only once when we store them in the DB. Depending on the formatting/cleanup complexity and quantity of comments on each page this may become significant.
If processing does become a problem you should think of an alternative to use first approach, but while cleaning up and re-formatting the comment you'd save both versions in your DB. Original submitted comments as well as processed ones. So when you do change formatting rules you can always reformat old comments because you stored originals.
Yes, you always want to use <%: Model.CustomerName %> from now on where you can. Only in very specific cases should you use <%= %> but try not to use it at all.
If you are creating your own html helpers that you don't want to be encoded, then just return a MvcHtmlString from them.
E.g. This is a extension method I created to display a tick icon if the passed in value is true.
public static MvcHtmlString MECross(this HtmlHelper html, string value, string text)
{
if (Convert.ToBoolean(value))
{
string spanTag = string.Format("<span class=\"replace icon-cross\" title=\"{0}\"><em></em>{1}</span>",
html.AttributeEncode(text),
html.Encode(text));
return MvcHtmlString.Create(spanTag);
}
return MvcHtmlString.Empty;
}
Note that I Encode and AttributeEncode anything that could be dangerous in my extension method and then return a MvcHtmlString.
HTHs,
Chares