Add class to body tag using diazo with notheme - plone

i'm displaying the content of a document in an overlay using
plone/document?ajax_load=True&ajax_include_head=True as the src for an iframe.
in development mode appending &diazo.off=1 did the trick.
on the production server this sadly does not work, so i added the
ajax_load parameter as suggested in the documentation of plone.app.theming
i wrapped all my directives in a <rules if-not="$ajax_load"> element to make sure they are not applied (see code below)
now i'd need to mark the body of the iframed page with a certain class to apply different styles (eg no background color for the body in overlays)
the solution proposed for a nearly similar question does only work if you are using a theme with a body element having a class attribute to operate on.
is there a way to add a class to the content without having a theme (using )?
or do i have to supply an empty html document (index2.html) as theme and apply lots of rules to copy over css/js etc twice?
<rules if="$ajax_load">
<!-- theme href="index.html" /-->
<notheme />
<!-- only works when using a theme -->
<before theme-children="/html/body"><xsl:attribute name="class"><xsl:value-of select="/html/body/#class"/> my class</xsl:attribute></before>
<!-- thought this could to the trick but does not work at all -->
<xsl:template match="html/body">
<xsl:attribute name="class"> foo</xsl:attribute>
</xsl:template>
</rules>
<rules if-not="$ajax_load">
<theme href="index.html" />
<replace content="/html/head/title" theme="/html/head/title" />
...

Obviously without a theme to operate on, any rule referencing a theme does not work in conjunction with <notheme/>. You can however <drop> and <replace> content (I have ideas of how to implement <before> and <after> content, but its difficult to implement. Maybe in a future version of Diazo.) However you can achieve the same thing with a small amount of xslt:
<replace content="/html/body/#class">
<xsl:attribute name="class"><xsl:value-of select="."/> newclass</xsl:attribute>
</replace>

If you are using plone.app.jquerytools for your overlays, then you can pass a class parameter:
$('a.myPopover').prepOverlay({
subtype: 'iframe',
cssclass: 'my-popover'
});
In some of our project using plone.app.tiles we used a specific theme template for the overlays, that was stripped of all unecessary parts and reduced to a single wrapper div and used it for the tile edit view like so:
<theme href="minimal.html" if-path="##edit-tile" />

Related

Changing subscription box style

I added a subscription box widget and I need to change the style to put the submit button inside the input box. It currently looks like this:
enter image description here
[enter image description here][2]
And I want it to look like this:
[2]: https://i.stack.imgur.com/Z4Aqe.png
Which I know how to do with plain html, but I'm not sure how to change the Wordpress widget html while keeping the functionality. Here is the widget code:
<!-- wp:group -->
<div class="wp-block-group"><div class="wp-block-group__inner-container"><!-- wp:group -->
<div class="wp-block-group"><div class="wp-block-group__inner-container"><!-- wp:group -->
<div class="wp-block-group"><div class="wp-block-group__inner-container"><!-- wp:genesis-blocks/gb-newsletter {"instanceId":0} /--></div></div>
<!-- /wp:group --></div></div>
<!-- /wp:group --></div></div>
<!-- /wp:group -->
Thank you in advance.
That is markup outputted from the WordPress' new block-based syntax (Background)
It's not quite HTML in that if you edit it, it would not render as you would expect; it will break, because the additional block code (not shown on the screen) expects only certain .
You have a couple options here depending how much time you want to devote to this:
Determine whether your has block styling options (borders, font, font-size, etc) already built-in to the block settings. Check the genesis blocks documentation to verify this. This will be the easiest option to do what you want but if you're asking this question, I'm guessing that the block doesn't have these options.
This is probably the best route to take:
In your group block container, on the right hand side, create a css class shown in this picture. Then, go to your theme's CSS; add a selector of that CSS class and begin adding the rules that you want. This may require some trial and error because you're likely need to write some additional selectors and increase the level of specificity so you can style exactly how you want it and override some other rules already written.
(You may also need to include !important as for your rules but that is a last resort and not a best practice for writing CSS)
You may also need to do this for the gb-newsletter block as well.
Writing your own blocks (which has frustratingly has a high learning curve, imho); this will offer the most customization but will be a LOT of time.

xsl:attributes strips the "content"

