Expression Engine, filter relationship's entry by category id - expressionengine

I have the channel Market and Family. Both have the same expressionengine's category group.
I want to print out all the entries of the channel Market with the category XY, and for each market I want to print ONLY the first family entry of category XY related to it.
In my solution, seems that the category parameter inside the relationship field "market-families" doesn't work. here is the code:
{exp:channel:entries channel="Market" category="{segment_2_category_id}" orderby="title" sort="asc"}
{if "{url_title}" == "{segment_3}"}
<li class="active">
{if:else}
<li>
{/if}
{market-families orderby="title" sort="asc" category="{segment_2_category_id}" limit="1"}
{title}
{/market-families}
</li>
{/exp:channel:entries}
Legend:
{segment_2_category_id} -> plugin to get the category id from a segment.
market-families -> Multiple relationship field inside channel Market
Thank you for any help :)

Have you tried manually entering the category id in the parameter instead of using the plugin just to verify that it's not the plugin?
I couldn't find any specific reference to the relationship field being able to use the category parameter in ExpressionEngine's documentation: http://ellislab.com/expressionengine/user-guide/modules/channel/relationships.html

Related

Short description info

How we add short description in the form of bullet points below the product title.
like this...in this photo bullet points are below the title
Simply add an unordered list to the product record, in the product description textarea.
<ul>
<li>List Item 1</li>
<li>List Item 2</li>
<li>List Item 3</li>
</ul>
If you're using default Cornerstone (6.6.1 at the time of this comment), you will need to:
Set theme_settings.show_product_details_tabs to false.
Move {{> components/products/description}} into the correct spot in templates/components/products/product-view.html.

Scraping data when a parent tag has a child for some element only

