Removing duplicate titles retrieved from custom fields. Wordpress - php

Following is the code that retrieves and outputs state name from custom select field into a navigation menu. For eg: if there is 5 post under state New York, this code shows only one post of New York in navigation drop down menu as redundant values are removed.. but what i want to do is , when the user clicks new york, it redirects to a new page where all the posts under New York will be displayed.. Same with all the states as well because this is a dynamic menu
$args = array('post_type' => 'article-form', 'showposts' => -1, 'orderby' => 'date', 'order' => 'DSC');
$city = new WP_Query($args);
$states = [];
while ( $city->have_posts() ) :
$city->the_post();
$state = get_field('state');
if ( !in_array($state, $states) ) :
$states[] = $state;
?>
<li>
<a href="<?php the_permalink(); ?>" style="text-decoration: none; color: #9c9c9c;">
<?php echo $state;
?>
</a>
<hr style="margin: 0">
</li>
<?php
endif;
endwhile; ?>
<?php wp_reset_query(); ?>
</ul>

Try pushing unique values into an array
<?php $stateArray = array(); ?>
<?php while ($city->have_posts()):$city->the_post(); ?>
<li>
<a href="<?php the_permalink(); ?>" style="text-decoration: none; color: #9c9c9c; ">
<?php
$state = the_field('state');
if (!in_array($state, $stateArray)):
echo $state;
array_push($stateArray, $state);
endif;
?>
</a>
<hr style="margin:0">
</li>
<?php endwhile; ?>
I hope it helps!
P.S Try to avoid inline css, use and external css file for any kind of stylining. Keep you html files as clean as possible.

#user3127632's idea of pushing values to an Array to check if they've been printed before is a good one, but there are a couple of mistakes in his/her code.
If you need to store an ACF's field value to a variable, you should use get_field() instead of the_field() as the last one doesn't return the value but print it. Also, you need to move the li and a nodes inside the condition, otherwise you won't be echoing the label in your link, but the duplicated link will still be there...
So, it would be something like this:
<?php
$states = [];
while ( $city->have_posts() ) :
$city->the_post();
$state = get_field('state');
if ( !in_array($state, $states) ) :
$states[] = $state; // A more efficient way to push values to an array
?>
<li>
<a href="<?php the_permalink(); ?>" style="text-decoration: none; color: #9c9c9c;">
<?php echo $state; ?>
</a>
<hr style="margin: 0">
</li>
<?php
endif;
endwhile;
?>
I hope this helps!

Related

ACF - change link based on backend select choice in a repeater field

am using Advanced Custom Fields for many things on my site. One thing in particular is for a staff profile page. I have a select field where the staff can add social icons or an email icon. The repeater field is 'social' and if they choose to 'add a row' there is 'social channel' select field and a 'social_link' test field. My current code is this:
<?php if ( have_rows('social')): ?>
<div class="staff-social">
<?php while ( have_rows('social')) : the_row() ?>
<li><img src="<?= get_template_directory_uri(); ?>/img/footer-<?php the_sub_field('social_channel') ?>.svg" alt="social icon" /></li>
<?php endwhile; ?>
</div><!--end staff-social-->
<?php endif; ?>
I need to prepend a 'mailto:' to my anchor tag if the user selects 'mail' from the 'social_channel' dropdown in the backend. I have tried doing:
<?php while ( have_rows('social')) : the_row() ?>
<li>
<?php $select = get_sub_field_object('social_channel');
$choices = $select['choices'];
foreach ($choices as $choice) {
if ($choice == 'mail') {
echo '<a href="mailto:'.the_sub_field('link').'">';
} else echo '<a href="'.the_sub_field('link').'">';
} ?>
<img src="<?= get_template_directory_uri(); ?>/img/footer-<?php the_sub_field('social_channel') ?>.svg" alt="social icon" />
</a>
</li>
<?php endwhile; ?>
But this of course spits something out for all choices, whether or not they are selected by the user in the backend. Can anyone help me with this? I think this is pretty basic PHP but I'm not sure how to do it. Any help will be much appreciated!
Your Select field should return just a single string, not an array, (make sure you set the 'social_channel' field to NOT allow multiple values) so change your code to this:
<?php while ( have_rows('social')) : the_row() ?>
<li>
<?php $select = get_sub_field('social_channel');
if($select == 'mail'){
$linkURL = 'mailto:'.get_sub_field('link');
}else{
$linkURL = get_sub_field('link');
} ?>
<img src="<?= get_template_directory_uri(); ?>/img/footer-<?php the_sub_field('social_channel') ?>.svg" alt="social icon" />
</li>
<?php endwhile; ?>

