1

I'm new to Craft CMS and I'm trying to build a new website using Craft. I want my client to be able to change the order of displaying contents of a page by dragging and rearranging them in the Admin panel. So I created a Section called 'Home Page' with type Single and I created few fields with type Matrix and I updated the Entry Type for section Home Page with those new fields. Home Page appeared in the Entries under Single as expected and I was able to update the contents on the matrix fields as well.

Then I created a twig file and used the content entered via Admin to render the home page. So far so good but my client wants to rearrange the fields (I don't know whether I can call them fields) in the Home Page via Admin by dragging them around and that should be reflected in the rendered homepage.

I thought of creating a subfolder and separate twig files for rendering the entry types in the home page but what I don't know is how I can query the entry types from the entry object in the order in which it's configured via the Admin panel.

My Home Page in Admin now looks like this

Banner
Why Choose Us
What We do
Our Clients
Testimonials

And my client wants to change this to say

Banner
What We do
Our Clients
Why Choose Us
Testimonials

Once they change this, it should be reflected in the rendered home page. Is this possible in Craft?

1
  • I tried the following [code] {% set section = craft.app.sections.getSectionByHandle('homePage') %} {% for e in section.getEntryTypes() %} {{ dump(e.name) }} <br/> {% endfor %} but only the string 'homePage' was printed out and not the entry types.
    – Jugs
    May 4 at 9:22
1

I can see what you're trying to do here, and it's really not a great idea to be honest:

Just to clarify for anyone else - we're not talking about "Entry Types" here - you're talking about the order of the fields as defined in the entry type's field layout. A client should not have access to alter this. Clients and future developers would not expect the order of fields in the back end to have any direct relationship to their order on the front end. The back end needs the flexibility to change over time according to new requirements without the fear of messing up the front end. If you ask editors to make changes to the entry type's field layout just to update content you miss out on things like entry versioning/drafts, and for example, the ability to disable individual blocks temporarily as you'd get with a Matrix field. If you ever start using Project Config the recommended way, even developers cannot access or edit the field layouts on the remote - changes in that area belong in Git, and far from editorial hands.

If you want to give clients control over the order of content, then Matrix is a great tool for this. You can combine Matrix with nested relationship field types (i.e. Entries/Categories fields) to emulate matrix-in-matrix functionality without the need for Super Table. (For example, you could have a generic block type called "widget" with just an Entries selector in it pointing to a section full of reusable page components - each of which could contain their own matrices... if that's a bit too advanced for a first site, then Super Table is still a good option).

Try to take a step back before you continue down your field layout rabbit hole too deep - maybe do some quick intro courses on Craftquest.io or similar to consider different approaches. The field layout editor is intended for developers, not editors.

1
  • That makes perfect sense brother! I will accept this as the answer. Thanks!
    – Jugs
    May 5 at 3:00
1

I think you might be going about this the wrong way. Personally, I'd create a single Matrix or Super Table field and attach that to your home page single. This is far easier for your editors to maintain and doesn't require the entry type's field layout every time you want to rearrange content.

However, to answer your question:

What you're looking for is the field layout definition for your entry type (which is effectively what you're looking at in the screen capture you've provided) and iterate over the fields ($entry->fieldLayout->fields) as necessary, either using a switch statement using the field name for conditional processing or by pulling in an include based on the field's name.

If you decide that the latter is really what you want to do, I'll help with some suggested logic but I'd encourage you to look at the first option before digging into the Craft class reference!

2
  • If I use a Matrix then I'm afraid I will be restricted with a single level of data because Matrix fields can't be of type Matrix. Please correct me if I'm wrong
    – Jugs
    May 4 at 13:11
  • You are correct in saying that you can't add a matrix field to a matrix field, but you can pretty much always get around this with alternating Super Table and Matrix fields. Your example suggests that a top level Super Table field might work if the structure is really that simple.
    – Andy
    May 4 at 14:15
1

I was able to get the field structure using the below code.

{% for entryType in entry.section.entryTypes %}
{% set fieldLayouts = entryType.getFieldLayout().getFields() %} 
{% for field in fieldLayouts %}
{{field.blockTypes[0]}}<br/>
{% endfor %}
{% endfor %}

outputs the handles like this

header whyChooseUs whatWeDo whoWeWorkWith ourClients testimonialsInfo

0

Your question is unclear to me, here is the solution that you can try, if still not working, please provide more information.

{% set entries = craft.entries.section('homePage').all() %} 
{% for entry in entries %} 
    {# control by entry handle #}
    {% if entry.type.handle == 'yourentryhandle' %}
       {{ entry.title }}

       {# control by maxtrix #}
       {% for block in entry.matrix %}
           {% if block.type == 'yourblocktype' %}
               {{block.title}}
           {% elseif block.type == 'yourblocktype2' %}
               {{block.title}}
           {% endif %}
       {% endfor %}
    {% elseif entry.type.handle == 'yourentryhandle2' %}
        {{entry.title2}}
    {% endif %}
{% endfor %}

If you are using a matrix, by default it should arrange based on the sequence arranged by the admin. If you are using entry, you might need to create a custom order system.

4
  • I know it's difficult to understand. Please check the image in the link below. ibb.co/hdHW4nz I'd like to get a list of all the entry types for a section in the same order as it is defined. For instance from the image I expect an array of entry types in the order title, header, whyChooseUs, whatWeDo, whoWeWorkWith, ourClients, testimonialInfo. I tried running your code but I got an error Calling unknown method: craft\elements\Entry::matrix() I think the block was not of type matrix
    – Jugs
    May 4 at 10:29
  • {% for entry in entries %} {{ entry.type }} {% endfor %} outputs "homePage" and nothing else. I expected a list of more than one entries but there seems to be just one.
    – Jugs
    May 4 at 10:31
  • Try use {% for block in entry.whyChooseUs.all() %} {% if block.type == 'yourblocktype' %} {{block.title}} {% elseif block.type == 'yourblocktype2' %} {{block.title}} {% endif %} {% endfor %} or {% set blockWhyChooseUs = entry.whyChooseUs.type('matrixFieldType').one() %} {{blockWhyChooseUs.title}}
    – Lee
    May 4 at 10:41
  • I can do this without any problem. entry.whyChooseUs.all() but the question I'm asking is on what position is whyChooseUs field is in the Entry Types. Is there anyway I can iterate through the Entry Types for a Section? Like in the image I posted above, I have 7 fields and is there any way I can iterate through those 7 fields and know which field is where in the order. Once I deliver the code, then my client will play around with Enrty Type definition as he might move whatWeDo above whyChooseUs and they expect the home page to be rendered with that change. Something like a page builder
    – Jugs
    May 4 at 13:15

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.