Dynamic tags in foreach

I’m trying to create a simple for loop to display the opening hours of a company in a template, using the code below. All info is coming from a structured field which works like a charm form both development and client (panel) part, but I want to simplify some stuff…

<ul>
<?php
    $openinghours = $location->openinghours()->toStructure();
    foreach ($openinghours as $opening):
?>
    <?php
        $weekdays = array(
            'mon' => 'Monday',
            'tue' => 'Tuesday',
            'wed' => 'Wednesday',
            'thu' => 'Thursday',
            'fri' => 'Friday',
            'sat' => 'Saturday',
            'sun' => 'Sunday'
        );
        foreach ($weekdays as $shortweekday => $longweekday) :
    ?>
        <li>Company is open on <?= $longweekday; ?> from <?= $opening->open_mon_from(); ?> to <?= $opening->open_mon_to(); ?></li>
    <?php endforeach ?>
<?php endforeach ?>
</ul>

As you can see, this for-loop will repeat the $opening->open_mon_from() and $opening->open_mon_to() now each and every time, where the mon stands for monday. I’ve tried many several things, but I can’t get it wo work to replace the instance of mon by the $shortweekday string coming from the array.

Is this achievable at all, or do I have to manually write 7 instances of the <li> where I write down stuff like $opening->open_tue_from(), $opening->open_wed_from() etc?

Honestly, I think for this use case 7 lines of code are easier to write and faster executed by PHP than unnecessary foreach loops, whereas the inner loop is misplaced IMHO.

This is certainly not the right approach, I think. Could you please share what is stored in your structure field? And the blueprint for this field as well…

Sure thing!

The blueprint:

title:
    nl: Contact
    en: Contact