Filter by 2 different category value

I want a field to show if it has a category of either 2 values from 2 different sub fields.
Im not quite sure how to do this though with 2 different subfields.
Here is an exmaple im trying to demo to show how I would like it to work:
<?php while(has_sub_field('team_profile')):
$category = get_sub_field('category');
$category_2 = get_sub_field('category_2');
if($category=='copyclearance')
if($category_2=='anothercat'){ ?>
<li class="col-lg-2 teamProfile">
<img src="<?php the_sub_field('profile_image'); ?>" class="img-responsive"/>
<h2><?php the_sub_field('profile_name'); ?></h2>
<p class="jobTitle"><?php the_sub_field('job_title'); ?></p>
</li>
<?php
}
endwhile; ?>
This is my working version with just one category filter (but I need 2):
<?php while(has_sub_field('team_profile')):
$category = get_sub_field('category');
if ($category=='copyclearance') { ?>
<li class="col-lg-2 teamProfile">
<img src="<?php the_sub_field('profile_image'); ?>" class="img-responsive"/>
<h2><?php the_sub_field('profile_name'); ?></h2>
<p class="jobTitle"><?php the_sub_field('job_title'); ?></p>
</li>
<?php
}
endwhile; ?>
So this would work, by looking to see if anything has been posted in either $category or in $category_2 then displaying all of them results. NOT using the 2 to filter specifically i.e only showing posts that are in both $category and $category_2
Instead of nesting your if statements, use the or operator:
if($category=='copyclearance' || $category=='anothercat') {
// ...
}
If you want to do more than two, I recommend using an array:
$valid_cats = array('copyclearance', 'cat2', 'cat3', 'etc');
if(in_array($category, $valid_cats)) {
// ...
}

get_post_meta() not working after javascript runs

I am trying to retrieve data through my template in wordpress using get_post_meta() function. This works fine if I put the code above the div which is using a javascript, but it doesnt work if I put this function after the java script.
My php template file is as follows.
Here is the div using the javascript file ( lets call it div 1)`
<div style="width: 100%;margin: 0 auto; clear: both; ">
<div style="width: 800px">
<ul class='tabs'>
<?php $the_query = new WP_Query( 'showposts=3' ); ?>
<?php
$i=1;
while ($the_query -> have_posts()) : $the_query -> the_post(); ?>
<li><a href='#tab<?php echo $i; ?>'><?php the_title(); ?></a></li>
<?php $i++; endwhile;?>
</ul>
</div>
<div class="clear"></div>
<div style="background:#d0d8e0; position:relative; width: 96%; margin: -1% 4% 4% 2%; padding: 40px 0 20px 0; ">
<?php $the_query = new WP_Query( 'showposts=3' ); ?>
<?php
$i=1;
while ($the_query -> have_posts()) : $the_query -> the_post(); ?>
<div id='tab<?php echo $i; ?>'>
<div class="tab" >
<h4><?php the_title(); ?></h4>
<?php the_content(); ?>
</div>
</div>
<?php $i++; endwhile;?>
</div>
<div class="clear"></div>
`</div></div>
And the code I am putting after this div to retrieve values from data base is( lets call it div 2)
<div class="group group-custom" >
<?php $url = get_post_meta($post->ID,'wpcf-youtube-url', true); ?>
<div style="float: left">
<iframe type="text/html" width="480" height="315" <?php echo wp_oembed_get( 'http://www.youtube.com/watch?v=' . $url ); ?></iframe>
</div>
<div class="video-area">
<h2><?php echo "" .get_post_meta($post->ID,'wpcf-video-line',TRUE)?></h2>
<br/>
<p><?php echo "" .get_post_meta($post->ID,'wpcf-video-text',TRUE)?></p>
<a class="button" href=""></a></div></div>
If I put the div 2 after div 1 in my php template, it doesn't work but if I switch the divs, it works normally. Here is my javascript file ( which I dont see a problem)
<script language="JavaScript">
$(function() {
$('ul.tabs').each(function(){
// For each set of tabs, we want to keep track of
// which tab is active and it's associated content
var $active, $content, $links = $(this).find('a');
// If the location.hash matches one of the links, use that as the active tab.
// If no match is found, use the first link as the initial active tab.
$active = $($links.filter('[href="'+location.hash+'"]')[0] || $links[0]);
$active.addClass('active');
$content = $($active.attr('href'));
// Hide the remaining content
$links.not($active).each(function () {
$($(this).attr('href')).hide();
});
// Bind the click event handler
$(this).on('click', 'a', function(e){
// Make the old tab inactive.
$active.removeClass('active');
$content.hide();
// Update the variables with the new link and content
$active = $(this);
$content = $($(this).attr('href'));
// Make the tab active.
$active.addClass('active');
$content.show();
// Prevent the anchor's default click action
e.preventDefault();
});
});
});
The live version of this work is http://cmi.pixstreammedia.com.s177734.gridserver.com/
I found the problem. I have to use <?php wp_reset_query() ?> after the new wp_query function is over to restores the $wp_query and global post data to the original main query.
http://codex.wordpress.org/Function_Reference/wp_reset_query

