Get WordPress Submenus in Gatsby JS - wordpress-rest-api

I am fiddling around with Gatsby JS using WP as the backend and so far so good. Now I was trying to pull in the menu which for main menu items works just as expected. What I can't really wrap my head around is how to get the submenus pulled in.
The only related thing I found was https://github.com/gatsbyjs/gatsby/issues/2426 which does give me the submenus if I log the data. Just can't get them to be pulled into the menu.
Here is my query in layouts/index.js:
export const query = graphql`
query LayoutQuery {
allWordpressWpApiMenusMenusItems {
edges {
node {
name
count
items {
order
title
url
wordpress_children {
wordpress_id
title
url
}
}
}
}
}
}
`
This is my menu component:
class MainMenu extends Component {
render(){
const data = this.props.menu.allWordpressWpApiMenusMenusItems.edges["0"].node.items
console.log(data)
return(
<div>
<h1>Menu</h1>
<ul>
{data.map((item) =>
<li key={item.object_slug}>
<Link to={item.url}>
{item.title}
</Link>
</li>
)}
</ul>
</div>
)
}
}
export default MainMenu
I tried fiddling around with variations of
{item.children["0"].wordpress_children.title}
but just can't get it to work:/ Any ideas or pointers would be much appreciated!

I just tested this, and your logic is sound all you need is another loop to display subitems. So in your MainMenu.js you can do something like this:
class MainMenu extends Component {
render() {
const data = this.props.menu.allWordpressWpApiMenusMenusItems.edges[0].node.items
console.log(data)
return (
<div>
<h1>Main Menu</h1>
<ul>
{data.map((item) =>
<li key={item.object_slug}>
<Link to={item.url}>
{item.title}
</Link>
<ul>
{item.wordpress_children && item.wordpress_children.map((subitem) =>
<li key={item.wordpress_id}>
<Link to={subitem.url}>
{subitem.title}
</Link>
</li>
)}
</ul>
</li>
)}
</ul>
</div>
)
}
}
This line is very important {item.wordpress_children && item.wordpress_children.map((subitem)
This will check if your menu item has subitems, and if it does it will map them and iterate through them.
I hope this works for you, I tested it and it works.

Related

"Yield" doesn't work in binding.scala

Several days ago I read about binding.scala and I found it so cool therefore I decided to write my own single page app.
The problem is that I'm trying to add "li" items into "ul" element, but it seems like the component Want doesn't see updates.
The code below:
case class Movie(title: Var[String], raring: Var[Int], watched: Var[Boolean])
var movies = Vars.empty[Movie]
#dom def Want = {
println(movies.bind, "!##!##!##!")
<div class="want">
<ul>
{for (movie <- movies.value) yield {
<li>
<div>
<span>
{movie.title.bind}
</span>
<button onclick={event: Event => {
event.preventDefault()
movies.value.remove(movies.value.indexOf(movie))
println(movies.value)
}}></button>
</div>
</li>
}}
</ul>
</div>
When I change movies nothing happens.
UPDATE
After the comment below I updated the code:
def remove(movie:Movie) = {
movies.value.-=(movie)}
#dom def Want = {
println(movies, "!##!##!##!")
<div class="want">
<ul>
{for (movie <- movies.bind) yield {
<li>
<div>
<span>
{movie.title.bind}
</span>
<button onclick={event: Event => {
event.preventDefault()
remove(movie)
}}></button>
</div>
</li>
}}
</ul>
</div>
}
However, the code doesn't work.
Please change for (movie <- movies.value) to for (movie <- movies).
According to the Scaladoc of value method:
Note: This method must not be invoked inside a #dom method body.

magnific popup autoplay slideshow

I am using magnific popup for popup image slideshow. Below is what i have done.
$('.parent-container').magnificPopup({
type:'image',
delegate: 'a',
gallery: {
// options for gallery
enabled: true
},
image: {
// options for image content type
titleSrc: 'title'
}
});
And this is my HTML Markup
<div class="parent-container">
<ul class="row carousel-inner" style="margin:0; padding:0; background:red;">
<li class="active item gallery-photo" style="margin:0; padding:0; background:red;">
<img class="img-responsive" src="images/gallery-1.jpg">
</li>
<li class="item">
<img class="img-responsive" src="images/gallery-2.jpg">
</li>
<li class="item">
<img class="img-responsive" src="images/gallery-3.jpg">
</li>
</ul>
</div>
Now, everything is working fine, but i want the image to change automatically, like when i launch the popup first image will be displayed and then it should change automatically. I am not able to fine anything to make it auto in the documentation .
Your efforts will be greatly apprecialted.
I have found it, i am adding this as an answer so that someone else also can benefit out of it.
You just need to add callbacks.
I have added below code after magnificPopup({}) function. And that will solve the problem images will start moving automatically.
callbacks: {
open: {
setInterval(function() {
$.magnificPopup.instance.next();
}, 2000);
}
}

Open one node and all its parents using jstree

I'm trying to use jstree and let one node and all its parent be opened when the page is opened. Here is the html code I used to test.
<div id="treeTask">
<ul>
<li id="node_37">TEST1
<ul>
<li id="node_38">TEST2</li>
<li id="node_39">TEST3</li>
</ul>
</li>
</ul>
<ul>
<li id="node_3">TEST1
<ul>
<li id="node_4">TEST2</li>
<li id="node_6">TEST3</li>
</ul>
</li>
</ul>
</div>
And here is the call to initialize jstree and open the node.
$(function () {
$("#treeTask").jstree();
$("#treeTask").bind("ready.jstree", function (event, data) {
$("#treeTask").jstree("open_node", $("#node_4"));
if((data.inst._get_parent(data.rslt.obj)).length) {
data.inst._get_parent(data.rslt.obj).open_node(this, false);
}
});
});
I have been manipulating the code for a while, but could not make it work. I would really appreciate if anyone can help.
Thanks so much!
You can use the built-in _open_to function:
http://www.jstree.com/api/#/?q=open_to&f=_open_to%28obj%29
$("#treeTask").jstree().bind('ready.jstree', function (event, data) {
data.instance._open_to('node_4');
});
Based on #maddin solution, I've updated it to support any number of parent levels.
jsFiddle
$("#treeTask").jstree().bind('ready.jstree', function (event, data) {
$("#treeTask").jstree('open_node', 'node_4', function(e,d) {
for (var i = 0; i < e.parents.length; i++) {
$("#treeTask").jstree('open_node', e.parents[i]);
};
});
});
It should be noted that if a node is selected, all its parents will be opened automatically. This would be somewhat equivalent to the above:
$("#treeTask").jstree().bind('ready.jstree', function (event, data) {
$("#treeTask").jstree('select_node', 'node_4');
});
Maybe this is an Solution for your problem:
fiddle
$("#treeTask").jstree().bind('ready.jstree', function (event, data) {
$("#treeTask").jstree('open_node', 'node_4', function(e,d) {
if(e.parents.length){
$("#treeTask").jstree('open_node', e.parent);
};
});
});

executing java/scala code in scala.html templates

Can I execute that line of code
nav = request().path().toString()
inside of scala template like index.scala.html
I would like to have that code to check on witch side is user and to mark it on menu
using code like this in main.scala.html:
<li class="#("active".when(nav == "contact"))">
Contacts
</li>
I would recommend you different approach, create tag - resuable template, which takes Integer as an argument,
it will render menu and mark as an active different menuitem depends on value.
#(menuItem: Int)
<ul >
<li #if(menuItem==1){ class="active" } >
////
</li>
<li #if(menuItem==2){ class="active" }>
</li>
<li #if(menuItem==3){ class="active" }>
///
</li>
</ul>
from your contact page and any other page, call this tag with corresponding value, #views.html.tags.menu(1)
You can define variables like that if that is your question. If it is not your question than please try to explain your problem in more detail.
#nav = { #request().path().toString() }

HTML attribute in Scala Template

I am a Java developer who recently started to learn about the Play Framework. I have been trying to get the below template working but cant seem to get it. I have got the following in my Scala template
#navItem(label: String, link1: String) = {
#{if (Application.isAuthenticated()) {
<li class="active">
label
</li>
}
else {
<li class="disabled">
{label}
</li>
}
}
}
I am calling this later in my template like so
<ul class="nav">
#navItem("Search Documents", "/search")
</ul>
The generated link has href as localhost:9000/#link1 instead of localhost:9000/search. I am not sure whats going on.
PS: If I change my template as below it works fine. But I want to understand why the above template wont work.
#navItem(label: String, link1: String) = {
<li class="#(if (Application.isAuthenticated()) "active" else "disabled")">
#label
</li>
}
Not quite sure about this, but my guess would be the following: The #{ ... } indicates the beginning of a dynamic statement and all of its content is treated as Scala code. Thus, it is a normal if-condition with two strings as a result, both of which are simply returned in the template.
Why are you marking it as a multi-line code block anyway? Have you tried it like this? (note the missing curly braces after the 2nd # sign):
#navItem(label: String, link1: String) = {
#if(Application.isAuthenticated()) {
<li class="active">
#label
</li>
} else {
<li class="disabled">
#label
</li>
}
}