Filtering & Sorting

A configurable pagelist is the basis for every navigation. This template illustrates the main concepts of filtering, sorting and searching in Automad pagelists.



INFINITE MOTHER
November 2024
Infinite Mother is a video game film, known as a machinima, that responds to the disassociation ...
More

HONEY FUNGUS
October 2024
Honey Fungus is a virtual reality science fiction piece by Jonah King and Sue Huang that encourages ...
More

BEST SYNTHETIC ANSWER #1: CROSSING
September 2024
Rindon Johnson’s Best Synthetic Answer #1: Crossing simulates a real-time journey from the ...
More

Rendezvous in Kyoto: 1000 Deaths at BitSummit DRIFT
August 2024
Pariah Interactive’s experience showcasing 1000 Deaths at the 13th edition of BitSummit, Japan's ...
More

SYMBIOSIS HYPNOSIS
June 2024
Rindon Johnson’s Symbiosis Hypnosis is a video game grounded in the evolutionary biologist Lynn ...
More

Blake Andrews Hacked 4 Guitar Hero Controllers during Triple Canopy's Live Feed
March 2024
Triple Canopy’s quarterly Live Feed event in March was devoted to music, subtitled “Add to ...
More

Kinfolk: First Augmented Reality Installation at the Museum of Modern Art
March 2024
An inside look at the process of installing an augmented reality experience at MoMA, from ...
More

India Game Developer Conference (IGDC) 2023 Recap
January 2024
Pariah Interactive recently showcased a demo of 1000 Deaths, our upcoming 3D platformer, at the ...
More

Level Up Your Game: A Panel Discussion about Indie Game Development | Tech Week 2023 Recap
December 2023
Learn about indie game development from local New York indie game makers and studios, featuring ...
More

KINFOLK
November 2023
Kinfolk brings underrepresented history closer than ever through immersive augmented reality (AR) ...
More

AEROBANQUETS RMX
November 2022
Aerobanquets RMX is a multi-sensory experience in virtual reality where users eat physical food ...
More

MADE IN TRANS-PAKISTAN
September 2022
Made in Trans-Pakistan is an exhibition by artist Umber Majeed featuring AR and ceramic sculptures ...
More

UNSUNG
September 2022
UNSUNG is a multi-player augmented reality learning experience that teaches students about musicians ...
More

THE BELLS PURSUING ONE ANOTHER
August 2022
The Bells Pursuing One Another is a video game by Rindon Johnson in collaboration with Jacqueline ...
More

IDIOM 1 PLEA PIECE (TIME IS A DIMENSION)
July 2022
Idiom 1 Plea Piece (Time is a Dimension) by Rindon Johnson is a five-channel collaged audio ...
More

BEYOND ALL POLARITIES, WE ARE _____
June 2022
“Beyond All Polarities, We Are _____” is a multisensory experience using our complex ...
More

AWOKE & AWOKENED: ALAAP
April 2022
An ongoing speculation into a techno-utopian myth, centered on the relationship between a mythical ...
More

THIS END THE SUN
June 2021
This End the Sun is a collaborative exhibition by artists Maryam Hoseini, Rindon Johnson, and Jordan ...
More

LAST YEAR'S ATLANTIC
March 2021
Coeval Proposition #2: Last Year’s Atlantic, or You look really good, you look like you pretended ...
More

MAY THE MOON MEET US APART, MAY THE SUN MEET US TOGETHER
March 2021
"May the moon meet us apart, may the sun meet us together" is an interactive virtual reality short ...
More

2020: THE RIDE
December 2020
"2020: The Ride" is a terrifying year in review in the form of a VR roller coaster because of course ...
More

ALL HER BODIES
November 2020
“All Her Bodies,” an experimental virtual reality project, merges poetic storytelling and ...
More

THE 1975 - DON'T WORRY
July 2020
The 1975 and Ben Ditto have curated an online exhibition of 15 artists responding to tracks from The ...
More

SHE WHO SEES THE UNKNOWN: KABOUS, THE RIGHT WITNESS AND THE LEFT WITNESS
February 2020
She Who Sees the Unknown: Kabous, The Right Witness and The Left Witness, commissioned by The Shed, ...
More

MEAT GROWERS: A LOVE STORY
November 2019
Two meatgrowers meet in a processing plant. They move automatically through each day, longing for ...
More

SONGS OF THE LOST
July 2019
Songs of the Lost is a magic-realist game odyssey through a surreal and absurd digital landscape. ...
More

DIANA SAID
March 2019
In the animated virtual reality work Diana Said (2019) the viewer is seated within a glass cell that ...
More

DREAMS OF THE JAGUAR'S DAUGHTER
March 2019
Dreams of the Jaguar's Daughter is a three-part surreal VR documentary where Achik', the spirit of a ...
More

PORTFOLIO
April 2018
More

5YEARPARTY
More

[Tech Week 2023] Level Up Your Game: A Panel Discussion about Indie Game Development
RSVP to attend in person: lu.ma/9sguooqt Watch the livestream of the event: ...
More

BLOG
Your source for game development techniques, critical examinations of video games, and latest news ...
More

