Entries Sorted by Author in ExpressionEngine Templates

Last night while burning the midnight oil I came to one of my tasks. My task was to create a template to show a list of authors and under each author a list of their entries. Simple you may think, but no.

This problem bit me for a few hours and what made me more infuriated is that I know I solved this many years ago but had forgotten how I did it. What follows is how I solved this issue…again!

For the purposes of this example I have 2 authors each with 3 entries assigned to them. This is how I want them to look in my front-end.

Rage

So lets start with a typical loop of entries and see what kind of data structure we can come up with by default.

{exp:channel:entries channel="blog" status="not closed" dynamic="no" disable="pagination|member_data|category_fields|categories|custom_fields"}
    <h2>{author}</h2>
    {title}<br />
{/exp:channel:entries}

So in my setup that would give me the following and use 19 queries and 6.5MB of memory.

Rage

Not what we wanted but we can see the issue here, that we are duplicating the author title before each entry. Ok so the next step would be to use an embed that we can pass the author id into and loop through the entries. Lets try that and see what we get.

I add an embed to my original template first and pass in the {author_id}

{exp:channel:entries channel="blog" status="not closed" dynamic="no" disable="pagination|member_data|category_fields|categories|custom_fields"}
    <h2>{author}</h2>
    {embed="includes/author-entries" author_id="{author_id}"}
{/exp:channel:entries}

In our template includes/author-entries I have the following

<ul>
    {exp:channel:entries channel="blog" status="not closed" dynamic="no" disable="pagination|member_data|category_fields|categories|custom_fields" author_id="{embed:author_id}"}
    <li>{title}</li>
    {/exp:channel:entries}
</ul>

So this gives me the following and uses 43 queries and 6.48MB of memory. We are immediately running a performance risk where we are embedding the template 6 times for each entry.

Rage

So what to do. I used PHP in my templates and performance wise it comes in at a reasonable 27 queries and 6.48MB of memory used.

{exp:channel:entries channel="blog" status="not closed" dynamic="no" disable="pagination|member_data|category_fields|categories|custom_fields"}
<?php
    $authors[] = "{author}"; //create array of authors
    $author_ids[] = "{author_id}"; //create array of author IDs
?>
{/exp:channel:entries}

<?php
    $authorOutput = array_unique($authors); //remove duplicate authors
    $idOutput = array_unique($author_ids); //remove duplicate author IDs
?>

<?php
    foreach (array_combine($authorOutput , $idOutput) as $name => $id) {
            echo "<h2>".$name."</h2>";
?>
            {embed="includes/author-entries" author_id="<?php echo $id;?>"}
<?php
    }
?>

Now I’m sure my PHP if not very efficient and could probably use some work, but have any of you come up with a similar solution, written a plugin or found a default tag in the EE Docs that I am clueless about? I did experiement with Stash but I have yet to get my head around it to fit into my workflow.