Filtering out items using SimpleXML

Been looking around and am stumped. Basically I'm trying to filter out a result from an xml feed and hide it from displaying in the html output. I'm trying to find out the venue "Hornblower Cruises and Events" and if it exists, hide the whole , which is the parent of all the nodes.
Here's the URL: http://www.sandiegomagazine.com/goldstartest/rss3-exclude.php
Here's my code:
<?php
$myfeed = simplexml_load_file('https://www.goldstar.com/api/listings.xml?api_key=6d0d598c69dfecfcf028b0d2b3c9b693b606ad8c&postal_code=92101');
$i = 0;
foreach ($myfeed as $goldstar):
$title=$goldstar->headline_as_html;
$summary=$goldstar->summary_as_html;
$dates=$goldstar->upcoming_dates->event_date->date;
$ourprice=$goldstar->our_price_range;
$fullprice=$goldstar->full_price_range;
$img=$goldstar->image;
$link=$goldstar->link;
$venue_name=$goldstar->venue->name;
$venue_street=$goldstar->venue->address->street_address;
$venue_locality=$goldstar->venue->address->locality;
$venue_region=$goldstar->venue->address->region;
$venue_zip=$goldstar->venue->address->postal_code;
$venue_phone=$goldstar->venue->phone;
$category=$goldstar->category_list->category->name;
// if ($venue_name == 'Hornblower Cruises and Events'){
// unset($myfeed->event);
//echo $myfeed->asxml();
//}
if (++$i > 20) {
// stop after 10 loops
break;
}
?>
<html>
<head></head>
<body>
<div class="gs-item">
<div class="gs-itemcontent">
<h3 class="gs-cat"><?php echo $category; ?></h3>
<h2><?php echo $title; ?></h2>
<h4 class="gs-date">Date: <?php echo $dates; ?> <br/>For more show dates, click here</h4>
<img src="<?php echo $img; ?>" />
<p><?php echo $summary; ?></p>
<div id="gs-callout">
<span class="fullprice">Full Price: <?php echo $fullprice; ?></span>
<br/>
<span class="ourprice">Our Price: <span class="gs-hilite"><?php echo $ourprice; ?></span></span>
<p><a class="gs-button" href="<?php echo $link; ?>" target="_blank">Buy Tickets ยป</a></p>
</div>
<ul class="gs-venue">
<li><strong><?php echo $venue_name; ?></strong> | </li>
<li><?php echo $venue_street; ?></li>
<li><?php echo $venue_locality; ?>, <?php echo $venue_region; ?> <?php echo $venue_zip; ?></li>
<li><?php echo $venue_phone; ?></li>
</ul>
</div>
<div class="gs-clear"></div>
</div>
<? endforeach; ?>
</body>
Help?
Use a keyed foreach
foreach ($myfeed as $key => $goldstar):
And then unset the entire current xml using the key
unset($myfeed->$key);
Or unset just the venue with unset($myfeed->$key->venue);
Alternately, you could just build a new obj instead of trying to edit the existing one. Instantiate a new object before your loop and then only add the pieces to it that you want to keep.
Or, you can just continue the foreach if you find the unwanted venue. The only downside is that you won't have a copy of your ok'd list in $myfeed. So...
if ($venue_name == 'Hornblower Cruises and Events') { continue; }
Firstly you should cast every object that you are getting from your SimpleXML object to the relevant type. For example you should cast string attributes or nodes with putting (string) before reading the field:
$venue_name = (string)$goldstar->venue->name
For your question about filtering, I'd suggest your own way to keep looking for the match string and then decide to add or not.
EDIT
You're trying to see if the venue name is 'Hornblower Cruises and Events' then unset the current event field and echo it as XML? Firstly you should write unset($myfeed) because it's the event field itself. Next asxml would return nothing if you unset $myfeed. And you have HTML mistake in your code. In every loop of your for, you're writing:
<html>
<head></head>
<body>
You should place them before the for. And there is no closing tag for them. Put the closing tags after for. If you want to just get the fields with not venue name 'Hornblower Cruises and Events', put the <?php if($venue_name != 'Hornblower Cruises and Events') : ?> before <div class="gs-item"> and put <?php endif; ?> after </ul>.

