A quick way to make Composer forms more condensed

We routinely configure sites to use make use of Composer to create new pages, often with lots of attributes that get used on custom page and block templates. This then makes it really easy for our clients to manage pages on their sites with structured content, and we can programatically control output.

One minor but recurring problem with this approach is that a Composer form can get pretty long, especially if you’re using lots of individual attributes that aren’t always used. We had a client the other day ask whether it was possible to make some of their long composer forms a bit more condensed, as one of their forms had 30 fields in a row that they sometimes use. And they weren’t fields we could condense down into new attribute types, they had to stay as seperate fields.

With the Composer page/form being core behaviour, I wanted to find a way to override this, but in a fairly lightweight way, and something I could remove easily if my override caused an issue with future upgrades. I came up with something quite simple, admittedly a bit hacky (and using jQuery), but I thought it was worth sharing. It’s an easy one to drop into a site.

What you would do is drop the following code, into a file at /application/elements/page_types/composer/form/output/form.php

defined('C5_EXECUTE') or die("Access Denied.");
include_once(DIR_BASE_CORE .'/elements/page_types/composer/form/output/form.php'); ?>

    $("fieldset legend:contains('+')").each(function(index) {
        $(this).text( $(this).text().replace('+', ''));
        let fieldset = $(this).closest('fieldset');
        fieldset.attr('id', 'composer-fieldset-' + index);
        let fields = fieldset.find('.form-group');
        $(this).append('<button class="btn btn-sm btn-info pull-right float-end expand-fields" aria-expanded="false" data-label="<?= t('View Fields');?> (' + fields.length + ')" aria-controls="composer-fieldset-' + index + '" href=""><?= t('View Fields');?> (' + fields.length + ')</button>');

        if ($(this).attr('aria-expanded') === 'false') {
            $(this).text('<?=t('Hide Fields'); ?>');
            $(this).attr('aria-expanded', 'true');
        } else {
            $(this).attr('aria-expanded', 'false');

All this does is inject a bit of extra Javascript into the Composer page, the core page itself gets loaded as is. This same code works on V8 and V9.

Then what you do is just add + character to field set Name. When the script runs, it strips this character from the label, but it knows to make that section collapsable.

Screen Shot 2022-08-21 at 12.04.59 pm

Then this happens:

On V8:

The only thing I wasn’t 100% sure of was the correct way to load the original elements file, in particular when there’s an upgrade core folder in use. I’ve used the constant DIR_BASE_CORE, but there might be a better way to do that (I always upgrade sites by replacing the core). I have no doubt the Javascript could be improved.

Just thought I’d share in case this is found to be handy, or it prompts some further ideas on Composer forms in general.


@mesuva I’ll see what i can find out from engineering. It might be a bit as we have some on holiday’s.

I’m not sure if there’s any need for you to chase anything up here, I was really just sharing to see if others found useful, or might have some suggestions.

1 Like

@mesuva thanks for sharing. This is a really good idea and I’d bet that other people would find it useful without having to do the little + hack (as brilliant as that is). You should consider making a pull request and/or feature request here: Issues · concretecms/concretecms · GitHub

I’d bet there’s a fairly easy way to just add an option to attributes used in composer where they could be marked as collapsable or optional and thus get different visual treatment in Composer.

If you don’t have time, let me know and I can make a feature request for you based on this post.


That looks like a great UX feature that could make end users’ interaction with composer nicer when there are many optional fields.

+1 for finding a way to have that included in core :slight_smile:

This worked for me. Thanks. im using on 5.8

Note that this was submitted to the core, so will be available in 9.2 when that comes out - you’ll be able to remove your form.php file once you’re using it.

1 Like