Jump to content

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 post
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 post
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 post
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 2
Link to post
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 post
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 post
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 post
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 post
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 post
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 post
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 post
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 post
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 post
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
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By spercy16
      These issues should be fairly easy for any intermediate to advanced ProcessWire developer to answer. I'm new to PHP and relatively new to ProcessWire and just need a bit of help. What I'm trying to do is bring in a couple of cards from my Projects page to display on my home page. I finally got the code right to bring in the cards but right now they're using my original images instead of my resized "variations". So firstly, I would like to know how to reference the variations of my images instead of using the original. Secondly, I need to grab only four of the cards from the Project page and not import in all ten. It should be just two small changes to my code to do these things (I would imagine). Here is the code I currently have for that section:
      <?php // https://processwire.com/api/arrays/ // check if the array of images has items if (count($pages->get("/projects/")->images)) : // get array of images from the field $images = $pages->get("/projects/")->images; $count = 0; // iterate over each one foreach ($images as $image) : $count++; $sectionText = $pages->get("/projects/")->get("paragraph_$count"); $img = $image; $buttonCode = $pages->get("/projects/")->get("url_$count"); ?> <span id="card<?php echo $count?>" class="card"> <img class="cardThumb" src="<?php echo $img->url; ?>" alt="<?php echo $image->description; ?> Thumbnail" /> <div class="cardBody"> <div class="cardText"> <h2><?php echo $img->description; ?></h2> <?php echo $sectionText; ?> </div> <div class="primaryBtn"> <a href="https://www.paypal.com/donate?hosted_button_id= <?php echo $buttonCode; ?> &source=url"> <button> <i class="fas fa-donate"></i> Donate </button> </a> </div> </div> </span> <?php endforeach; endif; ?> Thanks in advance for any help!
    • By skeltern
      WebP image support is great and works fine. But once created I've issues to get rid of all API generated WebP variations.
      The backend image field variations "Delete" works and I can remove all variations JPEG plus WebP. Image list is clean but all WebP API variations are still stored in file system (for instance files/12345/84.900x675.webp etc). I can only use ImageSizer with temp 'force' option to request fresh WebP variations or have to delete WebP files from folders. No other way so far. Tested with 2 sites and latest master PW 3.0.165.
      Is there somewhere a "magic button" or config/setup thing to solve my sticky WebP issue?
    • By psy
      I've searched, and maybe missed, the solution. I have a 'normal' images field and uploading images with a file size greater than 10Kb is fine. Any image size smaller results in the never-ending spinner and no upload.
      No min/max width/height set on image uploads in admin, ie just the defaults.
      Any ideas on how to fix?
      Using:
      PW: 3.0.175
      PHP: 7.3
      Marking it as "Resolved" rather than "Solved" as it auto-magically fixed itself. No idea whether PW, PHP, or just an internet hiccough... All good now 🤞
    • By totoff
      Dear all,
      tomorrow I'll have to introduce some editors on how to upload and edit images in image fields in Processwire. The site in question is quite image rich and I've spent some time to serve the appropriate images via scrcset already cropped for different screen sizes.
      However, the backend offers a lot of possibilities to manipulate images and most of them I'm not familiar with because as a developer I've never spent much thinking on what all the features might be good for … Yet I'm concerned that my editors work on images in the backend may interfere with my optimization strategies in the templates.
      Is there a general rule of thumb what content editors should do or not do with images in order not to break srcset strategies etc.? Maybe there is already a source of information you could point me to?
      Your recommendations are much appreciated!
    • By totoff
      Dear all,
      I'm upgrading an older side with the new custom fields for images feature as of 3.0.142. My image field is set to "Automatic" and holds a bunch of images together with their respective description on each page. New custom fields include "caption" among others and to make my live easier I I'm trying to populate "caption" with the value from the (default) description field. But unfortunately I can't seem to find out how to save the newly set values. This is my code:
      <?php foreach (page()->images as $image) { $image->set('caption', $image->description); bd($image->caption); echo files()->render("markup/views/view-card-image-fancybox.php", array('image'=>$image)); } ?> <?php $page->save(); bd($page->save()); ?> This sets the value as intended (see screenshot) but doesn't save it permanently to the database. What am I doing wrong?
      Thanks!
       

×
×
  • Create New...