I am new to php and Wordpress and what I am trying to accomplish is listing all my posts by month+year. The month+year is shown as a link, which when clicked, toggles the days. My css code looks like this and is working properly (toggle function done by jquery).
<div class="monat"> <!-- month div -->
Oktober 2014 <!-- Toggle Button -->
<div class="tage"> <!-- toggle div - shown when toggle button clicked -->
12 <!-- day of month -->
20 <!-- day of month -->
22 <!-- day of month -->
23 <!-- day of month -->
</div> <!-- end toggle div -->
</div> <!-- end month div -->
That´s what I have accomplished so far in php. The problem is, that i need 2 closing divs at the end (for class monat and class tage) and I am not sure how to implement them in the php code...
<?php
$prev_month = '';
$prev_year = '';
while(have_posts())
{
the_post();
if(get_the_time('F') != $prev_month || get_the_time('Y') != $prev_year)
{
echo '<div class="monat">'.get_the_time('F Y').'<div class="tage">';
}
?>
<?php the_time('j'); ?>
<?php
$prev_month = get_the_time('F');
$prev_year = get_the_time('Y');
}
?>
Thanks for your help,
Andreas
Thank you so much, hakre!
Works like a charm!
Here is the edited code:
<?php
$prev_month = '';
$prev_year = '';
$divs_opened = false;
query_posts( 'category_name=wurst' );
while(have_posts()) { ## Loop Start
the_post();
$month_changed = (get_the_time('F') != $prev_month) || (get_the_time('Y') != $prev_year);
if ($month_changed) {
if ($divs_opened) {
echo "</div></div>";
}
$divs_opened = true;
{
echo '<div class="monat">'.get_the_time('F Y').'<div class="tage">';
}
}
?>
<?php the_time('j'); ?>
<?php
$prev_month = get_the_time('F');
$prev_year = get_the_time('Y');
} ## Loop End
if ($divs_opened) {
echo "</div></div>";
}
?>
You've already found out how to detect the month change event:
$month_changed = (get_the_time('F') != $prev_month)
|| (get_the_time('Y') != $prev_year);
if ($month_changed) {
...
}
and you output (here I've placed ...) the opening of the divs already. But you're still missing when to place the close of those.
First of all you only need to place closing div tags when you have opened any. You can do this very similar like you do with the months check, just with another variable:
$prev_month = '';
$prev_year = '';
$divs_opened = false; ## third variable
while (have_posts()) {
...
So now when you for the first time open the divs, set that $divs_opened variable to true:
$month_changed = (get_the_time('F') != $prev_month)
|| (get_the_time('Y') != $prev_year);
if ($month_changed) {
$divs_opened = true;
...
}
And as you need to close the divs if they were already opened, you need to check for that, too:
$month_changed = (get_the_time('F') != $prev_month)
|| (get_the_time('Y') != $prev_year);
if ($month_changed) {
if ($divs_opened) {
echo "</div></div>";
}
$divs_opened = true;
...
}
so now this is nearly done, but there is one more place you need to close the divs (if opened), too: that is after the loop:
$prev_month = '';
$prev_year = '';
$divs_opened = false; ## third variable
while (have_posts()) {
...
}
if ($divs_opened) {
echo "</div></div>";
}
That should do it. And I hope it gives you the pointers that you can use a similar method how you detected the month change for the closing divs, too.
Related
I have this code, which allows me to make a "show more" button on Advanced Fields Pro repeater Elements in WordPress.
The problem is when I click fast twice(or more) on the buttons it shows me the fields, which are hidden also twice the (or more) time.
Does anyone have an idea on how to solve it?
Code on WordPress Front end:
<div id="photo-gallery">
<div class="row mt-5 mb-3">
<?php
if( have_rows('logos_der_externen_plattformen') ):
$total = count(get_field('logos_der_externen_plattformen'));
$count = 0;
$number = 5;
while ( have_rows('logos_der_externen_plattformen') ) : the_row(); ?>
<div class="col-6 col-md-4 col-lg-2 p-md-5 pr-2 pl-2 pb-5 pt-2 text-center" data-aos="fade-up">
<img data-src="<?php the_sub_field('logo'); ?>" alt="<?php the_sub_field('alternative_beschreibung_des_logos'); ?>" class="lazy img-fluid">
</div>
<?php
if ($count == $number) {
// we've shown the number, break out of loop
break;
} ?>
<?php $count++; endwhile;
else : endif;
?>
</div>
<div align="center" class="text-decoration-none">
<a id="gallery-load-more" style="text-decoration:none;" href="javascript: my_repeater_show_more();" <?php if ($total < $count) { ?> class="d-none" <?php } ?>><h7 id="title-bg"><span>und viele mehr...</span></h7></a></div>
</div>
var my_repeater_field_post_id = <?php echo $post->ID; ?>;
var my_repeater_field_offset = <?php echo $number + 1; ?>;
var my_repeater_field_nonce = '<?php echo wp_create_nonce('my_repeater_field_nonce'); ?>';
var my_repeater_ajax_url = '<?php echo admin_url('admin-ajax.php'); ?>';
var my_repeater_more = true;
function my_repeater_show_more() {
// make ajax request
jQuery.post(
my_repeater_ajax_url, {
// this is the AJAX action we set up in PHP
'action': 'my_repeater_show_more',
'post_id': my_repeater_field_post_id,
'offset': my_repeater_field_offset,
'nonce': my_repeater_field_nonce
},
function (json) {
// add content to container
// this ID must match the containter
// you want to append content to
jQuery('#photo-gallery .row').append(json['content']);
// update offset
my_repeater_field_offset = json['offset'];
// see if there is more, if not then hide the more link
if (!json['more']) {
// this ID must match the id of the show more link
jQuery('#gallery-load-more').css('display', 'none');
}
},
'json'
);
}
Backend:
/**
* ACF Load More Repeater
*/
// add action for logged in users
add_action('wp_ajax_my_repeater_show_more', 'my_repeater_show_more');
// add action for non logged in users
add_action('wp_ajax_nopriv_my_repeater_show_more', 'my_repeater_show_more');
function my_repeater_show_more() {
// validate the nonce
if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'my_repeater_field_nonce')) {
exit;
}
// make sure we have the other values
if (!isset($_POST['post_id']) || !isset($_POST['offset'])) {
return;
}
$show = 10; // how many more to show
$start = $_POST['offset'];
$end = $start+$show;
$post_id = $_POST['post_id'];
// use an object buffer to capture the html output
// alternately you could create a varaible like $html
// and add the content to this string, but I find
// object buffers make the code easier to work with
ob_start();
if (have_rows('logos_der_externen_plattformen', $post_id)) {
$total = count(get_field('logos_der_externen_plattformen', $post_id));
$count = 0;
while (have_rows('logos_der_externen_plattformen', $post_id)) {
the_row();
if ($count < $start) {
// we have not gotten to where
// we need to start showing
// increment count and continue
$count++;
continue;
}
?>
<div class="col-6 col-md-4 col-lg-2 p-md-5 pr-2 pl-2 pb-5 pt-2 text-center" data-aos="fade-up">
<img src="<?php the_sub_field('logo'); ?>" alt="<?php the_sub_field('alternative_beschreibung_des_logos'); ?>" class="img-fluid">
</div>
<?php
$count++;
if ($count == $end) {
// we have shown the number, break out of loop
break;
}
} // end while have rows
} // end if have rows
$content = ob_get_clean();
// check to see if we have shown the last item
$more = false;
if ($total > $count) {
$more = true;
}
// output our 3 values as a json encoded array
echo json_encode(array('content' => $content, 'more' => $more, 'offset' => $end));
exit;
} // end function my_repeater_show_more
This solution fork just fine for me:
document.getElementById("title-bg").onclick = function() {
document.getElementById("title-bg").style.display = "none";
}
There are 2 ways you could solve this:
Create a wrapper function around your JAVASCRIPT implementation of my_repeater_show_more. When this function starts, set a variable that the request is in progress. Unset the variable when the request has completed and the fields have been loaded. Disable the button when the field is set. This way, while the fields are loading, the button cannot be clicked.
Wrap your JAVASCRIPT call to my_repeater_show_more in a debounce. This will prevent the function from firing until some minimum amount of time has passed between clicks. Doing so will prevent the function from firing twice if you double click quickly.
More information about writing a debounce in vanilla JS can be found on this excellent blog post.
I am working on a calendar script to output events that are grouped by month. Everything is working fine, except I can't figure out how to add a div wrapper around each month without some closing tag issues. Here is my loop code:
if ($posts) {
$month_titles = array();
$close = false;
foreach( $posts as $post ) {
setup_postdata( $post );
$month_title = date('F Y', strtotime(get_post_meta($post->ID,'_event_start_local', true)));
if(!in_array($month_title, $month_titles)) {
if($close) echo '</ul>';
echo '<h4>'.$month_title.'</h4>';
echo '<ul>';
$month_titles[] = $month_title;
$close = true;
}
echo '<li>'.get_the_title().'</li>';
}
if ($close) echo '</ul>';
}
Here is how this is current output:
<h4>Month Name 2018</ul>
<ul>
<li>Title of Event</li>
<li>Title of Event</li>
</ul>
I would like for it to be like this:
<div>
<h4>Month Name 2018</h4>
<ul>
<li>Title of Event</li>
<li>Title of Event</li>
</ul>
</div>
I have tried a few different ways to add the div wrap and it either closes too early or too late. I need a fresh set of eyes on this as I have been messing with it too long!
This logic should work for what you want:
// preset some vars
$oldMonth = null;
$firstItem = true;
foreach($posts as $post) {
setup_postdata($post);
$month_title = date('F Y', strtotime(get_post_meta($post->ID,'_event_start_local', true)));
// check if we have a new month coming up:
if($oldMonth != $month_title) {
// when it's the first one ever, just open the div
if($firstItem) {
echo "<div>";
$firstItem = false; //..and remember that the following aren't the first
} else { // else close the previous ones and open a new one
echo "</ul></div><div>";
}
// show the new month and open the list
echo '<h4>'.$month_title.'</h4>';
echo '<ul>';
}
echo '<li>'.get_the_title().'</li>';
$oldMonth = $month_title; // remember the last month
}
// at the end close the last ul and last div
echo '</ul></div>';
It seems just changing these lines:
if($close) echo '</ul>';
echo '<h4>'.$month_title.'</h4>';
to
if($close) echo '</ul></div>';
echo '<div><h4>'.$month_title.'</h4>';
should do what you want. Note you have to change the if on $close in both places in your code)
I have the following loop which brings in the title of each post onto my page
html
<?php
if (have_posts()) {
while (have_posts()) {
the_post();
echo '<div class="cell">'.get_the_title().'</div>';
} // end while
} // end if
?>
css
.cell {
display: inline-block;
margin: 0 10px;
}
I want to put a separator between each title/link brought in (not on the ends)
example output
link <div class="separate"></div>
link <div class="separate"></div> link
simple solution using additional flag variable $first
<?php
if ( have_posts() ) {
$first = true;
while ( have_posts() ) {
the_post();
if($first){
$first = false;
} else {
// echo separator
}
echo '<div class="cell">'.get_the_title().'</div>';
} // end while
} // end if
?>
You could put in a <hr> element at the end of your echo like this:
echo '<div class="cell">'.get_the_title().'</div><hr>';
You have to put a counter and compare the counter with posts per page to check if you have reached last post.
You can get posts per page from options table like this:
$default_posts_per_page = get_option( 'posts_per_page' );
Check if you have reached the last post, then don't print out the separator.
$counter = 1;
while ( have_posts() ) {
//your stuffs
if ($counter != $default_posts_per_page) {
//print separator
}
$counter++;
}
I have a condition that says :
if the posts are superiors of today -> show
else -> //do nothing, I leave empty and then my posts disappear if there are inferiors of today.
But the problem is that I have 10 posts per page but because of this empty else I have only 7 who appear for example.
So how can I say in the empty else to display the following posts which are still valid ?
Here's my code :
<?php if (get_field('fin_de_levenement')){ ?>
<?php $now = time();
$date_one_timestamp = strtotime(get_field('fin_de_levenement', false, false));
if ($now < $date_one_timestamp ) { ?>
<div>my content</div>
<?php } else {
// do nothing
} ?>
Thank you !
Just remove your else statement.
<?php if (get_field('fin_de_levenement')){ ?>
<?php $now = time();
$date_one_timestamp = strtotime(get_field('fin_de_levenement', false, false));
if ($now < $date_one_timestamp ) { ?>
<div>my content</div>
<?php }
This is puzzling me for the past hours already. Hopefully anybody has the clearing answer and in any case, thank for any support. In need to filter between three values in a data-attribute, which are set in jQuery. These values are changed and put in the attribute, depending on screenwidth. The jQuery part works fine. Now the tricky part is that in the PHP file the right value of the data-width attribute should be used and put as a value for a custom field. This value triggers the right images in a backgroundslider.
I tried the if/else statement in which the attribute value had a variable, which could give the right value for the custumfield, when its value would be equal as the one mad in jQuery. This failed. My knowledge is limited and therefore my files looked like this.
jQuery:
function schermFilter() {
var scherm = $(window).width();
if (scherm >= 320 && scherm <= 480) {
$('#homeslider-wrapper').attr('data-width','slides_mobiel')
console.log(scherm + ": mobiel");
} else if (scherm >= 768 && scherm <= 992) {
$('#homeslider-wrapper').attr('data-width','slides_tablet')
console.log(scherm + ": tablet");
} else {
$('#homeslider-wrapper').attr('data-width','slides_groot')
console.log(scherm + ": groot");
}
};
schermFilter();
$(document).ready(function() {
schermFilter();
});
PHP:
<?php $screenwidth =""; ?>
<?php $args = array(
'post_type' => 'homeslides',
'order' => 'date'
);
$slider = new WP_QUERY($args);
if($slider->have_posts()) : ?>
<div id="homeslider-wrapper" class="slides" data-width="$screenwidth">
<?php while ($slider->have_posts()) : $slider->the_post(); ?>
<?php if ($screenwidth === "slides_mobiel") {
$image = get_field('slides_mobiel');
echo $screenwidth;
} elseif ($screenwidth === "slides_tablet") {
$image = get_field('slides_tablet');
echo $screenwidth;
} else if ($screenwidth === "") {
$image = get_field('slides_groot');
echo $screenwidth;
} else {
$image = get_field('slides_groot');
echo "groot - else";
}
?>
<?php $imageList .= '"'. $image['url'] . '",'; ?>
<?php endwhile; ?>
</div>
<?php endif;wp_reset_postdata(); ?>
<?php $imageList = rtrim($imageList, ','); ?>
I tried isset and property-exists, but without success. Thanks!