tabs:
    layouts:
        label:
            nl: Locaties
            en: Locations
        icon: page
        columns:
            sidebar:
                width: 1/3
                sticky: true
                sections:

                    pages:
                        type: pages
                        label:
                            nl: Subpagina's
                            en: Sub pages

            content:
                width: 2/3
                fields:
                    locations:
                        type: structure
                        label:
                            nl: Locaties
                            en: Locations
                        columns:
                            title:
                                width: 1
                        fields:
                            title:
                                label:
                                    nl: Naam
                                    en: Name
                                type: text
                            address:
                                label:
                                    nl: Adres
                                    en: Address
                                type: text
                                required: true
                            zip:
                                label:
                                    nl: Postcode
                                    en: Zipcode
                                type: text
                                width: 1/3
                                required: true
                            city:
                                label:
                                    nl: Stad
                                    en: City
                                type: text
                                width: 2/3
                                required: true
                            country:
                                label:
                                    nl: Land
                                    en: Country
                                type: select
                                options:
                                    nl:
                                        nl: Nederland
                                        en: The Netherlands
                                    en:
                                        nl: Engeland
                                        en: England
                                    pt:
                                        nl: Portugal
                                        en: Portugal

                            headingOpeninghours:
                                label:
                                    nl: Openingstijden
                                    en: Opening hours
                                type: headline
                                numbered: false

                            openinghours:
                                label:
                                    nl: Openingstijden
                                    en: Opening hours
                                type: structure
                                fields:

                                    open_title:
                                        label:
                                            nl: Locatietitel
                                            en: Location title
                                        type: text
                                        help:
                                            nl: Dit kan een titel zijn voor je extra locatie zoals bijvoorbeeld een dependance, of wanneer je een restaurant hebt kun je hiermee de openingstijden van zowel je restaurant zelf en die van je keuken aangeven
                                            en: This can be a title for your extra location such as an annex, or if you have a restaurant you can indicate the opening hours of both your restaurant itself and that of your kitchen

                                    open_mon:
                                        label:
                                            nl: Maandag
                                            en: Monday
                                        type: select
                                        options:
                                            open:
                                                nl: Geopend
                                                en: Open
                                            closed:
                                                nl: Gesloten
                                                en: Closed
                                        default: "open"
                                        width: 1/3
                                        required: true
                                    gap_mon_closed:
                                        type: gap
                                        width: 2/3
                                        when:
                                            open_mon: "closed"
                                    open_mon_from:
                                        label:
                                            nl: Van
                                            en: From
                                        type: time
                                        display: HH:mm
                                        width: 1/3
                                        when:
                                            open_mon: "open"
                                        required: true
                                    open_mon_to:
                                        label:
                                            nl: Tot
                                            en: To
                                        type: time
                                        display: HH:mm
                                        width: 1/3
                                        when:
                                            open_mon: "open"
                                        required: true

                                    open_tue:
                                        label:
                                            nl: Dinsdag
                                            en: Tuesday
                                        type: select
                                        options:
                                            open:
                                                nl: Geopend
                                                en: Open
                                            closed:
                                                nl: Gesloten
                                                en: Closed
                                        default: open
                                        width: 1/3
                                        required: true
                                    gap_tue_closed:
                                        type: gap
                                        width: 2/3
                                        when:
                                            open_tue: "closed"
                                    open_tue_from:
                                        label:
                                            nl: Van
                                            en: From
                                        type: time
                                        display: HH:mm
                                        width: 1/3
                                        when:
                                            open_tue: "open"
                                        required: true
                                    open_tue_to:
                                        label:
                                            nl: Tot
                                            en: To
                                        type: time
                                        display: HH:mm
                                        width: 1/3
                                        when:
                                            open_tue: "open"
                                        required: true

                                    open_wed:
                                        label:
                                            nl: Woensdag
                                            en: Wednesday
                                        type: select
                                        options:
                                            open:
                                                nl: Geopend
                                                en: Open
                                            closed:
                                                nl: Gesloten
                                                en: Closed
                                        default: open
                                        width: 1/3
                                        required: true
                                    gap_wed_closed:
                                        type: gap
                                        width: 2/3
                                        when:
                                            open_wed: "closed"
                                    open_wed_from:
                                        label:
                                            nl: Van
                                            en: From
                                        type: time
                                        display: HH:mm
                                        width: 1/3
                                        when:
                                            open_wed: "open"
                                        required: true
                                    open_wed_to:
                                        label:
                                            nl: Tot
                                            en: To
                                        type: time
                                        display: HH:mm
                                        width: 1/3
                                        when:
                                            open_wed: "open"
                                        required: true

                                    open_thu:
                                        label:
                                            nl: Donderdag
                                            en: Thursday
                                        type: select
                                        options:
                                            open:
                                                nl: Geopend
                                                en: Open
                                            closed:
                                                nl: Gesloten
                                                en: Closed
                                        default: open
                                        width: 1/3
                                        required: true
                                    gap_thu_closed:
                                        type: gap
                                        width: 2/3
                                        when:
                                            open_thu: "closed"
                                    open_thu_from:
                                        label:
                                            nl: Van
                                            en: From
                                        type: time
                                        display: HH:mm
                                        width: 1/3
                                        when:
                                            open_thu: "open"
                                        required: true
                                    open_thu_to:
                                        label:
                                            nl: Tot
                                            en: To
                                        type: time
                                        display: HH:mm
                                        width: 1/3
                                        when:
                                            open_thu: "open"
                                        required: true

                                    open_fri:
                                        label:
                                            nl: Vrijdag
                                            en: Fridday
                                        type: select
                                        options:
                                            open:
                                                nl: Geopend
                                                en: Open
                                            closed:
                                                nl: Gesloten
                                                en: Closed
                                        default: "open"
                                        width: 1/3
                                        required: true
                                    gap_fri_closed:
                                        type: gap
                                        width: 2/3
                                        when:
                                            open_fri: "closed"
                                    open_fri_from:
                                        label:
                                            nl: Van
                                            en: From
                                        type: time
                                        display: HH:mm
                                        width: 1/3
                                        when:
                                            open_fri: open
                                        required: true
                                    open_fri_to:
                                        label:
                                            nl: Tot
                                            en: To
                                        type: time
                                        display: HH:mm
                                        width: 1/3
                                        when:
                                            open_fri: "open"
                                        required: true

                                    open_sat:
                                        label:
                                            nl: Zaterdag
                                            en: Saturday
                                        type: select
                                        options:
                                            open:
                                                nl: Geopend
                                                en: Open
                                            closed:
                                                nl: Gesloten
                                                en: Closed
                                        default: "closed"
                                        width: 1/3
                                        required: true
                                    gap_sat_closed:
                                        type: gap
                                        width: 2/3
                                        when:
                                            open_sat: "closed"
                                    open_sat_from:
                                        label:
                                            nl: Van
                                            en: From
                                        type: time
                                        display: HH:mm
                                        width: 1/3
                                        when:
                                            open_sat: "open"
                                        required: true
                                    open_sat_to:
                                        label:
                                            nl: Tot
                                            en: To
                                        type: time
                                        display: HH:mm
                                        width: 1/3
                                        when:
                                            open_sat: "open"
                                        required: true

                                    open_sun:
                                        label:
                                            nl: Zondag
                                            en: Sunday
                                        type: select
                                        options:
                                            open:
                                                nl: Geopend
                                                en: Open
                                            closed:
                                                nl: Gesloten
                                                en: Closed
                                        default: "closed"
                                        width: 1/3
                                        required: true
                                    gap_sun_closed:
                                        type: gap
                                        width: 2/3
                                        when:
                                            open_sat: "closed"
                                    open_sun_from:
                                        label:
                                            nl: Van
                                            en: From
                                        type: time
                                        display: HH:mm
                                        width: 1/3
                                        when:
                                            open_sun: "open"
                                        required: true
                                    open_sun_to:
                                        label:
                                            nl: Tot
                                            en: To
                                        type: time
                                        display: HH:mm
                                        width: 1/3
                                        when:
                                            open_sun: "open"
                                        required: true

