Jump to content

Output image tags


Peter Knight
 Share

Recommended Posts

Hi guys

Trying to output a series of image tags in surrounded by an <li> a

I've been partially successful in that the tags are displaying BUT they're repeating.

IE the following code ...

<?php 
echo"<ul class='article-filter uk-subnav uk-subnav-pill'>";
				
foreach($page->images as $image){
echo"
<li class='' data-uk-filter='{$image->tags}'>
<a href='#'>{$image->tags}</a>
</li>
";}					  
echo"</ul>"
;
?>

will output

  • Sitting-Room
  • Kitchen
  • Kitchen
  • Home-Office
  • Gym Basement
  • Bedroom Gym Basement

There's repetition in there. I only need a tag listed once.

There's also a case where an image has 3 tags IE 

  • Bedroom Gym Basement

is actually 3 separate tags.

That's the first 2 parts of my problem :)

Link to comment
Share on other sites

This is just to get you going...It is not a complete solution and will only work if there's only 1 tag per image...Otherwise, you need to capture each page's image's tag in an array (explode the tags string) and remove duplicates. Image tags are saved as a string of space separated tags. So, if there's more than one tag, you will get all of them in one line :-). Anyway, gotta run, so here goes...

$duplicates = array();
foreach($page->images as $image){
	if(in_array($image->tags, $duplicates)) continue;// skip duplicate tags
echo"
<li class='' data-uk-filter='{$image->tags}'>
<a href='#'>{$image->tags}</a>
</li>
";
$duplicates[] = $image->tags;

}					  
echo"</ul>"
;

Btw, why are you using a quote as a code block? :-)

Edited by kongondo
  • Like 1
Link to comment
Share on other sites

I've just tried that and it works in terms of outputting a list with no duplicates.

You're right though about commas within the LI. 

<li class="" data-uk-filter="Gym Basement">
<a href="#">Gym Basement</a>
</li>

Unfortunately, this means the UIKit filtering is broken as "Gym Basement" doesn't match images which are "Gym, Basement".

Link to comment
Share on other sites

Was there a question in there? :-)

$out = "<ul>";
$duplicates = array();
foreach($page->images as $image){
  // rather than count words, let's just explode each string into an array (even if only one word)
  $tagsArray = explode(' ', $image->tags);
  foreach ($tagsArray as $t) {
	if(in_array($t, $duplicates)) continue;// skip duplicate tags
	$out .= "<li class='' data-uk-filter='{$t}'>" .
	          "<a href='#'>{$t}</a>" .
                "</li>";
    $duplicates[] = $t;
  }
}                 

$out .= "</ul>";
echo $out;
  • Like 3
Link to comment
Share on other sites

Was there a question in there? 

Sorry - that was me typing/thinking out loud. :-/

Thanks for the sample. I'm set up and at the moment the LIs correctly produce

<li class="" data-uk-filter="Kitchen"><a href="#">Kitchen</a></li>
<li class="" data-uk-filter="Bedroom"><a href="#">Bedroom</a></li>
<li class="" data-uk-filter="Bathroom"><a href="#">Bathroom</a></li>
<li class="" data-uk-filter="Sitting-Room"><a href="#">Sitting Room</a></li>
etc

Now I need to apply image tags to a DIV surrounding an image.

In UI Kit, each filtered item (my image tag) separated by a comma:

<div data-uk-filter="filter-a,filter-b">...</div>

or

<div data-uk-filter="Bedroom,Gym,Basement" >...</div>

I've spent the last few hours goofing around with some code LostKobrakai gave me before which implodes an array but that was based on Page tags

<div data-uk-filter='{$tags->implode(", ", "tags")}'</div>

and then some code from your own example (which explodes!)

$tagsArray = explode(' ', $image->tags);

and i'm not getting anywhere.

So just to rewind a bit, here's my current base code which works but doesn't separate the image tags with a comma

<?php
				 
foreach($page->images as $image) {
$large = $image->width(800);
$thumb = $image->size(380);

echo "
  <div data-uk-filter=\"{$image->tags}\">
  <a class='fancybox-portfolio port-item' href='$image->url' rel='gallery1'></a>
  </div>
  ";
}
?>

I know in my mind, what I need to do but cab't translated that to working code when using image tags Vs page tags.

Worst case scenario, I can save each image as a page but I've a programming itch now I need to scratch :-/

Any tips after your 3am Media Manager marathon?

Link to comment
Share on other sites

Does this:

<div data-uk-filter="Bedroom,Gym,Basement" >...</div>

..come after your list?