Simple Call to Get Category Images & Display in List

I'm displaying a list of sub categories by parent category ID and am wanting to display the category image in place of a category name.
Here is what I have so far...
<div id="menu_brands">
<div class="brand_head">
<h3><?php echo $this->__('Browse By Brand') ?></h3>
</div>
<div class="brand_list">
<?php
$cats = Mage::getModel('catalog/category')->load(6)->getChildren();
$catIds = explode(',',$cats);
$categories = array();
foreach($catIds as $catId) {
$category = Mage::getModel('catalog/category')->load($catId);
$categories[$category->getName()] = $category->getUrl();
$img = $category->getImageUrl(); //I suspect this line is wrong
}
ksort($categories, SORT_STRING);
?>
<ul>
<?php foreach($categories as $name => $url): ?>
<li>
<!--<?php echo $name; ?>-->
<a href="<?php echo $url; ?>" title="<?php echo $name; ?>">
<img src="<?php echo $img; ?>" width="auto" alt="<?php echo $name; ?>" /> <!--I suspect this line is wrong-->
</a>
</li>
<?php endforeach; ?>
</ul>
</div>
</div>
I've tried countless ways to display the images in place of the category names but nothing seems to make the images appear. Currently with the above, the output is an empty 'img src' so there is clearly an error with what I'm trying (and probably a better way of achieving what I'm after).
Please could someone kindly point out what the problem is?
If it's of any relevance, what I intend to do afterwards is then display the category images in a grid format (3 or 4 per line).
Many thanks in advance.
The solution by zigojacko is not ideal because it separately loads in models in a loop. This does not scale well, and with many categories will thrash your database. Ideally, you'd add the images to the child collection.
A faster solution is to add the image attribute to a collection with an ID filter like B00MER:
// Gets all sub categories of parent category 'Brands'
$parent = Mage::getModel('catalog/category')->load(6);
// Create category collection for children
$childrenCollection = $parent->getCollection();
// Only get child categories of parent cat
$childrenCollection->addIdFilter($parent->getChildren());
// Only get active categories
$childrenCollection->addAttributeToFilter('is_active', 1);
// Add base attributes
$childrenCollection->addAttributeToSelect('url_key')
->addAttributeToSelect('name')
->addAttributeToSelect('all_children')
->addAttributeToSelect('is_anchor')
->setOrder('position', Varien_Db_Select::SQL_ASC)
->joinUrlRewrite();
// ADD IMAGE ATTRIBUTE
$childrenCollection->addAttributeToSelect('image');
?>
<ul>
<?php foreach($childrenCollection as $cat): ?>
<li>
<a href="<?php echo $cat->getURL(); ?>" title="<?php echo $cat->getName(); ?>">
<img class="cat-image" src="<?php echo $cat->getImageUrl(); ?>" />
</a>
</li>
<?php endforeach; ?>
</ul>
We managed to resolve this ourselves - see fix below.
<?php
//gets all sub categories of parent category 'Brands'
$cats = Mage::getModel('catalog/category')->load(6)->getChildren();
$catIds = explode(',',$cats);
$categories = array();
foreach($catIds as $catId) {
$category = Mage::getModel('catalog/category')->load($catId);
$categories[$category->getName()] = array(
'url' => $category->getUrl(),
'img' => $category->getImageUrl()
);
}
ksort($categories, SORT_STRING);
?>
<ul>
<?php foreach($categories as $name => $data): ?>
<li>
<a href="<?php echo $data['url']; ?>" title="<?php echo $name; ?>">
<img class="cat-image" src="<?php echo $data['img']; ?>" />
</a>
</li>
<?php endforeach; ?>
</ul>
Surprised we didn't get more support on this with it being a relatively simple Magento issue. Thanks B00MER for your answer though.
Give this method a try instead of your $img = $category->getImageUrl(); to $img = getCategoryImage($category);
function getCategoryImage($category) {
$categoryCollection = Mage::getModel('catalog/category')->setStoreId(Mage::app()->getStore()->getId())->getCollection()->addAttributeToSelect('image')->addIdFilter($category->getId());
foreach($categoryCollection as $category) {
return $category->getImageUrl();
}
}
(now defunct) Reference: http://www.magentocommerce.com/boards/viewthread/5026/P45/

Categories