How do I wrap an empty submenu? - menu

I have this menu in TYPO3:
HEADER = HMENU
HEADER {
1 = TMENU
1 {
expAll = 1
NO = 1
NO {
wrapItemAndSub = <ul class="select one"><li>|</li></ul> || <ul class="select two"><li>|</li></ul>
}
ACT < .NO
ACT = 1
ACT {
wrapItemAndSub = <ul class="current one"><li>|</li></ul> || <ul class="current two"><li>|</li></ul>
}
}
2 < .1
2.wrap = <ul class="sub">|</ul>
2.NO.wrapItemAndSub = <li>|</li>
2.ACT.wrapItemAndSub = <li class="current_sub">|</li>
}
Here is the resulting HTML code:
<ul class="current one">
<li>
Homepage
<ul class="sub">
<li>Subpage</li>
</ul>
</li>
</ul>
<ul class="current two">
<li>
Second page
</li>
</ul>
As you can see, there are no subpages below the second page. That is the reason <ul class="sub">...</ul> is not rendered for second page.
However, I need the <ul class="sub"></ul> - even if there is nothing in it.
How can I get it into my code?

Premise: the whole menu seems a bit...odd... at least for my tastes (each first level item is wrapped with an <ul>, and you also require an additional empty <ul> even without subitems...)
Said that, this trick should work: Basically I appended at the NO state a "fake" empty <ul class="sub"></ul> and I removed it when the actual subpages kick in.
HEADER = HMENU
HEADER{
1 = TMENU
1 {
expAll = 1
NO = 1
NO {
wrapItemAndSub = <ul class="select one"><li>|</li></ul> || <ul class="select two"><li>|</li></ul>
}
NO.after = <ul class="sub"></ul>
ACT < .NO
ACT = 1
ACT {
wrapItemAndSub = <ul class="current one"><li>|</li></ul> || <ul class="current two"><li>|</li></ul>
}
IFSUB < .NO
IFSUB = 1
IFSUB.after =
ACTIFSUB < .ACT
ACTIFSUB = 1
ACTIFSUB.after =
}
2 < .1
2.wrap = <ul class="sub">|</ul>
2.NO.wrapItemAndSub = <li>|</li>
2.ACT.wrapItemAndSub = <li class="current_sub">|</li>
}

This is the solution I ended up using. I still took care to remove the additional code again for the second level and I made sure the right classes still are applied on level 2:
HEADER = HMENU
HEADER {
1 = TMENU
1 {
expAll = 1
NO = 1
NO {
wrapItemAndSub = <ul class="select one"><li>|</li></ul> || <ul class="select two"><li>|</li></ul>
}
NO.after = <ul class="sub"><li class="empty"> </li></ul>
ACT < .NO
ACT = 1
ACT {
wrapItemAndSub = <ul class="current one"><li>|</li></ul> || <ul class="current two"><li>|</li></ul>
}
IFSUB < .NO
IFSUB = 1
IFSUB.after =
ACTIFSUB < .ACT
ACTIFSUB = 1
ACTIFSUB.after =
}
2 < .1
2.wrap = <ul class="sub">|</ul>
2.NO.wrapItemAndSub = <li>|</li>
2.NO.after =
2.ACT.wrapItemAndSub = <li class="current_sub">|</li>
2.ACT.after =
2.IFSUB.wrapItemAndSub = <li>|</li>
2.ACTIFSUB.wrapItemAndSub = <li class="current_sub">|</li>
}

Related

CheerioJS get specific <li> where header text 'What I Want'

I'm trying to get li elements where the header is 'What I want'
This is my Code:
let wants = []
$$('li').each((wantIdx, wantElement) => {
const want= $(relatedArticleElement).text()
wants.push(want)
})
and this is the HTML i'm trying to parse from:
<div class="side-list-panel">
<h4 class="panel-header">What I Want</h4>
<ul class="panel-items-list">
<li>
1
</li>
<li>
2
</li>
<li>
3
</li>
<li>
4
</li>
<li>
5
</li>
</ul>
</div>
<div class="side-list-panel">
<h4 class="panel-header">What I don't want</h4>
<ul class="panel-items-list">
<li>
a
</li>
<li>
b
</li>
<li>
c
</li>
<li>
d
</li>
<li>
e
</li>
</ul>
</div>
this code gets me every single li elements in the page obviously, is there any way i can only get the lis under the 'What I Want' panel-header?
You can get those with:
$('h4:contains("What I Want") + ul li').get().map(li => $(li).text())
You can try JQuery's contains if Cheerio supports it Example $('td:contains("male")')

How to select all nodes beetwen certain headers?