<li class="" data-uk-filter="Kitchen"><a href="#">Kitchen</a></li>
<li class="" data-uk-filter="Bedroom"><a href="#">Bedroom</a></li>
<li class="" data-uk-filter="Bathroom"><a href="#">Bathroom</a></li>
<li class="" data-uk-filter="Sitting-Room"><a href="#">Sitting Room</a></li>

In that case you already have all the tags you need in $duplicates (you could rename it to say, $uniqueTags, btw) and do something like:

$commaTags = implode(', ', $uniqueTags);
$out .= '<div data-uk-filter="' . $commaTags . '" >...</div>';// if continuing with the $out above
echo $out;

Btw..the other code by @LostKobrakai is a newish ProcessWire syntax in case it's getting you confused with the 'normal' PHP implode syntax

Link to comment
Share on other sites

@Kongondo - thanks for the examples. 

Does this:

<div data-uk-filter="Bedroom,Gym,Basement" >...</div>

..come after your list?

It does but I have it in a separate PHP call. Not sure if that matters.

At the moment it's not working but leave it with me for a few hours. I'd like to fine comb it and try figure it out.

Link to comment
Share on other sites

Hmm. Not sure what I'm doing really. I'm reluctant to use code that I don't understand but want to wrap this up. Granted, my code doesn't work so I can't use it anyway :-/

Any pointers on where I'm going wrong?

Part 1 (works): Output a list of image tags with no duplicates

<?php
$out = "<ul  class='portfolioFilter'>";
$duplicates = array();
foreach($page->images as $image){
// rather than count words, let's just explode each string into an array (even if only one word)
$tagsArray = explode(' ', $image->tags);
foreach ($tagsArray as $t) {
if(in_array($t, $duplicates)) continue;// skip duplicate tags
  $out .= "<li class='' data-uk-filter='{$t}'>" .
          "<a href='#'>{$t}</a>" .
          "</li>";
$duplicates[] = $t;
}
}                 
					
$out .= "</ul>";
echo $out;
?>
<ul class="portfolioFilter">
<li class="" data-uk-filter="Sitting-Room"><a href="#">Sitting-Room</a></li>
<li class="" data-uk-filter="Kitchen"><a href="#">Kitchen</a></li>
<li class="" data-uk-filter="Home-Office"><a href="#">Home-Office</a></li>
<li class="" data-uk-filter="Gym"><a href="#">Gym</a></li>
etc...
</ul>

Part 2 (no working): 

Wrap each image in a DIV referencing the image tags in a "data-uk-filter". Unlike the LIs above, each image can have many tags separated by commas

 <?php
	
foreach($page->images as $image){

$tagsArray = explode(' ', $image->tags);
foreach ($tagsArray as $t2) 
$large = $image->width(800);
$thumb = $image->size(380);  
echo "

<div data-uk-filter=\"$t2\" >
  <a class=\"fancybox-portfolio port-item\" href=\"$image->url\" rel=\"gallery1\">
  <img src=\"$thumb->url\" alt=\"$thumb->description\" class=\"portfolio-thumb\">
  </a>
</div>
";}
?>

It works in the sense that it's outputting everything correctly but I'm only getting a single tag per image. Most images have more than 1 tag.

The output is 

<div data-uk-filter="Sitting-Room">
<a class="fancybox-portfolio port-item" href="/site/assets/files/1082/006---dc3420.jpg" rel="gallery1">
<img src="/site/assets/files/1082/006---dc3420.380x0.jpg" alt="Sitting room by Ensoul Interior Architecture" class="portfolio-thumb">
</a>
</div>

but it should start

<div data-uk-filter="Image-Tag1, Image Tag 2">
Link to comment
Share on other sites

@Peter,

It won't work like that. In part 1, each tag is a separate <li>. In part 2, each group of tags has to be within one <div data-uk-filter> but comma-separated. Hence, what @Martijn has said, or my earlier example using implode...

$commaTags = implode(', ', $uniqueTags);
$out .= '<div data-uk-filter="' . $commaTags . '" >...</div>';// if continuing with the $out above
echo $out;

...which I don't think will work in this case since you are doing a fresh foreach :-). So, go with @Martijn's

Thumbs up for trying though  ^-^:)

Edit: Here's the full code just for completion...You might get a syntax error in there somewhere; I haven't fully checked things are properly closed..

foreach($page->images as $image){

$large = $image->width(800);
$thumb = $image->size(380);  
echo "
<div data-uk-filter=". (str_replace($image->tags, ' ', ', ')) . ">
  <a class=\"fancybox-portfolio port-item\" href=\"$image->url\" rel=\"gallery1\">
  <img src=\"$thumb->url\" alt=\"$thumb->description\" class=\"portfolio-thumb\">
  </a>
</div>";
}