CONTACT
Want to work together? Need technical support? Looking to share feedback? Don't hesitate to shoot ...
More

ABOUT
Pariah Interactive is an independent games and XR development studio based in Brooklyn, New York ...
More

Source /packages/tutorial/filter_sort.php
<?php defined('AUTOMAD') or die('Direct access not permitted!'); ?>
<# 
Since the header markup is the same in all templates, 
it is stored in a separate snippet file and therefore can be reused
across multiple templates.
#>
<@ snippets/header.php @>
    <# The top navigation is included here. #>
    <@ snippets/navbar.php @>
    <section class="section">
      <# 
      Since also the content markup is the same in every template,
      it is included here as a reusable snippet. 
      #>
      <@ snippets/content.php @>
    </section>
    <section class="section">
      <# 
      As a next step, the pagelist is configured.
      Note that query string parameters get used as parameter values to make the pagelist
      controllable by a menu.
      #>
      <@ newPagelist {  
        filter: @{ ?filter }, 
        search: @{ ?search },
        sort: @{ ?sort | def ('date desc') }
      } @>
      <# 
      A simple filter menu lets the user filter the paglist dynamically.
      #>
      <div class="field is-grouped is-grouped-multiline is-marginless">
        <div class="control">
          <div class="field has-addons">
            <p class="control">
              <a 
              <#
              The first button in the menu resets the filter.
              Note that the 'queryStringMerge' method is used here for the href attribute value to only 
              modify the filter parameter within an existing query string without resetting other options. 
              #>
              href="?<@ queryStringMerge { filter: false } @>" 
              class="button is-info<@ if not @{ ?filter } @> is-active<@ end @>">
                All
              </a>
            </p>
            <# 
            The 'filters' object contains all available tags of pages in the pagelist.
            The 'foreach' statement can be used to iterate over that list to create a filter button
            for every tag.
            #>
            <@ foreach in filters @>
              <p class="control">
                <a 
                <# Note the 'queryStringMerge' method. #>
                href="?<@ queryStringMerge { filter: @{ :filter } } @>" 
                <# The 'if' condition can be used to test whether a button is active. #>
                class="button is-info<@ if @{ ?filter } = @{ :filter } @> is-active<@ end @>"
                >
                  <# The ':filter' runtime variable contains the current tag within the loop. #>
                  @{ :filter }
                </a>
              </p>
            <@ end @>
          </div>
        </div>
        <# The sorting menu. #>
        <div class="control">
          <div class="field has-addons">
            <p class="control">
              <a 
              <# The concept of creating the sorting menu is the same as for the filters. #>
              href="?<@ queryStringMerge { sort: 'date desc' } @>" 
              class="button is-info<@ if not @{ ?sort } or @{ ?sort } = 'date desc' @> is-active<@ end @>">
                <span class="icon is-small">
                  <i class="fas fa-sort-numeric-down" aria-hidden="true"></i>
                </span>&nbsp;
                Date
              </a>
            </p>
            <p class="control">
              <a 
              href="?<@ queryStringMerge { sort: 'title asc' } @>" 
              class="button is-info<@ if @{ ?sort } = 'title asc' @> is-active<@ end @>"
              >
                <span class="icon is-small">
                  <i class="fas fa-sort-alpha-up" aria-hidden="true"></i>
                </span>&nbsp;
                Title
              </a>
            </p>
          </div>
        </div>
        <# A normal form is used to create the keyword search field. #>
        <div class="control">
          <form action="" method="get">
            <input 
            class="input" 
            type="text" 
            <# 
            Note that the input name can be used as variable. 
            For example 'name="search"' will add a query string parameter 'search' on submission
            which can be used as '@{ ?search }' (see value attribute).
            #>
            name="search" 
            placeholder="Keyword" 
            value="@{ ?search }"
            />
          </form>
        </div>
      </div>
      <br />
      <# The pagelist markup. #>
      <div class="columns is-multiline is-8 is-variable">
        <@ foreach in pagelist @>
          <# 
          While iterating over the pages,  
          the page context changes automatically with every iteration.
          Therefore, the normal page variables can simply be used to 
          reference the content of the current page within the loop.
          #>
          <div class="column is-one-quarter">
            <hr />
            <div class="field">
              <span class="is-size-5 has-text-weight-bold">@{ title }</span>
              <br />
              <span class="is-size-7">
                <# 
                Pipe functions can be used to modify the content of a variable.
                Here the date string is formatted to 'F Y' (month and year).
                #>
                @{ date | dateFormat ('F Y') }
              </span>
            </div>
            <div class="field is-size-6">
              <# 
              Multiple pipe functions can be chained. 
              Here, all tags get stripped before shortening the content to 100 characters.
              #>
              @{ textTeaser | 100 }
            </div>
            <a href="@{ url }" class="button is-light is-small">More</a>
          </div>
        <@ end @>
      </div>
    </section>
<# As the last step, the footer markup is included. #>
<@ snippets/footer.php @>
Made with Automad
Released under the MIT license
© 2025 by Marc Anton Dahmen