Plone 4: Get the parent of a page in a portlet template - plone

I have something like: site/country-1/item-1/item-2/item-3
In Item 3 I have a portlet. In its template I'm trying to show the title of Item 2 or Item 1. How can I do this?
<div tal:content="python:context.Title()"></div> gives me Item 3.
<div tal:content="python:context.aq_parent"></div> gives me <plone.app.portlets.portlets.classic.Renderer object at 0x7fa76b97a990>
<div tal:content="python:view"></div> the same: <plone.app.portlets.portlets.classic.Renderer object at 0x7fa76b97a590>
I need this information to implement a solution to have news items and events filtered by parent country, on any level.

The acquisition chain may be different from what you expect.
To see the acquisition chain check context.aq_chain.
You may have good luck trying context.aq_inner.aq_parent.
Anyway I would use the plone_context_state view, i.e.: context/##plone_context_state/parent.
Relevant links:
https://docs.plone.org/develop/plone/misc/context.html
https://github.com/plone/plone.app.layout/blob/master/plone/app/layout/globals/context.py#L155

Related

Using Data Layer to track event based rule

This is kind of confusing. suppose i have implemented a data layer with page details. The page has 2 articles, both gets redirected whenever clicked. Now suppose the tracking goes like this, Once the User clicks on the card, the name of card (h1) name will be reported in the tool. I have implemented this scenario without using data layer. (Looking for custom script in Adobe DTM data element?).
The code is mentioned below where i have defined the data layer. In DTM console I have created data elements, and mapped with the datalayer object. for Card name - DDO.pageData.cardname. Also created an event based rule and mapped with this data element. Problem here is, whenever i am clicking one article, it is taking h1 of both the article in a single evar. Ideally it should take the value of ONLY the article which is being clicked. Please suggest.
<article class="mu-item">
<a href="www.google.com" data-tags="test" target="_blank">
<div>
<h1>This is a test text for tracking</h1>
<p>This was the day when the South Stand at Old Trafford, the stadium where he played around half of his 758 matches for United, was officially renamed in his honour before his beloved Reds took on Everton in the Barclays Premier League.<br><br>
</p>
</div>
</a>
</article>
<article class="mu-item">
<a href="www.facebook.com" data-tags="{{displaytag_2}}" target="_blank">
<div>
<h1>This is new card</h1>
<p>This was the day when the South Stand at Old Trafford.<br><br>
</p>
</div>
</a>
</article>
<span>some text</span>
<script type="text/javascript">
DDO = {} // Data Layer Object Created
var pageObj = {};
var pageDOM = $('.mu-item');
pageObj.DestinationURL = $(pageDOM).find('a').attr('href');
pageObj.cardName = $(pageDOM).find('h1').text();
DDO.pageData = {
"pageName": document.title,
"DestinationURL":pageObj.DestinationURL,
"cardname":pageObj.cardName
}
</script>
<script type="text/javascript">_satellite.pageBottom();</script>
As others have mentioned, the only way to know which h1 value is relevant is to capture it during the click event.
As I mentioned in the comments of your other question
[..] DTM does not currently pass a reference to this to data elements created in the config area
There is no way around this. You must capture it during the click event as I showed you on your other question (custom script within a rule condition). As others have mentioned, making it pass through your data layer is technically an unnecessary step. There are pros and cons to actually doing it, but that's a different discussion.
Assuming you are determined to do it...
Go to Rules > Data Elements, and click Create New Data Element.
Name your data element according to whatever convention you use. For data layers, I personally like to name it the full data layer path, e.g. "DDO.pageData.cardName".
For Type, select "JS Object".
For Path, put the full path DDO.pageData.cardName
Click Save Data Element to save the data element.
Next, go to your Event Based Rule. It should still have your same Event Type (click), and Element Tag or Selector (article.mu-item).
In your Rule Conditions, select "Data > Custom" to add a custom js code box.
In here, you will still need to grab the information based on this. But instead of using _satellite.setVar() to create an on-the-fly data element, you will instead push the value to your data layer.
Example:
var articleTitle = $(this).find('h1').text()||'';
window.DDO
&&
window.DDO.pageData
&&
(window.DDO.pageData.cardName=articleTitle);
return true;
Note: I'm using jQuery syntax to get the h1 text. Based on your previous question you were having trouble with that at the time, so I showed you the vanilla js version. Not sure if you sorted that out or not, but you get the principle.
Now you can use your data layer referenced data element within the rest of your rule's fields %DDO.pageData.cardName%
Your problem is that you have multiple menu items and headlines. You would either have to create an array with all headlines (which would it make hard to get the correct entry for a click) or populate the datalayer only after a click on the element, so it always contains the data for the selected element.
However as I pointed out there is a good chance you do not need this. If you do an event based click rule with an css selector you have available a data element that DTM automatically creates - it's called %this% and contains the clicked DOM node. You should be able to get the text inside the headline with %this.textContent% (you have a nested paragraph in your headline, which I'm not sure is valid HTML, so you must allow event to bubble up in the event rule configuration).