What @Martijn's code is doing is searching for a double space in the $image->tags string and replacing that with a comma then a space, e.g. 'This is my tag' will become, 'This, is, my, tag';

Edited by kongondo
Link to comment
Share on other sites

Thank you both. str_replace looks useful.

Since neither example was working, I did some digging and here' what I found.

1. The Div which is supposed to hold the comma separated image tags is outputting just the following around every image.

<div data-uk-filter=",">

That seems odd to me when the images field is called images and do have tags within.

2. I turned on error logging and found perhaps a more basic error which may be stopping the tags working?

Warning: Missing argument 2 for Pageimage::size(), called in /Users/peterknight/Sites/site2.co.uk/site/templates/Portfolio.php on line 56 and defined in /Users/peterknight/Sites/site2.co.uk/wire/core/Pageimage.php on line 240

I don't think this is the issue though as the Images themselves are successfully outputting both thumbs and larger modal versions.

At this stage, I think I've managed to output almost every kind of data from messing around with the code examples. I'm pretty sure at one stage I even had next weeks winning Lottery numbers on the page :)

Link to comment
Share on other sites

Thanks Martijn

My understanding of the images API is that I can set just a width and the height will be proportional

$img = $image->width($x)

Create a new image at width $x, and proportional in height to the original. 

so I'm not sure why thats throwing an error. At least I'm happy it's not causing my issue.

Can anyone actually try on their own install to output a list of comma separated image tags from a page? I've never seen it done before and there's not much evidence on the forums that it's been tried.

  • Like 1
Link to comment
Share on other sites

Peter, it can be done. There's nothing to prevent it from being done :-). Something is goofing your script somewhere. Either you are overwriting your output in the foreach loops or there is something else we can't see, given we are only seeing part of the code. I am finding it difficult to understand how the <div> are related to the <ul> (if at all). How should the end result look like on a single page? One list of <ul>,</ul> and several <div> one for each image on that page?

May I also suggest that if you can, try not to echo stuff within code but save them to a variable, usually $out, concatenating stuff to that variable and finally when you are done with the code, to echo $out. It's just easier to follow what's going on that way.

Back to your qn, if we can get a clearer picture of the end result, this can be resolved quickly, maybe even put up an example online on some PHP Fiddle..

  • Like 2
Link to comment
Share on other sites

Head over here and run the following code (pasting between the <?php ?> tags). Have a look at the output (underlying html) Is that what you are after? Note: this is pseudo-code. No image tags here. $tags here are equivalent to your $page->images. 

$tags = array('Bathroom', 'Gym Basement Loft', 'Home-Office Kitchen', 'Kitchen', 'Car', 'Gym');
$tagsArray = array();
$uniqueTags = array();
$out ='';

$out .= "<ul>";
foreach ($tags as $tag) {
	
	$tagsArray = explode(' ', $tag);

	foreach ($tagsArray as $t) {

		if(in_array($t, $uniqueTags)) continue;// skip duplicate tags

		$out .= "<li data-uk-filter='{$t}'><a href='#'>{$t}</a></li>";
		$uniqueTags[] = $t;
		
	}
}
$out .= "</ul>";

foreach ($tags as $tag) {

	$t = str_replace(' ', ', ', $tag);// our comma separated tags
	$out .= "<div data-uk-filter='{$t}'>" .
	  "<a class='fancybox-portfolio port-item' href='url' rel='gallery1'>" .
  		 $tag .
  		"</a>" .
		"</div>";
}


echo $out;

Alternative shorter code...looping 'once'

$tags = array('Bathroom', 'Gym Basement Loft', 'Home-Office Kitchen', 'Kitchen', 'Car', 'Gym');
$tagsArray = array();
$uniqueTags = array();
$divs ='';// will hold the <div>
$out ='';
$out .= "<ul>";
foreach ($tags as $tag) {
	
	$tagsArray = explode(' ', $tag);

	$t = str_replace(' ', ', ', $tag);
	$divs .= "<div data-uk-filter='{$t}'>" .
	  "<a class='fancybox-portfolio port-item' href='url' rel='gallery1'>" .
  		 $tag .
  		"</a>" .
		"</div>";

	foreach ($tagsArray as $t) {

		if(in_array($t, $uniqueTags)) continue;// skip duplicate tags

		$out .= "<li data-uk-filter='{$t}'><a href='#'>{$t}</a></li>";
		$uniqueTags[] = $t;
		
	}
}
$out .= "</ul>" . $divs;

Edited by kongondo
shorter code..
  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...