and the data from the textfile:

Title: Contact

----

Locations:

- 
  title: Location 1
  address: Streetname 123
  zip: 1234AB
  city: Amsterdam
  country: nl
  openinghours:
    - 
      open_title: Restaurant
      open_mon: closed
      open_mon_from: ""
      open_mon_to: ""
      open_tue: open
      open_tue_from: 12:00:00
      open_tue_to: 22:30:00
      open_wed: open
      open_wed_from: 12:00:00
      open_wed_to: 22:30:00
      open_thu: open
      open_thu_from: 12:00:00
      open_thu_to: 22:30:00
      open_fri: open
      open_fri_from: 12:00:00
      open_fri_to: 23:00:00
      open_sat: open
      open_sat_from: 12:00:00
      open_sat_to: 23:00:00
      open_sun: open
      open_sun_from: 12:00:00
      open_sun_to: 22:30:00
    - 
      open_title: Kitchen
      open_mon: closed
      open_mon_from: ""
      open_mon_to: ""
      open_tue: open
      open_tue_from: 12:00:00
      open_tue_to: 21:30:00
      open_wed: open
      open_wed_from: 12:00:00
      open_wed_to: 21:30:00
      open_thu: open
      open_thu_from: 12:00:00
      open_thu_to: 21:30:00
      open_fri: open
      open_fri_from: 12:00:00
      open_fri_to: 22:00:00
      open_sat: open
      open_sat_from: 12:00:00
      open_sat_to: 22:00:00
      open_sun: open
      open_sun_from: 12:00:00
      open_sun_to: 21:30:00

So, as you can see here the panel user should be able to add multiple locations with multiple subs which have their own opening hours. Something similar I want to achieve can be seen here, but in this case I want to show the restaurant’s opening hours for both the kithen and the restaurant establishment (Rotterdam and The Hague). An example below, where the opening/closing times of the restaurants and their kitchens differ one hour, but that could also be two hours or even more. It’s just dummy content:

ADDRESS ROTTERDAM RESTAURANT
Address 123
1234AB Rotterdam

OPENING HOURS ROTTERDAM RESTAURANT
Monday          Closed
Tuesday         12:00 - 22:00
Wednesday       12:00 - 22:00
Thursday        12:00 - 22:00
Friday          12:00 - 23:00
Saturday        12:00 - 23:30
SUNDAY          12:00 - 22:00

OPENING HOURS ROTTERDAM KITCHEN
Monday          Closed
Tuesday         12:00 - 21:00
Wednesday       12:00 - 21:00
Thursday        12:00 - 21:00
Friday          12:00 - 22:00
Saturday        12:00 - 22:30
SUNDAY          12:00 - 21:00

***

ADDRESS THE HAGUE RESTAURANT
Address 456
5678CD The Hague

OPENING HOURS THE HAGUE RESTAURANT
Monday          09:00 - 17:00
Tuesday         09:00 - 20:00
Wednesday       09:00 - 20:00
Thursday        09:00 - 23:30
Friday          Closed
Saturday        09:00 - 23:30
SUNDAY          09:00 - 22:00

OPENING HOURS THE HAGUE KITCHEN
Monday          09:00 - 16:00
Tuesday         09:00 - 19:00
Wednesday       09:00 - 19:00
Thursday        09:00 - 22:30
Friday          Closed
Saturday        12:00 - 22:30
SUNDAY          12:00 - 21:00

Hm, wouldn’t it make more sense to have a more open structure and maybe even a nested structure instead of fixed fields for every day?

openinghours:
  label:
    nl: Openingstijden
   en: Opening hours
  type: structure
    fields:
      open_title:
        label: Location title
        type: text
      openings:
        type: structure
        fields:
          day:
            label: Day
            type: text #or make this a select
         open:
           type: toggles
           options:
             - open
             - closed
          open_from:
            type: time
          open_to:
            type: time
#etc

And then you don’t loop through a days array, but just through the structure