Adding dynamic content to a jQueryUI Accordion

There are a couple of questions here, but they seem to be old and make reference to upcoming functionality, so I'm wondering if this has been done since those questions were asked.
I have a table that looks like this:
ID Category Provision
1 Plan Highlights Annual Maximum
2 Plan Highlights Lifetime Maximum
16 Benefits - Preventive Routine Preventive Care - Child
17 Benefits - Preventive Routine Preventive Care - Adult
18 Benefits - Preventive Immunizations - Child
22 Benefits - Physician Services Primary Care Physican (PCP) Office Visit
23 Benefits - Physician Services Specialty Care Physican Office Visit
24 Benefits - Physician Services Surgery Performed in Physician's Office
What I'd like to do is create an accordion with Category as the header, and then on each accordion tab I want to place a gridview with a list of all Provisions assigned to that category. The problem is, the Categories will change based on a user's selection, and the Provisions will also change based on the same selection.
If it matters, I'm using a SQL Server back end.
So, I'm trying to figure out if I can add each accordion title dynamically (pulling the names from a "Select DISTINCT Category" query), add a gridview to the accordion panel and fill the gridview (again using a "Select DISTINCT Provision" query as the data source). Is there some functionality built in to an accordion to handle this? If not, is there some place to find sample code to do it?
There's nothing special about an accordion, except classes that are added to the elements so it can be manipulated. This is the minimum markup required to create a working accordion:
<div id="myAccordion">
<h3 id="myHeader1">Header 1</h3>
<div>Stuff</div>
<h3 id="myHeader2">Header 2</h3>
<div>More Stuff</div>
</div>
and the minimum jQuery:
$('#myAccordion').accordion();
To dynamically append a header is simple:
$('#myAccordion')
.append('<h3 id="myHeader3">Header 3</h3><div>Still More Stuff</div>')
.accordion();
As for your "gridview": Whatever kind of gridview you're working with, if your result is an HTML table, you just need to and append it to the div below the h3, in similar fashion to the example I've given you for the header, and recall the accordion() function.
If you are working with the ASP.Net GridView as your tag suggests, this post will probably give you what you need to get to this point.

Getting the text value of link when clicked a particular link in a page in adobe dtm rules

Using the source code below, I need to track text values of clicked links.
How can I track this and whether page load rule or event based rule is beneficiary for it?
How to code this using dtm?
<div class="afgfj">
<section class="asked-questions">
<div class="g-bp-row-gutter p-comp-spacinottom p-rb">
<h2 class="p-heading-02 p-component-title">
Frequently Asked Questions
</h2>
<dl class="p-faq-main p-accordion"
data-ctn="S9031/26">
<dt class="p-top-10 p-faq-chapter p-active">
<span class="p-top-10-global">Top-10 FAQs</span>
<span class="p-top-10-local">Top 10 FAQs</span>
</dt>
<dd class="p-top-10 p-faq-list p-active">
<ul class="p-bullets">
<li class="p-faq-item" data-lang="ENG">
<div class="p-magnific-popup-launcher" data-comp-id="magnificPopupLauncher"
data-type="iframe"
data-title="Frequently asked questions"
data-close-label="Back"
data-href="//www.org.com/cgi-bin/oleeview?view=aa12_view_body.html&dct=QAD&refnr=0073544&slg=ENG&scy=GB&ctn=S9031/26">
How long does it take to get?
</div>
</li>
<li class="p-faq-item" data-lang="ENG">
<div class="p-magnific-popup-launcher" data-comp-id="magnificPopupLauncher"
data-type="iframe"
data-title="Frequently asked questions"
data-close-label="Back"
data-href="//www.org.com/cgi-bin/oleeview?view=aa12_view_body.html&dct=QAD&refnr=0020591&slg=ENG&scy=GB&ctn=S9031/26">
Can I recharge the appliance?
</div>
</li>
This is a perfect time to use an Event Based Rule. You'll also need to create a data element to hold the text value.
The main obstacle that I can see from your code would be identifying the A tag correctly.
First the Data Element: in DTM Rules, within Data Elements click Create New Data Element.
Enter a name, specify the type (CSS Selector seems the most appropriate here) then within the CSS Selector Chain list state how to reach it. My guess is for your code it would be "div.p-magnific-popup-launcher a" but you would need to test this. You can tell by opening a Inspect Element (F12) in Chrome or similar debugging gadget. There's a good blog about doing this from Adobe here.
You should also specify which part of the A tag to save. From your question you I believe you need 'text' which would capture items like "How long does it take to get?"
Under Event Based Rules within DTM click Create New Rule.
When you're happy with the settings on this page click Save Data Element.
Populate your name, and category if applicable. The Event Type should already be set to 'click'.
Within Tag you then have to set how to find the A tag through CSS, similar to above.
That's the basics, but you'll also need to set Criteria (what pages this should fire on). Furthermore, under the Adobe Analytics section you should set whether a pageview is incremented or not, and which eVars, Props and Events are populated as a result of the click. This is also where you can use the value from your Data Element. Under Link Tracking, choose Custom Link. Within Link Name, enter a percent sign (%) and your data elements should appear. Use the name you specified earlier.
Note: you should match up your populated eVars and Events etc. with your settings under Report Suites in the Analytics interface.
I am assuming you are attempting to get the text of an <a> element when it is clicked on.
Such as in the one below, you would want to get "How long does it take to get?":
How long does it take to get?
To do this, create an event based rule with the event type "click", set the element tag to "a". (See image below)
Next you will want to configure the Adobe Analytics section of the rule.
You will set the Tracking to s.tl() ,since you do not want to create a pageview when someone clicks the link (the page they view should already do that).
Then set an eVar and/or Prop to %this.text%. This is DTM notation to grab the text of the element that triggered the rule to fire.
Finally, set an event to trigger on this rule.
See image below for the configuration
This should track when an <a> element is clicked and store the text in an eVar