Each <header> tag contains a Title of Conference.
Each <ul> tag contains the links of this conference.
When I'll to try to crawl the website, I'm try to associating the <header> tag with yours links in <ul> tags. But I don't know how I can only select the <ul> tags of are sibling two certain <headers>.
HTML:
<header>... 0 ... </header>
<ul class="publ-list">... 0 ...</ul>
<header>... 1 ... </header>
<ul class="publ-list">... 0 ...</ul>
<header>... 2 ... </header>
<ul class="publ-list">... 0 ...</ul>
<p>...</p>
<ul class="publ-list">... 1 ...</ul>
<header>... 3 ...</header>
<ul class="publ-list">... 0 ...</ul>
<ul class="publ-list">... 1 ...</ul>
<ul class="publ-list">... 2 ....</ul>
<ul class="publ-list">... 3 ....</ul>
<ul class="publ-list">... 4 ....</ul>
<header>... 4 ...</header>
Example:
<ul> tags are sibling of header[0] and header[1]
<ul class="publ-list">... 0 ...</ul>
<ul> tags are sibling of header[2] and header[3]
<ul class="publ-list">... 0 ...</ul>
<ul class="publ-list">... 1 ...</ul>
Some cases:
It's possible more than one ul tag between header tag
Sometimes has a p tag between ul tags
All tags are siblings!
All ul has class "publ-list"
My code:
TITLE_OF_EDITIONS_SELECTIOR = 'header h2'
GROUP_OF_TYPES_OF_EDITION_SELECTOR = ".publ-list"
size_editions = len(response.css(GROUP_OF_TYPES_OF_EDITION_SELECTOR))
i = 0
while i < size_editions:
# Get the title of conference
title_edition_conference = response.css(TITLE_OF_EDITIONS_SELECTIOR)[i]
# Get datas and links of <ul> tags "(.publ-list)"
TYPES_OF_CONFERENCE = response.css(GROUP_OF_TYPES_OF_EDITION_SELECTOR)[i]
TYPE = TYPES_OF_CONFERENCE.css('.entry')
types_of_edition = {}
size_type_editions = 0
for type_of_conference in TYPE:
title_type = type_of_conference.css('.data .title ::text').extract()
link_type = type_of_conference.css('.publ ul .drop-down .body ul li a ::attr(href)').extract_first()
types_of_edition[size_type_editions] = {
"title": title_type,
"link": link_type,
}
size_type_editions = size_type_editions + 1
editions[i] = {
"title_edition_conference": title_edition_conference,
"types_of_edition": types_of_edition
}
i = i + 1
Problem of My Code
Sometimes there are many ul tags
Sometimes has a <p> tag and it's break my xPath, and get only the previous <ul> tags.
I got it testing with JQuery on Console of Google Chrome, example:
"$($('header')[0]).nextUntil($('header')[1])"
But How I can select this using xPath or CSS Selector? Thank you!
Following combination of css selectors and python for loop can solve this task.
from parsel import Selector
html = """
<ul class="publ-list">p1</ul>
<header>h1</header>
<ul class="publ-list">p2</ul>
<header>h2</header>
<ul class="publ-list">p3</ul>
<header>h3</header>
<ul class="publ-list">p4</ul>
<p>p_tag_1</p>
<ul class="publ-list">p5</ul>
<header>h4</header>
<ul class="publ-list">p6</ul>
<ul class="publ-list">p7</ul>
<header>h5</header>
<ul class="publ-list">p8</ul>
"""
response = Selector(text=html)
tags = response.css("header, ul")
output = {}
key = False
for t in tags:
if key and "<ul" in t.css("*").extract_first():
output[key].append(t.css("::text").extract_first())
elif "<header>" in t.css("*").extract_first():
key = t.css("::text").extract_first()
if key not in output.keys():
output[key]=[]
else:
pass
print(output)
Output is:
{'h1': ['p2'], 'h2': ['p3'], 'h3': ['p4', 'p5'], 'h4': ['p6', 'p7'], 'h5': ['p8']}
This css selector: tags = response.css("header, ul") returns list of <header> and <ul> tags in the same order as in the html code.
After that we can iterate through received tags using for loop and select required data.
Try to use following-sibling like here:
>>> txt = """<header>..</header>
... <ul class="publ-list">...</ul>
... <header>..</header>
... <ul class="publ-list">...</ul>
... <header>..</header>
... <ul class="publ-list">...</ul>
... <p>...</p>
... <ul class="publ-list">...</ul>
... <header>..</header>
... <ul class="publ-list">...</ul>
... <ul class="publ-list">...</ul>
... <header>..</header>"""
>>> from scrapy import Selector
>>> sel = Selector(text=txt)
>>> sel.xpath('//header/following-sibling::*[not(self::header)]').extract()
[u'<ul class="publ-list">...</ul>', u'<ul class="publ-list">...</ul>', u'<ul class="publ-list">...</ul>', u'<p>...</p>', u'<ul class="publ-list">...</ul>', u'<ul class="publ-list">...</ul>', u'<ul class="publ-list">...</ul>']
So with //header/following-sibling::*[not(self::header)] we choose all header siblings, but not header.
This may be what you're looking for.
html = """
<ul class="publ-list">...</ul>
<header>..</header>
<ul class="publ-list">...</ul>
<header>..</header>
<ul class="publ-list">...</ul>
<header>..</header>
<ul class="publ-list">...</ul>
<p>...</p>
<ul class="publ-list">...</ul>
<header>..</header>
<ul class="publ-list">...</ul>
<ul class="publ-list">...</ul>
<header>..</header>
<ul class="publ-list">...</ul>
"""
Note I added a <ul>before the first and after the last <header>..</header> sets.
This expression
//ul[
preceding-sibling::header
and
following-sibling::header
]
should select all the <ul> tags, except those I added before and after, and none of the <p> tags which may be in the way.