I am trying to scrape data from an e-commerce site for a certain product. On the result page, there are 50 products listed. Some products have original prices under them while some have discounted prices with original prices striked-out. The HTML code for that is
for non-discounted products
<div class="class-1">
<span>
Rs. 7999
</span>
</div>
For discounted product
<div class="class-1">
<span>
<span class="class-2">
Rs. 11621
</span>
<span class="class-3">
Rs. 15495
</span>
</span>
<span class="class-4">
(25% OFF)
</span>
</div>
What the result should be?
I want a code that could scroll through the list of products and extract data from Div[class='class-1]/span tag for the non-discounted product and where there is a child span[class='class-2'] present, it should extract data from only that tag and not from the Span[Class-3] tag.
Please help!!
If I understand you clearly, first you need to get a list of products with:
products = driver.find_element_by_xpath('//div[#class="class-1"]')
Now, you can iterate thru the list of products and grab the prices as following
prices = []
for product in products:
discount_price = product.find_elements_by_xpath('.//span[#class="class-2"]')
if(discount_price):
prices.append(discount_price[0].text)
else:
prices.append(product.find_element_by_xpath('./span').text)
Explanation:
Per each product I'm checking existence of //span[#class="class-2"] child element as you defined.
In case there is such an element, product.find_elements_by_xpath('.//span[#class="class-2"]') will return non-empty list of web elements. Not empty list is Boolean True in Python so if will go.
Otherwise the list is empty and else will go.

Python Splinter Star Ratings

Given the star ratings under the "Recent Comments" section here,
I am trying to build a list of the star rating per comment shown on the page.
The trouble is that each star rating objects does not have a value.
For example, I can get an individual star object via xpath like this:
from splinter import Browser
url = 'https://www.greatschools.org/texas/harker-heights/3978-Harker-Heights-Elementary-School/'
browser.visit(url)
astar=browser.find_by_xpath('/html/body/div[5]/div[4]/div[2]/div[11]/div/div/div[2]/div/div/div[2]/div/div[2]/div[3]/div/div[2]/div[1]/div[2]/span/span[1]')
The rub is that I cannot seem to access the value (filled in or not) for the object astar.
Here's the HTML:
<div class="answer">
<span class="five-stars">
<span class="icon-star filled-star"></span>
<span class="icon-star filled-star"></span>
<span class="icon-star filled-star"></span>
<span class="icon-star filled-star"></span>
<span class="icon-star filled-star"></span>
</span>
</div>
UPDATE:
Some comments do not have star ratings at all, so I need to be able to determine if a particular comment has a star rating and, if so, what the rating is.
This seems helpful for at least getting a list of all stars. I used it to do this:
stars = browser.find_by_css('span[class="icon-star filled-star"]')
So if I can get a list showing the sequence of if a comment has a star rating (something like ratings = [1,0,1,1...]) and the sequence of all stars (i.e. ['Filled', 'Filled', 'Empty'...]), I think I can piece together the sequence.
One solution:
access the html attribute of each object like this:
#Get total number of comments
allcoms = len(browser.find_by_text('Overall experience'))
#Loop through all comments and gather into list
comments = []
#If pop-up box occurs, use div[4] instead of second div[5]
if browser.is_element_present_by_xpath('/html/body/div[5]/div[4]/div[2]/div[11]/div/div/div[2]/div/div/div[2]/div/div[2]/div[1]/div/div[2]'):
use='4'
else:
use='5'
for n in range(allcoms): #sometimes the second div[5] was div[4]
comments.append(browser.find_by_xpath('/html/body/div[5]/div['+use+']/div[2]/div[11]/div/div/div[2]/div/div/div[2]/div/div[2]/div['+str(n+1)+']/div/div[2]').value)
#Get all corresponding star ratings
#https://stackoverflow.com/questions/46468030/how-select-class-div-tag-in-splinter
ratingcode = []
ratings = browser.find_by_css('span[class="five-stars"]')
for a in range(len(comments)+2): #Add 2 to skip over first 2 ratings
if a<2: #skip first 2 and last 3 because these are other ratings - by just using range(len(comments)) above to get correct # before stopping
pass
else:
ratingcode.append(ratings[a].html)

Trying to use PugJS to iterate both href attribute and link text

I'm having a hard time taking my json object and using the name and values to make a link. I've tried separate arrays as well, but I've decided it'd be easier if I set the object as {title:url} and when I use this code:
ul
each url, title in news
li= title
li= url
it returns my titles and urls like so
These are the arguments against net neutrality — and why they’re
wrong
https : //techcrunch .
com/2017/05/19/these-are-the-arguments-against-net-neutrality-and-why-theyre-wrong/
The bizarre naming trends that modern startups follow
https: //techcrunch .
com/2017/05/20/the-bizarre-naming-trends-that-modern-startups-follow/
Salesforce marches steadily toward $10B run rate goal
https :// techcrunch .
com/2017/05/19/salesforce-marches-steadily-toward-10b-run-rate-goal/
Uber threatened to fire engineer at center of Waymo trade secret
lawsuit
https :
//techcrunch.com/2017/05/19/uber-waymo-anthony-levandowski-termination-threat/
but when I try to make links with this code
each url, title in news
a(href= url) title
I get this:
titletitletitletitle
the links work, but it won't iterate the title...
any tips with this issue?
I decided to switch to an array and it seems like you need a = after (href= link) like this:
each articles in news
p
a(href = articles.url)= articles.title
li= articles.description
The issue is actually that there must be an equal sign (you were right about that) but there can be no space between the assignee (left side) and that equal sign. For example, this works:
ul
each url, title in {'/a': 'Title A', '/b': 'Title B'}
li
a(href=url)= title
... and will render:
<ul>
<li>
<a href='/a'>Title A</a>
</li>
<li>
<a href='/b'>Title B</a>
</li>
</ul>
If you omit the equals sign or leave a space like this:
ul
each url, title in {'/a': 'Title A', '/b': 'Title B'}
li
a(href=url) = title
... you'll get:
<ul>
<li>
<a href='/a'>title</a>
</li>
<li>
<a href='/b'>title</a>
</li>
</ul>

Ideal way to handle layout changes in a list

So I've stupidly designed a list of recent articles, all is good with the world BUT the first 2 entries html are markedly different then the remainder of entries.
I am yet to turn a line of code so any advice anyone an offer is greatly appreciated.
Simplistically the ul would look like:
<li class="1of2"> /* It's number 1 – give it a class to identify it as special */
<h1>{title}</h1>
<p>{short_desc}</p>
</li>
<li class="1of2"> /* It's number 2 – give it a class to identify it as special */
<h1>{title}</h1>
<p>{short_desc}</p>
</li>
<li> /* It's not number 1 or 2 – ie. every other item, NO class per se */
<h1>{title}</h1>
<p>{short_desc}</p>
</li>
If you imagine a 3 column grid for all entries but the first 2 entries are 1.5 columns each. Bit of a noodle scratch going on here, any thoughts gratefully voted upon.
PS. I will be using Stash if that helps !
Just output the class name based on the value of {count}. I've output the whole opening <li> tag here to keep it simple but you could just output the class attribute or class name itself.
{if count<=2}
<li class="special">
{if:else}
<li>
{/if}
<h1>{title}</h1>
... etc.
</li>
Incidentally, I don't think you can have class names that begin with a number.
Here's how I would do it if you want each of the first 2 to have a unique class name:
<li{if count<=2}class="top{count}"{/if}>
that will output
<li class="top1">...
<li class="top2">...
<li>...
If you want the first 2 items to have the same class:
<li{if count<=2}class="whateveryouwant"{/if}>
which will output
<li class="whateveryouwant">...
<li class="whateveryouwant">...
<li>...
Couldn't you do {if count == "1|2"}class="whatever"{/if} ?
Seems you are asking for two unique classes, one for the first entry and one for the second entry. In that case, this will work:
{if count == 1}
<li class="first">
<h1>{title}</h1>
<p>{short_desc}</p>
</li>
{if:else if count == "2"}
<li class="second">
<h1>{title}</h1>
<p>{short_desc}</p>
</li>
{if:else}
<li>
<h1>{title}</h1>
<p>{short_desc}</p>
</li>
{/if}
Also, class names that start with a number will not validate.
You could do it with simple conditionals as well if there is no "other" class that would then require the if:else part of the conditional:
<li{if count == "1"} class="first"{/if}{if count == "2"} class="second"{/if}">
<h1>{title}</h1>
<p>{short_desc}</p>
</li>
This assumes you don't have any other differences, such as different custom fields in one option versus the other, which MediaGirl's suggestion would handle more elegantly. If the only difference between them is class assignment, this is another alternative.

Resources