2

I've been writing a field plug-in for adding files to articles in com_content. I've got the basics of the field plug-in working ok, extending the JFormFieldFile class

The issue I've hit is, for the com_content form to be able to handle the upload of the file, it needs to have the encoding type of multipart, like enctype="multipart/form-data"

I could create a template override, with the edit.php file, and change the form tag there, but I'd like the form plug-in to not be dependent on a specific template.

Does anyone know a nice way of changing the form's tag from a field plug-in?

This is the first field plug-in I've written, so am still getting the hang of it.

I've using Joomla 4.0.5, incase that's useful to know.

1
  • 1
    Dear community, ever wonder why some questions get upvoted and others don't? Well, different users have different reasons for upvoting questions. My personal set of criteria are not hard to satisfy. Ask a clear question and include some context, proof of research, or a failed attempt to self-solve. When I see this, I see good content being added to the community. Therefore, I give an upvote -- even if I cannot answer. This question looks like a valuable addition to JSE, so I have upvoted. If anyone is looking for ways to gain privileges, just ask good questions. Good post, Andy. Commented Jan 10, 2022 at 23:52

1 Answer 1

3

There really isn't a good way to do this. Your best bet is parsing the already generated HTML and making a replacement there. For the component this can be done using onAfterDispatch event. Below is a basic example that adds enctype attribute to all component forms with item-form ID. Regex can probably be optimized and maybe a check should be added to prevent double attribute, in case it's already added in the layout. Also note that the ID may differ in different components and views. For instance, in frontend article form it's adminForm.

public function onAfterDispatch()
{
    // Get the document.
    $doc = $this->app->getDocument();

    // Check that we are manipulating a HTML document.
    if (!($doc instanceof Joomla\CMS\Document\HtmlDocument))
    {
        return;
    }

    // Get the HTML content.
    $html = $doc->getBuffer('component');

    // Add the attribute.
    $html = preg_replace('/<form((?=[^>]*id="item-form")[^>]*)>/', '<form$1 enctype="multipart/form-data">', $html);

    // Set the updated HTML.
    $doc->setBuffer($html, 'component');
}

Depending on whether you want this to run in other components, you may add some context checks. E.g. to run this only in com_content article forms, add this at the top:

// Check that we're in correct application.
if (!$this->app->isClient('site') && !$this->app->isClient('administrator'))
{
    return;
}

$input = $this->app->getInput();

// Check the component.
if ($input->get('option') !== 'com_content')
{
    return;
}

// Check the views.
if ($this->app->isClient('site') && $input->get('view') !== 'form')
{
    return;
}

if ($this->app->isClient('administrator') && $input->get('view') !== 'article')
{
    return;
}
3
  • Do you want a space before enctype in the replacement? Instead of capturing the lookahead, you could alternatively: '/<form[^>]* id="item-form"[^>]*\K/', ' enctype="multipart/form-data"' Commented Jan 11, 2022 at 8:34
  • @mickmackusa OK
    – Sharky
    Commented Jan 11, 2022 at 8:39
  • Thanks @Sharky that's ace, works really well. I'd tried it with onCustomFieldsPrepareDom, onContentPrepareForm, onContentPrepareData, onAfterRender and onContentPrepare, with no luck. I've not used onAfterDispatch before, that's really handy. Commented Jan 11, 2022 at 9:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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