How to concatenate HREF to get id from database?

NodeJS, Mongoose
<% for(var i = 0; i < articles.length; i++){ %>
<ul class="list-group">
<li class="list-group-item">
<a href="/article/<%=articles._id%>">
<%= articles[i].title %>
</a>
</li>
</ul>
<% } %>
<% include partials/html-footer %>
How do I make it go to /articles/articles._id? I've tried -
<a href="/article/"+<%=articles._id%>>
as well. If there's anything else you need to see, let me know. Don't know what else to post.
You are missing the array index:
<a href="/article/<%= articles[i]._id %>">

Typo3 Menu - problems with templating

I know there are many tuts for creating a menu with typo3.. But it doesn't work for me, so I hope you can help me..
I do not know why my generated code will not show my sublevel-pages "Subpage 1" and "Subpage 2"..
My menu-structure is the following:
Home
Imprint
Subpage 1
Test 1
Subpage 2
My Code in my template-file
page = PAGE
page.10 = TEMPLATE
page.10.workOnSubpart = DOCUMENT
page.10.template = FILE
page.10.template.file = fileadmin/Template/index.html
temp.tmenu= HMENU
temp.tmenu{
1 = TMENU
1.wrap = <ul class="menu-level1">|</ul>
1{
NO{
wrapItemAndSub = <li>|</li>
}
ACT=1
ACT{
wrapItemAndSub = <li class="menu-level1-active">|</li>
}
CUR=1
CUR{
wrapItemAndSub = <li class="menu-level1-current-active">|</li>
}
IFSUB=1
IFSUB{
wrapItemAndSub = <li class="menu-level1-with-subpage">|</li>
}
}
2 = TMENU
2.wrap = <ul class="menu-level2">|</ul>
2{
NO{
wrapItemAndSub = <li>|</li>
}
ACT=1
ACT{
wrapItemAndSub = <li class="menu-level2-active">|</li>
}
CUR=1
CUR{
wrapItemAndSub = <li class="menu-level2-current-active">|</li>
}
IFSUB=1
IFSUB{
wrapItemAndSub = <li class="menu-level2-with-subpage">|</li>
}
}
3 = TMENU
3.wrap = <ul class="menu-level3">|</ul>
3{
NO{
wrapItemAndSub = <li>|</li>
}
ACT=1
ACT{
wrapItemAndSub = <li class="menu-level3-active">|</li>
}
CUR=1
CUR{
wrapItemAndSub = <li class="menu-level3-current-active">|</li>
}
IFSUB=1
IFSUB{
wrapItemAndSub = <li class="menu-level3-with-subpage">|</li>
}
}
}
page.10.subparts {
METANAV < temp.tmenu
}
And this is the generated output:
<ul class="menu-level1">
<li class="menu-level1-current-active">Home</li>
<li class="menu-level1-with-subpage">Imprint</li>
<li class="menu-level1-with-subpage">Test 1</li>
</ul>
http://typo3buddy.com/typoscript/menus/tmenu-left-menu/
expAll = 1
is your golden ticket

Finding Current Page in SailsJS

Does anyone know of a prettier way to output a class name to a list element (in this case) using EJS?
<% var active = "active"; %>
<div class="header">
<ul class="nav nav-pills pull-right">
<li class="<% if(req.path == '/user') { %><%= active %><% } %>">Users</li>
<li class="<% if(req.path == '/about') { %><%= active %><% } %>">About</li>
<li class="<% if(req.path == '/contact') { %><%= active %><% } %>">Contact</li>
</ul>
<h3 class="text-muted">Sails Tutorial App</h3>
</div></li>
You can do it like this :)
<li class="<%= (req.path == '/user') ? 'active' : '' %>">Users</li>
It's a little bit prettier I guess...

Resources