Hajosch

Help with IMPLODE (different output of last page)

Recommended Posts

Posted (edited)

Hello everyone!

I am an absolute ProcessWire novice and unfortunately I don't have too good PHP knowledge. Nevertheless, I have made good progress with the development of our ProcessWire website thanks to this helpful forum. But now I have a problem with the formatting of field queries, where I still haven't found a solution after 2 days of searching.

I have a field "authors", which is created as type: PageReference / MultiplePages.

I would now like to query all authors of this field who are saved for a single book title. This works well with the following query:

<!-- Query of the authors -->
<?php
    if (count($page->authors)) {
    echo "<u>AUTOR/EN</u>:&nbsp";
    foreach($page->authors as $authors) {
        echo "<a href='{$authors->url}'>{$authors->title}</a>;&nbsp";
        }
    }
?>

Starting with the first author, each of the following authors is inserted a semicolon to separate the names of the individual authors. That works correctly. But I would like to have a dot after the last author, not a semicolon. So I want to get a result like this:

Author-1; Author-2; Author-3.

In the meantime I found out on this forum that the command 'implode' can be used for this. But I simply can't implement this solution in my specific case due to lack of PHP knowledge and I haven't found any patterns that I can use for my type of field query. So I would be very grateful for support. Where do I have to insert the command 'implode' with which additional parameters in my code?

It would be great if someone could help me by showing me how to change the code of my previous field query.

Thank you and best regards

Hajosch, Potsdam/Germany

Edited by cstevensjr
Formatted the Code for Readability

Share this post


Link to post
Share on other sites

There are various ways you can achieve this, including plain PHP and even plain HTML+CSS (depending on your use case you might be able to convert this to a list and add those delimiters as ::after pseudo-elements – it might even make more sense semantically), but probably the easiest way would be the implode() method of the WireArray class.

Since $page->authors returns an instance of PageArray and PageArrays inherit the methods of the WireArray class, you can do something like this in your code:

<!-- Query of the authors -->
<?php
    if (count($page->authors)) {
        echo "<u>AUTOR/EN</u>:&nbsp";
        echo $page->authors->implode("; ", function($item) {
            return "<a href='{$item->url}'>{$item->title}</a>";
        });
        echo ".";
    }
?>

A plain PHP solution using a counter variable would look something like this – this is probably the easiest method to understand for a not-so-experienced developer:

<!-- Query of the authors -->
<?php
    $author_count = count($page->authors);
    if ($author_count) {
        $count = 0;
        echo "<u>AUTOR/EN</u>:&nbsp";
        foreach ($page->authors as $author) {
            ++$count;
            echo "<a href='{$author->url}'>{$author->title}</a>";
            echo $count < $author_count ? ";&nbsp" : "."; // note: this is a ternary operator, see http://php.net/manual/en/language.operators.comparison.php#language.operators.comparison.ternary for details
        }
    }
?>

 

  • Like 3
  • Thanks 1

Share this post


Link to post
Share on other sites

You can also use some function like substr / str_replace or rtrim.

https://stackoverflow.com/questions/5592994/remove-the-last-character-from-string

You would have to build up a variable instead of echo-ing instantly to achieve this.

i.e. use something like $output .= .... inside the foreach loop, then do the str_replace() and finally echo() it.

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

Hello @Hajosch,

you could also do something like this:

<!-- Query of the authors -->
<?php
	if (count($page->authors)) {
		echo "<u>AUTOR/EN</u>:&nbsp";
		foreach($page->authors as $authors) {
			echo "<a href='{$authors->url}'>{$authors->title}</a>";
			if ($authors === $page->authors->last) {
				echo ".";
			} else {
				echo "; ";
			}
		}
	}
?>

Regards, Andreas

  • Like 3
  • Thanks 1

Share this post


Link to post
Share on other sites

Hello,

here is example using HTML "li" tags for list, and CSS pseudo-classes for styling HTML.

<?php
	if (count($page->authors)) {
		$out = '';
		foreach($page->authors as $authors) {
			$out.= "<li><a href='{$authors->url}'>{$authors->title}</a></li>";			
		}
        echo '<ul class="author-list">'.$out.'</ul>';
	}
?>

And CSS part:

.author-list { list-style-type: none; }
.author-list li { display: inline; }
.author-list li:after { content: "; "; }
.author-list li:last-child:after { content: "."; }

This example provide few options to style list inside CSS file only (inline or not, without bullets or not, various dividers etc.).
Codepen demo

Regards.

  • Like 3
  • Thanks 1

Share this post


Link to post
Share on other sites

Wow. This is an incredible feedback and an amazingly friendly forum. I thank everyone who took the time to offer me a solution to my problem.

I have now started with the first solution of teppo (the implode() method of the WireArray class), and it worked immediately.

On 8/4/2018 at 11:16 AM, teppo said:

 


<!-- Query of the authors -->
<?php
    if (count($page->authors)) {
        echo "<u>AUTOR/EN</u>:&nbsp";
        echo $page->authors->implode("; ", function($item) {
            return "<a href='{$item->url}'>{$item->title}</a>";
        });
        echo ".";
    }
?>

 

 

Thank you, thank you and thank you again!

I will now have another thorough look at the other solutions proposed by Dragan, AndZyk and OLSA and then give you a feedback that may also help other users who stumble across the same problem.

Thank you very much and have a nice day!

Hajosch

  • Like 2

Share this post


Link to post
Share on other sites

This is the shortest method using implode():

if($page->authors->count) echo $page->authors->implode("; ", "<a href='{url}'>{title}</a>") . ".";

 

  • Like 5
  • Thanks 1

Share this post


Link to post
Share on other sites

Hello Soma and everyone else who helped me to solve my problem. SOMA: Thanks for your suggestion, which also works well and which I took as standard because of the shorter code. It's amazing how many different solutions Processwire has to offer. I've learned a lot.

Thanks again to everyone and best regards
Hajosh

  • Like 4

Share this post


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.