I'm writing some rules in Diazo. I want, in case the user browses the "viewer" section (a browser view, not a real plone folder), to drop the "selected" class for the "home" tab in the globalnav and put "selected" class for the "viewer" tab.
<replace css:content="#portal-globalnav" css:theme="#portal-globalnav" />
<drop if-path="viewer/"
css:content="#portaltab-index_html"
attributes="class" />
<xsl:template if-path="viewer/"
match="//li[#id='portaltab-viewer']/">
<xsl:attribute name="class">selected</xsl:attribute>
</xsl:template>
But the result it's a right li portaltab-viewer with the "selected" class, but without any content inside! I obtain an empty "li" tag in the portal-globalnav O.O
What's wrong?
Vito
You need to recurse into the content of the element with xsl:apply-templates. Try:
<replace if-path="/viewer" css:content-children="li#portaltab-viewer"><xsl:attribute name="class">selected</xsl:attribute><xsl:apply-templates select="node()"/></replace>
The lack of whitespace before the xsl:attribute is necessary as I don't think I ever got around to making Diazo ignore whitespace around xsl:* elements.

Creating anchor links in rich text fields with SDL Tridion 2011 SP1

I am trying to use the anchor button in a RTF field of a Component, and getting unexpected behavior. Using the Chrome Browser from the design view, I highlight/select the heading (i.e. <h2>My Heading</h2>) I want to use as an anchor, and press the anchor button and enter the anchor name (i.e. my_place).
This results in the following code being displayed in my source tab:
<a name="my_place" id="myplace"/><h2>My Heading</h2>
This causes render problems when displaying the HTML in a browser due to the self closing <a/> tag.
I would have expected one of the following three HTML fragments being inserted into the HTML source:
<a name="my_place" id="myplace"><h2>My Heading</h2></a>
or
<h2><a name="my_place" id="myplace">My Heading</a></h2>
or
<a name="my_place" id="myplace"><a><h2>My Heading</h2>
Has anyone else experienced this? or know of a way to achieve what I had expected (without manually editing the HTML). Or is this a bug in the current version of the product.
Attached is my sample XSLT template:
<template match="a[(#name) and (count(node()) = 0)]">
<copy>
<apply-templates select="#*"/>
<xhtml:span xmlns:xhtml="http://www.w3.org/1999/xhtml" class="hidden"> </xhtml:span>
</copy>
</template>
This adds a bit more than strictly needed, but handles some other issues we have due to XML manipulation on the Content Delivery side.
Essentially it matches all empty a tags with a name attribute, and add something between them in order to stop them self closing. In our case we post process all of the XML with XSLT, so we have challenges with empty tags getting closed all the time. So as a dirty hack, we are now inserting a hidden span tag between empty tags to prevent the issue.
Thanks Chris, I've edited your solution to fit my requirements so wanted to share for anyone with this issue in the future.
Note: This moves the text inside the anchor and deletes the text outside. Fixes anchors that were intended to contain text only, not html. i.e
My solution fixes this tag:
<p><a name="anchor1" id="anchor1"></a>Anchor text</p>
To
<p><a name="anchor1" id="anchor1">Anchor text</a></p>
But not this:
<p><a name="anchor1" id="anchor1"></a><h1>Anchor text</h1></p>
Here's my xsl. Hopefully it will help give you a base, I'm sure you could easily update it to look for a following tag (I don't require this for my solution).
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" method="html" cdata-section-elements="script"/>
<xsl:template match="/ | node() | #*">
<xsl:copy>
<xsl:apply-templates select="node() | #*"/>
</xsl:copy>
</xsl:template>
<!-- fixes Tridion bug when using interface button to insert anchor in rich text field -->
<!-- gets all empty anchor tags with an id and takes any following text and copies it inside anchor -->
<xsl:template match="a[(#id) and (count(node()) = 0)]">
<xsl:copy>
<xsl:for-each select="#*">
<xsl:attribute name="{name(.)}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:value-of select="normalize-space(following-sibling::text())"/>
</xsl:copy>
</xsl:template>
<!-- delete any text after an empty anchor (template above has already copied this text inside the anchor) -->
<xsl:template match="text()[preceding-sibling::a[(#id) and (count(node()) = 0)]]" ></xsl:template>
</xsl:stylesheet>
Here's my test XML
<?xml version ="1.0"?>
<?xml-stylesheet type="text/xsl" href="tridionhtmlfield.xsl"?>
<html>
<head></head>
<body>
<p><a id="anchorlink" name="anchorlink" title="Anchor link" href="#Anchor">Anchor link</a>Some text after</p>
<p><a name="broken-with-html-name" id="broken-with-html-id"></a><h1>Anchor - broken with html</h1></p>
<p><a name="broken-text-only-name" id="broken-text-only-id"></a>Anchor - broken text only</p>
<p><a name="broken-notext-name" id="broken-notext-id"></a></p>
<p><a name="correct-name" id="correct-id">Anchor - correctly rendered</a> Some text after</p>
</body>
</html>
After transform:
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head>
<body>
<p><a id="anchorlink" name="anchorlink" title="Anchor link" href="#Anchor">Anchor link</a>Some text after</p>
<p><a name="broken-with-html-name" id="broken-with-html-id"></a><h1>Anchor - broken with html</h1></p>
<p><a name="broken-text-only-name" id="broken-text-only-id">Anchor - broken text only</a></p>
<p><a name="broken-notext-name" id="broken-notext-id"></a></p>
<p><a name="correct-name" id="correct-id">Anchor - correctly rendered</a> Some text after</p>
</body>
</html>
Hope this helps
It looks like a bug to me Chris. I've just confirmed it on Chrome, Firefox and IE. It's completely counter-intuitive that the current text selection should be ignored. (On the plus side, once you fix it manually in the source tab, everything appears to behave perfectly.)
I suggest that you report this to Tridion, and perhaps work around it by altering your templating or filter XSLT.
It is a bug in Tridion. One work-around that I suggest (and have implemented in our particular installation) is to do the following:
Edit the FormatAreaStyles.css file (found in the Tridion CMS program files) — as well as your CSS file used by the website — to include a class like this:
.hiddenanchor {
width:1px;
height: 1px;
display: block;
text-indent:-50000px;
}
Publish out your CSS file (with the new class) so that it'll format your anchors properly.
And then in the component where you are building out the anchors, you will have to:
a. type a word or series of words in your component (where you want the target to be),
b. select that text, and apply the anchor tag to it,
c. then apply the new class you've created (.hiddenanchor) to the anchor.
In the end, your "invisible" anchor would look like this:
<a name="anchorname" id="anchorname" class="hiddenanchor">Anchor Name</a>
It's a crude work-around — fully acknowledged. But it works. You don't end up with the hyperlink/underline styling until the close of the next DOM object.
As an explanation to the CSS, the anchor technically has to be visible in the DOM for it to work and to be accessible by the anchor link. So "display: none" won't work. Alternatively to taking the text-indent approach, you could absolute or fixed position the text off the screen as well.

Change the id of a theme element

Using Diazo, I have an id clash between the theme and the content and some JS which depends on the content id. How can I change the elements id attribute in the theme from one value to another?
The easiest way to change a value in the theme is to open it in your editor and edit the html ;) If you're after changing the id in the content to match markup in the theme then you can use a replace content rule, see: http://diazo.org/advanced.html#modifying-the-content-on-the-fly
(The replace content rule basically replaces xsl:template's in Diazo. The latter still work, but you should normally use the replace content now.)
This should work:
<replace css:theme="{theme-selector}" css:content="{content-selector}" />
<xsl:template match="{theme-selector}">
<xsl:attribute name="{attr-name}">
<xsl:value-of select="{attr-value}" />
</xsl:attribute>
</xsl:template>
More info:
How to transform block of content from plone being inserted into diazo theme
XSLT: How to change an attribute value during <xsl:copy>?
http://diazo.org/advanced.html#modifying-the-content-on-the-fly

How to transform block of content from plone being inserted into diazo theme

I'm using a diazo (currently plone.app.theming 1.0b1-r48205) with Plone 4.1. I want to use exactly Plone's html for the search widget except that I'd like to replace <input> element used for the search button in the search widget with a <button>. The diazo docs seem to suggest you can do this.
In my theme html file I have an empty <div id="portal-searchbox"></div>. In my rules.xml I have the following:
<rules if-content="$enabled">
<replace css:theme="div#portal-searchbox">
<xsl:apply-templates css:select="div#portal-searchbox" />
</replace>
<xsl:template css:match="div#portal-searchbox input.searchButton">
<button type="submit"><img src="images/search.png" alt="Search" /></button>
</xsl:template>
</rules>
I've tried numerous variations of this but with no success. Any help would be much appreciated.
Ok, so the following works. The reason it wasn't working before was that the <xsl:template> was not in the root level rules tag (there's a documentation bug there). The <xsl:template> must be in the root level rules tag because there is no way to apply rule conditions to an <xsl:template> currently.
<xsl:template css:match="div#portal-searchbox input.searchButton">
<button type="submit"><img src="images/search.png" alt="Search" /></button>
</xsl:template>
<replace css:theme="div#portal-searchbox" css:content="div#portal-searchbox"/>
Update: I've added support for <replace content="..."> to Diazo, so inline <xsl:template>'s are considered deprecated. Instead use:
<replace css:content="div#portal-searchbox input.searchButton">
<button type="submit"><img src="images/search.png" alt="Search" /></button>
</replace>
<replace css:theme="div#portal-searchbox" css:content="div#portal-searchbox"/>
Documentation at http://diazo.org/advanced.html#modifying-the-content-on-the-fly

Resources