Collections in Create.js

According to Create.js' integration guide, it should be possible to create editable collections of blocks.
Relationships between entities allow you to communicate structured
content to Create.js, which will turn them into Backbone collections.
For example, to annotate a list of blog posts:
<div about="http://example.net/blog/" rel="dcTerms:hasPart">
<div about="http://example.net/my-post">...</div>
<div about="http://example.net/second-post">...</div>
</div>
This dcTerms:hasPart doesn't seem to be present explicitly in Create.js; it's probably from a vocabulary. How can one show to Create.js that this content is a collection and make it show the "Add" button? In my case, I simply have sections which contain <h2>, <h3> and <article>s.
EDIT: Using rel="hasPart" in my <section>, the button appears. Problem is Create always uses the first element as a template. In this case, it uses my <h2> as template, which is not what I intended. So my question now would be how to trigger the "add" event in my section?
Hackish solution:
Using javascript, I created a new section or article in the DOM, then restarted Create calling $('body').midgardCreate({...}) again. Create will now recognize the new block. When I edit some fields in the block, the "Save" button is enabled and I can submit the new block.

How to move components around

I'm using the 0.4.0 branch for the components as HTML files functionality. I'm trying to do the following: I have a component that controls the layout of a page. This component has some subcomponents as an array and displays them on different parts of the page based on some data in the subcomponent. Something akin to this (due to layout restrictions they have to be in different parts of the page):
<div id="section1">
<h1> Section 1 </h1>
{{# subcomponents}}
{{#isflagsection1(flag)}}
<subcomponent flag={{flag}}/>
{{/isflag}}
{{/subcomponents}}
</div>
<div id="section2">
<h1> Section 2 </h1>
{{# subcomponents}}
{{#isflagsection2(flag)}}
<subcomponent flag={{flag}}/>
{{/isflag}}
{{/subcomponents}}
</div>
<div id="section3">
<h1> Section 3 </h1>
{{# subcomponents}}
{{#isflagsection3(flag)}}
<subcomponent flag={{flag}}/>
{{/isflag}}
{{/subcomponents}}
</div>
The flag is updated from controls within each component. this works great (the DOM is refreshed each time I modify the flag) except for one issue. Instead of performing a move, the subcomponent is recreated every time the flag changes, e.g. it's destroyed and created a new. This is unfortunate for my use case because of two reasons:
The subcomponent has a rather heavy creation cost (specially in mobile) since it performs some graphics work.
The subcomponent stores some private data (a
history of changes made to the model) that either a) gets lost when
it's moved along to another section or b) has to be stored in the
top component polluting it's data model.
So what I would like to know is, is there a way to "move" the component without deleting/recreating it?
Regards,
V. SeguĂ­
Yes - every Ractive instance has two methods that allow you to do this: ractive.detach() and ractive.insert(). Unfortunately the documentation is currently lacking, but here's how you use it:
// remove the instance from the DOM, and store a document
// fragment with the contents
docFrag = ractive.detach();
// insert the instance into the container element, immediately
// before nodeToInsertBefore (the second argument is optional -
// if absent or `null` it means 'insert at end of container'
ractive.insert( container, nodeToInsertBefore );
If you're removing the instance and immediately reinserting it, there's no need to detach it first - you can just do ractive.insert(). The arguments can be DOM nodes, but they can also be CSS selectors or the IDs of elements.
Here'a a JSFiddle demonstrating: http://jsfiddle.net/rich_harris/Uv8WJ/
You can also do this with inline components (i.e. <subcomponent/> as opposed to new Subcomponent(). In this JSFiddle, we're using ractive.findComponent('subcomponent') method to get a reference to the instance: http://jsfiddle.net/rich_harris/f28t5/.

Resources