2

I am creating a calendar for displaying films and their screening times.

I already have a quite convoluted mechanism of retrieving data from the "films" channel, where I have a supertable for "filmScreenings", which contain values for "theater" for name of the theater and "starts" which is a datetime for when the screening starts.

I am trying to create a multidimensional array for storing the films and screenings per theater. This is what I would like to accomplish:

screeningsForTheater  = {
  "Theater 1" : [
    { "film" : "Movie 1", "starts" : "09:00" },
    { "film" : "Movie 2", "starts" : "11:30" },
    { "film" : "Movie 3", "starts" : "13:30" }
  ],
  "Theater 2" : [
    { "film" : "Movie 4", "starts" : "09:30" },
    { "film" : "Movie 5", "starts" : "11:00" },
    { "film" : "Movie 6", "starts" : "13:00" },
    { "film" : "Movie 7", "starts" : "21:00" }
  ]
}

From here on I would be able to loop screenings displaying films and their screenings in the correct column:

Theater 1         Theater 2
Movie 1, 09:00    Movie 4, 09:30
Movie 2, 11:30    Movie 5, 11:30
Movie 3, 13:30    Movie 6, 13:00
                  Movie 7, 21:00

Here is the twig-code for trying to create this kind of array:

{% set screeningsForTheater = {} %}

{% for film in films %}
  {% for screening in film.screenings %}

  {% set starts = screening.starts %}
  {% set ends = "calc starts + length in minutes" %}

  {% set screeningsForTheater = screeningsForTheater | merge(
    { 
      (screening.theater.label) : [
        { "film" : film.title, "url" : film.url, "starts" : starts, "ends" : ends, "length" : film.length }
      ] 
    }
  ) %}

  {% endfor %}
{% endfor %}

What happens is that the values for keys "Theater 1" and "Theater 2" are being replaced as the loop progresses. In the end I have an array that looks like this:

screeningsForTheater = {
  "Theater 1" : [{ "film" : "Movie 3" ... }],
  "Theater 2" : [{ "film" : "Movie 7" ... }]
};

I cant quite understand how to correctly push screenings into screeningsForTheater[theater] - any help you could offer?

Running Craft 2.6 if it has anything to do with Twig syntax.

  • 3
    Have you checked this answer? It might answer your question -> craftcms.stackexchange.com/a/5267/5275 – Jalen Davenport Mar 27 '18 at 16:53
  • Thanks for the link. Hadn't come across that one yet and I'm sure that the techniques described will be helpful in the future. – LosHosez Mar 28 '18 at 6:47
2

Ok, I managed to figure it out following directions on this page: Creating dynamic array and set keys

{% set filmData = { "film" : film.title, "url" : film.url, "starts" : starts, "ends" : ends, "length" : film.length } %}

{% if not attribute(screeningsForTheater, screening.theater.label) is defined %}

    {% set screeningsForTheater = screeningsForTheater | merge({ (screening.theater.label) : [filmData] }) %}

{% else %}

    {% set otherFilms = attribute(screeningsForTheater, screening.theater.label) %}
    {% set otherFilms = otherFilms | merge([filmData]) %}
    {% set screeningsForTheater = screeningsForTheater|merge({ (screening.theater.label) : otherFilms }) %}

{% endif %}

EDIT

However I realized I had to create another level to the array by including the date of the screening. This was the format needed:

screenings = {
  "22.3.2018" : {
    "Theater 1" : {
      "Movie 1" : { ... },
      "Movie 2" : { ... }
    },
    "Theater 2" : {
      "Movie 3" : { ... },
      "Movie 4" : { ... }
    }
  },
  "23.3.2018" : {
    "Theater 1" : {
      "Movie 5" : { ... },
      "Movie 6" : { ... }
    },
    "Theater 2" : {
      "Movie 7" : { ... },
      "Movie 8" : { ... }
    }
  }
}

I spent some time trying to create this kind of array using twig, but couldn't get the merge to work correctly.

I then created a plugin and a templateVariable to do the search and array stuff using PHP, which was a lot more comfortable, and got this working in no time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.