Get children inside a controller to display on twig template - symfony

I've I'm trying to build a page which collects together all of the pages on a site and displays them along with their children (if they have any).
So far I've managed to make it loop through all of the top level pages and display them, however I'm getting some difficulty in making it display the child pages in the right place. It seems that I can either retrieve them but have them appear at the end or not retreive them at all.
I would need it to look like this:
<div id="parent" class="guide-item">
<h2>Parent</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p><p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>
<div id="child" class="guide-item">
<h2>Child</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p><p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>
</div>
</div>
Here is my controller (including my attempt at getting it to loop through the children:
// Render pages from database
public function sectorAction($sector)
{
$em = $this->getDoctrine()->getManager();
$pages = $this->getDoctrine()
->getRepository('acmeStyleGuideBundle:pageSector')
->findBySectorJoinedToUrlTopLevel($sector);
if (!$pages) throw $this->createNotFoundException('Unable to find any matching sectors');
foreach ($pages as $page) {
if ($page->getChildPages()) {
$children = $this->getDoctrine()
->getRepository('acmeStyleGuideBundle:pageContent')
->findBySectorAndParent($sector, $page->getPageUrl());
}
}
return $this->render(
'acmeStyleGuideBundle:Page:pages.html.twig',
array(
'Pages' => $pages,
'Children' => $children,
'header' => $sector
)
);
}
Here are the relavent repositories:
public function findBySectorJoinedToUrlTopLevel($sector)
{
$query = $this->getEntityManager()
->createQuery('
SELECT p, s FROM acmeStyleGuideBundle:PageContent p
JOIN p.pageSector s
LEFT JOIN p.pageTypes t
WHERE s.sectorName = :sector
AND t.typeName != :type
AND p.parentPage IS NULL'
)
->setParameter('type', 'Section Headers')
->setParameter('sector', $sector);
try {
return $query->getResult();
} catch (\Doctrine\ORM\NoResultException $e) {
return null;
}
}
public function findBySectorAndParent($sector, $pageParent)
{
$query = $this->getEntityManager()
->createQuery('
SELECT p, s, c FROM acmeStyleGuideBundle:PageContent p
JOIN p.pageSector s
LEFT JOIN p.pageTypes t
LEFT JOIN p.parentPage c
WHERE s.sectorName = :sector
AND p.pageUrl = :parent
AND t.typeName != :type'
)
->setParameter('sector', $sector)
->setParameter('parent', $pageParent)
->setParameter('type', 'Section Headers');
try {
return $query->getResult();
} catch (\Doctrine\ORM\NoResultException $e) {
return null;
}
}
And here is my twig template where I want to output the code:
{% extends 'acmeStyleGuideBundle::landing.html.twig' %}
{% block definition %}
<article class="js-load pageLoad">
<h1>
{% if header is defined %}
{{ header | title }}
{% else %}
{{ Pages[0].pageName }}
{% endif %}
</h1>
{% for pe in Pages %}
<div id="{{ pe.pageUrl | lower}}" class="guide-item">
<h2>{{ pe.pageName }}</h2>
{{ pe.richText | raw }}
</div>
{% endfor %}
</article>
{% endblock %}
I thought that I might hae been able to loop through the children in the controller and then apply it to the twig template as 'children' instead of 'pages' but that didn't seem to work as the following code just constantly repeated the last element in the database which WASN'T a child page.:
{% for ce in Children %}
<div class="childPage">
<div id="{{ ce.pageUrl | lower}}" class="guide-item">
<h2>{{ ce.pageName }}</h2>
{{ ce.richText | raw }}
<div class="explanation">
<div class="card active">
<h3>Example</h3>
{# ce.example | raw#}
</div>
<div class="card">
<h3>Code Example</h3>
<pre name="code" class="{#ce.lang#}">{# ce.example #}</pre>
</div>
</div>
</div>
</div>
{% endfor %}
I've been looking at this problem for a while now so I probably can no longer see the wood for the trees so feel free to pull my code to pieces. I'm a learner at symfony/twig/doctrine anyway so I'll gladly take any feedback you care to give me.

I managed to find a solution.
Instead of trying to do everything in one controller and template, I created a new template called childpages.html.twig and put in this code:
{% for pe in Pages %}
<div id="{{ pe.pageUrl | lower}}" class="guide-item child">
<h2>{{ pe.pageName }}</h2>
{{ pe.richText | raw }}
{{ render(controller('acmeStyleGuideBundle:Page:findCodeExamples', { 'pageParent': pe.codeExample })) }}
</div>
{% endfor %}
I then wrote a new controller:
// Render children from database (Similar to showSubAction but without the $pageUrl requirement)
public function findChildrenAction($pageParent, $sector)
{
$em = $this->getDoctrine()->getManager();
$pages = $this->getDoctrine()
->getRepository('acmeStyleGuideBundle:PageSector')
->findBySectorJoinedToParent($sector, $pageParent);
return $this->render(
'acmeStyleGuideBundle:Page:childPages.html.twig',
array(
'Pages' => $pages,
'sector' => $sector
)
);
}
and referenced it in the place I needed it to appear in my original template:
{{
render(controller('acmeStyleGuideBundle:Page:findChildren', {
'pageParent': pe.id,
'sector': 'residential'
}))
}}
Not sure if it's the most elegant solution but it worked.

Related

Responsive slider timeline (NextJs project) with Swiper

I am new to NextJs/ReactJs and I was trying to implement the Responsive slide with Swiperjs which is available in codepen.io
Here is the link to codepen.
Responsive slider timeline with Swiper
Below are my steps I carried out;
Installed JQuery (npm install)
Imported both swiper.min.css and swiper.min.js CDNs to my _Document.js file
Added the css files to Globals.css for time being
Created a TimelineComponent.js to have the swiper component separately.
imported TimelineComponent.js in the index.js
When I run the project it nicely shows you the expected output as below.
But when I resize my browser it behaves abnormally like below
import React, { useEffect } from 'react';
import $ from 'jquery';
function TimeLineComponent() {
function operateTimeline() {
var timelineSwiper = new Swiper('.timeline .swiper-container', {
direction: 'vertical',
loop: false,
speed: 1600,
pagination: '.swiper-pagination',
paginationBulletRender: function (swiper, index, className) {
var year = document
.querySelectorAll('.swiper-slide')
[index].getAttribute('data-year');
return '<span class="' + className + '">' + year + '</span>';
},
paginationClickable: true,
nextButton: '.swiper-button-next',
prevButton: '.swiper-button-prev',
breakpoints: {
768: {
direction: 'horizontal',
},
},
});
}
useEffect(() => {
$(window).on('load resize', operateTimeline);
operateTimeline();
return () => {
$(window).off('load resize');
};
}, []);
return (
<div className="timeline-container">
<div className="timeline">
<div className="swiper-container">
<div className="swiper-wrapper">
<div
className="swiper-slide"
style={{
backgroundImage: "url('https://unsplash.it/1920/500?image=11')",
}}
data-year="2011"
>
<div className="swiper-slide-content">
<span className="timeline-year">2011</span>
<h4 className="timeline-title">Our nice super title</h4>
<p className="timeline-text">
Lorem ipsum dolor site amet, consectetur adipscing elit, sed
do eisumod tempor incididut ut labore et dolore magna aliqua.
Ut enim ad mimim venjam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat.
</p>
</div>
</div>
<div
className="swiper-slide"
style={{
backgroundImage: "url('https://unsplash.it/1920/500?image=12')",
}}
data-year="2012"
>
<div className="swiper-slide-content">
<span className="timeline-year">2012</span>
<h4 className="timeline-title">Our nice super title</h4>
<p className="timeline-text">
Lorem ipsum dolor site amet, consectetur adipscing elit, sed
do eisumod tempor incididut ut labore et dolore magna aliqua.
Ut enim ad mimim venjam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat.
</p>
</div>
</div>
</div>
<div className="swiper-button-prev"></div>
<div className="swiper-button-next"></div>
<div className="swiper-pagination"></div>
</div>
</div>
</div>
);
}
export default TimeLineComponent;
Error can be replicated in the above codepen example as well. Most probably this is with the styling
Your help is much appreciated.

Next JS Error product.map Is Not a Function

Hello everyone i have a question according to my case, i have
index.js code bellow :
export default function Home({ productList }) {
return (
<div className={styles.container}>
<Head>
<title>OlResto UI Design With Next JS</title>
<meta name="description" content="This is stunning website build using next js" />
<link rel="icon" href="/favicon.ico" />
</Head>
<Featured />
<ProductList productList={ productList } />
</div>
);
};
export const getServerSideProps = async () => {
const res = await axios.get("http://localhost:3000/api/products");
return {
props: {
productList: res.data
}
}
};
the second one i have file call ProductList.jsx
code below:
const ProductList = ({ productList }) => {
return (
<div className={styles.container}>
<h1 className={styles.title}>THE BEST PIZZA IN TOWN</h1>
<p className={styles.desc}>Lorem ipsum dolor sit amet consectetur adipisicing elit. Sint, nemo at, labore porro reiciendis rem ad tempora blanditiis adipisci a eum animi obcaecati, dignissimos non perspiciatis natus corrupti consectetur libero.</p>
<div className={styles.wrapper}>
{productList.map(product => (
<ProductCard key={product._id} product={product} />
))}
</div>
</div>
);
};
export default ProductList;
Those files produce an error like this :
TypeError: productList.map is not a function
<div className={styles.wrapper}>
{productList.map(product => (
^
<ProductCard key={product._id} product={product} />
))}
</div>
Sorry if my question messed up, hope you guys can help my problem, thank you in advance

Toggling a class on a Tailwind/Alpine.js accordion

I've created an accordion with TailwindCSS and Alpine.js which works fine except that I also want to change the icon in the button that expands the content when it's clicked.
This is what I have:
<div x-data="{selected:null,open:true}">
<dl class="faqs mx-auto max-w-2xl">
<dt>
<span class="faq-q">Question</span>
<button
type="button"
class="faq-toggle"
#click="selected !== 1 ? selected = 1 : selected = null, open = open"
:class="{ 'faq-open': open, 'faq-close': !(open) }"
>
<span>+</span>
<span class="hidden">-</span>
</button>
</dt>
<dd
class="faq-a overflow-hidden transition-all max-h-0 duration-700"
style="" x-ref="container1" x-bind:style="selected == 1 ? 'max-height: ' + $refs.container1.scrollHeight + 'px' : ''"
>
<div class="inner">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure rerum in tempore sit ducimus doloribus quod commodi eligendi ipsam porro non fugiat nisi eaque delectus harum aspernatur recusandae incidunt quasi.
</div>
</dd>
</dl>
</div>
and a link to a CodePen.
What I want to do is toggle the class of the button from faq-open to faq-close when the button is clicked. Although I may actually need to toggle a class on the parent dt too.
At the moment, the accordion expands when you click on the button, but the class doesn't change.
The problem is on this line
#click="selected !== 1 ? selected = 1 : selected = null, open = open"
You never change value of open, it is always the value at initialization, and that is open: true.
You need to switch it:
#click="selected !== 1 ? selected = 1 : selected = null, open = !open"
By the way, you don't need extra variable selected to control the hidden text, just one open variable is enough. Something like this:
<div x-data="{open: true}">
<dl class="faqs mx-auto max-w-2xl">
<dt>
<span class="faq-q">Question</span>
<button
type="button"
class="faq-toggle"
#click="open = !open"
:class="open ? 'faq-open' : 'faq-close'"
>
<span :class="open ? '' : 'hidden'">+</span>
<span :class="open ? 'hidden' : ''">-</span>
</button>
</dt>
<dd
class="faq-a overflow-hidden transition-all max-h-0 duration-700"
style="" x-ref="container1" x-bind:style="open ? 'max-height: ' + $refs.container1.scrollHeight + 'px' : ''"
>
<div class="inner">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure rerum in tempore sit ducimus doloribus quod commodi eligendi ipsam porro non fugiat nisi eaque delectus harum aspernatur recusandae incidunt quasi.
</div>
</dd>
</dl>
import 'twin.macro';
import React, { useRef, useState } from 'react';
import { BiPlus, BiMinus } from 'react-icons/bi';
const Accordion = ({ title, children }) => {
const [active, setActive] = useState(false);
const [height, setHeight] = useState('0px');
const contentSpace = useRef(null);
function toggleAccordion() {
setActive(!active);
setHeight(active ? '0px' : `${contentSpace.current?.scrollHeight}px`);
}
return (
<div tw="flex flex-col outline-none" role="button" tabIndex={0}>
<div
tw="flex flex-row items-center justify-between py-4 border-b border-t border-black "
onClick={toggleAccordion}>
<h1 tw="cursor-pointer text-base font-bold">{title}</h1>
{active ? <BiMinus /> : <BiPlus />}
</div>
<div
ref={contentSpace}
style={{ maxHeight: `${height}` }}
tw="overflow-auto overflow-y-hidden duration-700 ease-in-out">
<p tw="my-4">{children}</p>
</div>
</div>
);
};
export default Accordion;

Can't get style sheet to work

I am trying to create my first webapp using google apps script. I am trying to follow the examples but it is not working. I created a stylesheet.html tab along with my main html page. But none of my formatting is working. I thought google appended the files together. FYI, my styles work fine if I include them at the bottom of the main page.
This is my code.gs page:
function doGet() {
return HtmlService.createHtmlOutputFromFile('frontpage')
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
This is my main page called frontpage.html :
<!DOCTYPE html>
<html lang="en">
<?!= HtmlService.createHtmlOutputFromFile('stylesheet').getContent(); ?>
<!-- google scripts says to not include header & body tags ?? -->
<meta charset="utf-8">
<title>Borah Physics</title> <!-- google syas not to use title tag need another way to set title.-->
<h1><div style="text-align:center">Physics Homework</div></h1>
<!--List of available assignments. This needs to be updated as assignments are added.
Add assignment name and the ssID of the spreadsheet containing the questions.
when clicked need to return value (ssid) as sheetID.-->
<select id="assignment">
<option sheetID="1ajedscAjuXDsUOcQRzru5-bhUIluGn3fPPsoN-Ww5wU">Kinematics 1</option>
<option sheetID="10mCGpLRwv8ETFbW3RwisI45s_x3-ZItatzq_vU0wacs">Dynamics</option>
</select>
<!--Question should be string variable activeQuestion It will get updated when the question number changes.-->
<div id="question">
<br>
<br>
Question Here
<br>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute
irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.
<br> <br>
</div>
<!-- If question has an image it will go here.-->
<div id="qImage">
Along with image (if needed)
<br>
</div>
<!-- This is the user inputed answer. It needs to be recorded in the response sheet of the spreadsheet and
compared to the correct answer. (in the comparison we need to add a within x% variable so if the answer
is close it is counted as correct. This accounts for thinks like g=10 m/s^2 vs 9.8 m/s^2.-->
<div id="answer">
<label>Answer:</label>
<input type="text" name="answer"/>
<input type="Submit" value="Submit"/>
<br>
<br>
</div>
<!-- bottom navigation list-->
<ul id="nav">
<li><a> </a></li>
<li><input type="button" onclick="previous()" value="Previous"></li> <!-- goes to previous question (calls previous function)-->
<li><a > Correct: 4/12 </a></li> <!-- need to insert variables #correct & total # questions-->
<li><input type="button" onclick="next()" value="Next"></li> <!-- goes to next question (calls next function).-->
<li><a> </a></li>
</ul>
and finally my stylesheet.html page
<style>
#assignment{
width: 20%; margin: 10 ;
position: absolute;
right: 10px;
}
#question {
width: 90%; margin: 0 auto;
}
#qImage{
width: 90%; margin: 0 auto;
}
#answer {
width: 90%; margin: 0 auto;
}
#nav {
text-align: justify;
min-width: 400px;
}
#nav:after {
content: '';
display: inline-block;
width: 100%;
}
#nav li {
display: inline-block;
}
</style>
My output shows the at the top of the page as if it were text. So I am not connecting the style sheet to the frontpage.
I have not even attempted to understand functions or javascript yet. Lots to learn. (This is a physics homework app I hope to get working before school starts!) All help is appreciated. Any tutors out there?
thanks.
Change createHtmlOutputFromFile to createTemplateFromFile in the doGet() function.
Should be:
return HtmlService
.createTemplateFromFile('frontpage')
.evaluate()
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
If a file has a scriptlet in it, it's a template. Your frontpage file has a scriptlet in it. The scriptlet is:
<?!= HtmlService.createHtmlOutputFromFile('stylesheet').getContent(); ?>
You can also call a server function from a scriptlet instead of using HtmlService directly inside the scriptlet.

