Masonry, WordPress Loop, and Bootstrap - php

I am building a wordpress site using bootstrap, and I want to create a featured work section on my homepage using masonry to display the thumbnails and titles of my 3 most recent portfolio items.
I would like the portfolio items to be placed in a seemingly random fashion (similar to this: http://studiosweep.com/) rather than just an orderly grid format. I can't figure out how to assign different widths to my portfolio items because they're just being generated in the featured work section via wordpress loop.
Here's my HTML:
<section id="work">
<div class="container-fluid">
<div class="row">
<div class="col-sm-offset-6 col-sm-6 text-center">
<h1>Featured Work</h1>
</div>
</div>
<div class="row" id="ms-container">
<?php query_posts('posts_per_page=3&post_type=work'); ?>
<?php while ( have_posts() ) : the_post();
$thumbnail = get_field('thumbnail');
$medium = get_field('medium');
$size = "large";
?>
<div class="ms-item col-lg-6 col-md-6 col-sm-6 col-xs-12">
<figure>
<?php echo wp_get_attachment_image($thumbnail, $size); ?>
</figure>
<h3><?php the_title(); ?></h3>
<div class="clearfix"></div>
</div>
<?php endwhile; // end of the loop. ?>
<?php wp_reset_query();
</div>
<div class="clearfix"></div>
</div>
</section>
Here's the script:
<script type="text/javascript">
jQuery(window).load(function() {
// MASSONRY Without jquery
var container = document.querySelector('#ms-container');
var msnry = new Masonry( container, {
itemSelector: '.ms-item',
columnWidth: '.ms-item',
});
});
</script>
As for CSS, I don't really know how to go about assigning the different column widths, so I only have this so far:
.ms-item {
width: 38.23%;
margin-right: 80px;
margin-bottom: 70px;
}
Any help would be appreciated!

Let's say you have 3 different classes for column widths:
.ms-item-width-1, .ms-item-width-2, .ms-item-width-3
A possible solution is to add those 3 classes to your css file and randomly assign one of your classes to your container after .ms-item class. Masonry will give the width of the last class you added to that container. For example:
<div class="ms-item <?php echo 'ms-item-width-' . (rand(0, 3) + 1); ?> col-lg-6 col-md-6 col-sm-6 col-xs-12">
<figure>
<?php echo wp_get_attachment_image($thumbnail, $size); ?>
</figure>
Update: To have a randomized without getting repeated values you could have an array $widths = array(1,2,3); and then shuffle this array shuffle($widths); and instead of calling the random function you would be removing the elements of the array and replace it with the following code:
<div class="ms-item <?php echo 'ms-item-width-' . array_shift($widths); ?> col-lg-6 col-md-6 col-sm-6 col-xs-12">
This will provide an unique width to this 3 items.

Related

How to make a 5 column section using a while loop with my latest posts in my frontpage.php file for Wordpress

I would like to add the right code to have my latest post (from the while loop) in a 5 column section. What is the the best way to do this?
<div class="container">
<div class="container container--narrow page-section">
<h2 class="headline headline--small-plus t-center">Laatste nieuws</h2>
<?php
$homepagePosts = new WP_Query(array(
'posts_per_page' => 5,
'category_name' => 'Posts'
));
while ($homepagePosts->have_posts()) {
$homepagePosts->the_post(); ?>
<div class="event-summary">
<a class="event-summary__date event-summary__date--beige t-center" href="#">
<span class="event-summary__month"><?php the_time('M'); ?></span>
<span class="event-summary__day"><?php the_time('d'); ?></span>
</a>
<div class="event-summary__content">
<h5 class="event-summary__title headline headline--tiny"><?php the_title(); ?></h5>
<p><?php echo wp_trim_words(get_the_content(), 18); ?>Lees meer</p>
</div>
</div>
<?php } wp_reset_postdata();
?>
I was trying to make a 5 column section, but got stuck on how I could loop it with my most recent posts.
You would use CSS grid to create that layout. Each .event-summary should take one column of the grid container. If you want to specify how many columns they should take, use grid-column: span ...; with the number of columns you want it to take up. See below example.
.page-section {
display: grid;
grid-template-columns: repeat(5, 1fr);
}
.page-section .headline {
grid-column: 1 / -1;
}
.page-section .event-summary {
grid-column: span 1; /* replace with column number you prefer */
}

two nested foreach

I have 2 tables in database first one is $slide_images and second is $why_us and I am using owl carousel for images.
The $slide_images contains 10 rows.
The $why_us contains 3 rows.
I need each image take one row of $why_us that's mean the first 3 images will have a text from $why_us table.
I tried many ways to do that but it's not given me what I want and I can't edit tables to do that and the id column is not nested to join them with SQL.
Can i solve them with nested foreach?
<div class="home_area">
<!-- start Carousel -->
<div class="owl-carousel block_1">
<?php
if(is_array($slide_image)){
foreach($slide_image as $src){
?>
<div class="overlay-text">
<div class="carousel_item" style="background-image:url('<?php echo base_url(); echo $src->url; ?>');"></div>
<div class="text-layer">
<!--============ start we us ================ -->
<?php if($why_us != ''){ ?>
<div class="we">
<div class="container">
<div class="row">
<?php foreach($why_us as $we){ ?>
<div class="box">
<h6><?php echo $we->name; ?></h6>
<div class="text"><?php echo $we->desc; ?></div>
</div>
<?php }?>
</div>
</div>
</div>
<?php } ?>
<!--============= end we us ========== -->
</div>
</div>
<?php } }?>
</div>
<!-- end Carousel -->
</div>
I hope I described my question well.
You should not use nested loops. That creates a cross product between the arrays.
Instead, you should just have one loop that uses the corresponding elements of both arrays. Since one of the arrays is smaller, you should check that the index exists.
foreach ($slide_image as $index => $src) {
// code that uses `$src` here
if (isset($why_us[$index])) {
$we = $why_us[$index];
// code that uses $we here
}
}

Items per slide responsive

I've made a logo slider using Bootstrap (basically as seen here http://jsfiddle.net/juddlyon/Q2TYv/10/).
Within each slide there are 4 logos. I want to make this responsive, where on smaller screens it only shows 2 logos per slide. I'm not sure what the best way is to do this.
I can double the grid-4 width to 50% with media queries but then it will still show 4 per slide, in a 2x2 grid.
Another way is to duplicate the entire slide and hide and show the correct one, but this seems like a rather inefficient appreach.
So really I need to reduce the number of logos per slide as it is loaded.. but how?
I'm using WP and Advanced Custom Fields to populate the slider. Simplified code below:
PHP:
<?php
$firstslide = 0;
$slide = 0;
$repeater = get_field('clients', $clients);
$order = array();
foreach( $repeater as $i => $row ) {
$order[ $i ] = $row['name'];
}
array_multisort($order, SORT_ASC, $repeater);
if($repeater):
foreach($repeater as $i => $row):
if ($firstslide == 0) {
$class = "item active";
} else {
$class = "item";
};
if ($slide == 0) {
echo '<div class="' . $class . '">';
};
?>
<div class="grid-4">
<img src="<?php echo $row['logo']; ?>">
</div>
<?php
if ($slide == 4) {
echo '</div>';
$slide = 0;
} else {
$slide++;
}
$firstslide++;
endforeach;
wp_reset_postdata();
endif;
?>
This would results in something like:
<div class="item active">
<div class="grid-4"><img src="logo1.jpg"></div>
<div class="grid-4"><img src="logo2.jpg"></div>
<div class="grid-4"><img src="logo3.jpg"></div>
<div class="grid-4"><img src="logo4.jpg"></div>
</div>
<div class="item">
<div class="grid-4"><img src="logo5.jpg"></div>
<div class="grid-4"><img src="logo6.jpg"></div>
<div class="grid-4"><img src="logo7.jpg"></div>
<div class="grid-4"><img src="logo8.jpg"></div>
</div>
<div class="item">
<div class="grid-4"><img src="logo9.jpg"></div>
<div class="grid-4"><img src="logo10.jpg"></div>
<div class="grid-4"><img src="logo11.jpg"></div>
<div class="grid-4"><img src="logo12.jpg"></div>
</div>
Very simplified CSS for the grid:
.grid-4 {
width: 25%;
}
After more searching, it looks like Slick is a solution that will just take care this.
jsfiddle.net/BishopBarber/ufnjkjy4/1/

Tile Thumbnails in a Grid

I want to tile thumbnails into 3 columns using bootstrap's grid classes like this (this entry only has 3 images):
The 4th image would go to the next row <div class="row"></div> within a <div class="col-sm-4"></div>, 5th and 6th images in the same row but separate <div class="col-sm-4"></div>. Then the 7th image goes to the 3rd row etc...
The details of the images including urls are taken from DB using php.
<div class="panel-body">
<?php foreach($screenshots as $key=>$screenshot): ?>
<div class="col-sm-4">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><?=$screenshot["ss_name"]?></h3>
</div>
<div class="panel-body">
<img class="img-rounded" style="display: block; text-align:center;" src="<?=UPLOADS_FOLDER.$screenshot['ss_url']?>" alt="<?=$screenshot['ss_name']?>">
<p><?=$screenshot["ss_description"]?></p>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
I've managed to figure out the algorithim:
<?php
$total_entries = count($screenshots);
$total_cols = 3;
$total_rows = ceil($total_entries / $total_cols);
for($col = 0; $col < $total_cols; ++$col):
?>
<div class="row" style="margin: 1% 0.5%;">
<?php for($row = 0; $row < $total_rows; ++$row): ?>
<div class="col-sm-4">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Panel Title</h3>
</div>
<div class="panel-body">
row: <?=$row?> | col: <?=$col?>
</div>
</div>
</div>
<?php endfor; ?>
</div>
<?php endfor; ?>
But I'm stuck trying to figure out how to find of the index of the screenshot to show.
You have row and column mixed up in the output above.
Once that is fixed, if you need an integer index you should be able to calculate it from the row and column values. For a zero based array of images, something like (row*3)+column
That said, in Bootstrap, you should not need to create the individual rows in the way you have. If you put all the col-sm-3 divs one after the other, without breaking out new rows, this will sort itself out anyway.
Doing it this way, you can use col-Xxx to specify different numbers of columns for different screen widths without changing your code.
The trick is to send every new data in a single column define by <div class="column-sm-4"> and in order to have three items in a row, calling <div class="row"> after every three items. Which can be done by using a counter initialized at 0 and then incrementing its value by 1 every time and inserting new row when dividing it by 3 results an integer:
$count = 0;
if (is_int($count/3)){
echo '<div class="row">';
}
We need to insert a div before first element so we check if its the starting:
if ($count==0 OR is_int($count/3)){
echo '<div class="row">';
}
Then in order to close the div we need to check again if the division results an integer:
if(is_int($count/3)){
echo '</div>' ;
}
We also need to close the div after the last element so we check whether the element is last one or not by:
if($count==$total_entries OR is_int($count/3)){
echo '</div>' ;
}
The full code is:
<?php
$count = 0;
$total_entries = count($screenshots);
foreach($screenshots as $key=>$screenshot):
if ($count==0 OR is_int($count/3)){
echo '<div class="row">';
}
?>
<div class="column-sm-4">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><?=$screenshot["ss_name"]?></h3>
</div>
<div class="panel-body">
<img class="img-rounded" style="display: block; text-
align:center;" src="<?=UPLOADS_FOLDER.$screenshot['ss_url']?>"
alt="<?=$screenshot['ss_name']?>">
<p><?=$screenshot["ss_description"]?></p>
</div>
</div>
</div>
<?php
$count++;
if($count==$total_entries OR is_int($count/3)){
echo '</div>' ;
}
endforeach;
?>

Child page content

I have a parent page that acts as menu for my portfolio.
It pulls in thumbnail images from the child pages which i have been able to accomplish with magic fields and some code. It dumps the images into a grid layout. The thumbnails are pulled into one container div like so:
div id="folio-content">
<div class="thumb-container">
<div class="thumb"><img src="/images/pic.jpg"/>
</div>JCPenny</div>
... </div>`
when the div gets filled up with 2 thumbnails I want to create a new container div and fill it with 2 images again and so on after 2 images.
So, if you had 4 images it would look like this.
<div id="folio-content"><!--/Main Container/-->
<div class="thumb-container">
<div class="thumb"><img src="/images/pic1.jpg"/>
</div>JCPenny</div>
<div class="thumb-container">
<div class="thumb"><img src="/images/pic1.jpg"/>
</div>Champ Car</div></div>
<div id="folio-content"><!--/Main Container/-->
<div class="thumb-container">
<div class="thumb"><img src="/images/pic1.jpg"/>
</div>JCPenny</div>
<div class="thumb-container">
<div class="thumb"><img src="/images/pic1.jpg"/>
</div>Champ Car</div></div>
this is the code I am using in my page.php file.
<?php get_header(); ?>
<div id="folio-content">
<?php
$projectpage = get_pages('child_of='.$post->ID.'&sort_column=post_date&sort_order=desc');
$count = 0;
foreach($projectpage as $page)
{
$content = $page->post_content;
if(!$content)
continue;
if ($count == 10) --- this is geting 10 images now, but I want to get them all.
break;
$count++;
$content = apply_filters('the_content', $content);
?>
<div class="thumb-container">
<div class="thumb"><a href="<?php echo get_permalink($page->ID); ?>"<?php echo get_image ("thumbnail",1,1,1,$page->ID);?></a>
</div><?php echo $page->post_title ?>
</div>
<?php
}
?>
</div><!--/close set!-->
</div>
also, how can I get ALL child pages? I have it set to 10 now with this if ($count == 10)
any help? thanks a ton again!!!!
I'm not familiar with "get_pages" but since Wordpress treats posts and pages in an identical manner you could use this.
$projectpage = get_posts('numberposts=-1&post_type=page&child_of='.$post->ID.'&sort_column=post_date&sort_order=desc');
The -1 removes the limit and gets ALL the specified pages.
I have cobbled together some code, that sort of sounds right but does not work at all! Which I am not surprised. But it is a starting point - please take a look at this code, maybe it is step in the right direction?
<?php
$projectpage = get_posts('numberposts=-1&post_type=page&child_of='.$post->ID.'&sort_column=post_date&sort_order=desc');
if (have_posts()) :
$i=0; // counter
while(get_posts()) : the_post();
if($i%2==0) { // if counter is multiple of 3, put an opening div ?>
<!-- <?php echo ($i+1).'-'; echo ($i+2); ?> -->
<div>
<?php } ?>
<div class="single_item">
<h2><?php the_title(); ?></h2>
</div>
<?php $i++;
if($i%2==0) { // if counter is multiple of 3, put an closing div ?>
</div>
<?php } ?>
<?php endwhile; ?>
<?php
if($i%2!=0) { // put closing div here if loop is not exactly a multiple of 3 ?>
</div>
<?php } ?>
<?php endif; ?>

Categories