Weird problem using custom fields

I am trying to pull content from specific categories and have them appear on the homepage along with an image that is pulled from the custom field for that entry. Everything looks like it is working ok.. and the second entry works as it should, however with the first entry, only the image links back to the post, the title and read more link are not recognized by the mouse as links. Looking at the html, it seems like the php is printing everything as it should, so I figured it must be a CSS problem, but I cleared all the relevant styles and the links still are not recognized.
Here is the php I have for the home page
<?php
// Show custom fields from Food Category
query_posts('showposts=2&cat=3'); ?>
<?php while (have_posts()) : the_post(); ?>
<?php
// This is added to show <!--more--> on home page
global $more;
$more = 0;
?>
<a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title(); ?>">
<img src="<?php
$values = get_post_custom_values("food_thumb"); echo $values[0]; ?>" alt="" /></a></div>
<div class="span-3">
<p class="smallTitle">
<a href="<?php the_permalink() ?>" rel="bookmark">
<?php the_title(); ?></a></p></div>
<div class="span-1 theDate">
<?php the_time('m.d.y') ?>
</div>
<div class="span-4">
<?php the_content('<span class="moretext">Read more...</span>'); ?>
</div>
<?php endwhile; ?>
The HTML output looks fine..
<div class="span-4 fixed-height-sidebar">
<div class="smallthumb"><img src="foodthumb.jpg" alt="" /></div>
<div class="span-3">
<p class="smallTitle"><a href="http://.com/?p=24" rel="bookmark">
Food Test 1</a></p></div>
<div class="span-1 theDate">
07.16.09</div>
<div class="span-4 fixed-height-sidebar">
<p>Mmmmmmmm. Food. Aliquam libero libero, luctus ut tristique pulvinar, euismod at diam. In hac habitasse platea dictumst. Lorem ipsum dolor sit amet, <span class="moretext">Read more…</span></p>
</div>
<div class="smallthumb"><img src="http://.com/wp-content/uploads/2009/07/foodthumb2.jpg" alt="" /></div>
<div class="span-3">
<p class="smallTitle"><a href="http://.com/?p=3" rel="bookmark">
Food test page -2</a></p></div>
<div class="span-1 theDate">
07.12.09</div>
<div class="span-4">
<p>“Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In nec odio vitae nunc euismod vulputate. Integer aliquam ullamcorper tortor, nec suscipit magna viverra in. Nunc urna neque, dapibus id congue et, dignissim vitae augue. Aliquam et bibendum lacus. <span class="moretext">Read more…</span></p>
</div>
</div>
Here is a screenshot to help explain my problem...
alt text http://zacharydesigns.com/temp/wpsample.jpg
I took your HTML output, and pasted it into a blank HTML page (adding the HTML/HEAD/BODY tags). Both links rendered and worked correctly. I tested in Firefox and IE. From the looks of it, your HTML output is just fine.
Any chance you could post the output of the entire page?
--Adam
What does fixed-height-sidebar do in the CSS?
That's the only difference between the two entries.

Resources