Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for forms in Blade templates #792

Merged
merged 5 commits into from
Feb 4, 2023

Conversation

jacksleight
Copy link
Contributor

@jacksleight jacksleight commented Jan 27, 2023

This PR adds support for the SC forms in Blade templates. It uses the same approach as statamic/cms#5892.

When the tags are called via Statamic::tag(...) the Antlers parser isn't set, so you can use that to check whether it's being called via Blade and return the raw form data instead, rather than the usual Antlers parsing. All the other variables that SC usually makes available inside the form tags is included in the returned array.

I haven't tested every form, but since all the SC forms go through the same createForm method this should work for all of them.

Usage Examples

Add to Cart Form

@php
$form = Statamic::tag('sc:cart:addItem')->params([
    'redirect' => '/cart',
])->fetch();
@endphp
<form {!! $form['attrs_html'] !!}>
    <input type="hidden" name="product" value="{{ $id }}" />
    <input type="text" name="quantity" value="1" />
    <button>Add to Cart</button>
    {!! $form['params_html'] !!}
</form>

Remove from Cart Form

@php
$form = Statamic::tag('sc:cart:removeItem')->params([
    'item' => $id
])->fetch();
@endphp
<form {!! $form['attrs_html'] !!}>
    <button>Remove</button>
    {!! $form['params_html'] !!}
</form>

Cart Update Form

@php
$form = Statamic::tag('sc:cart:update')->params([
    'redirect' => '/checkout/shipping'
])->fetch();
@endphp
<form {!! $form['attrs_html'] !!}>
    <input type="text" name="name" value="{{ old('name') }}">
    <input type="email" name="email" value="{{ old('email') }}">
    <button>Continue to Shipping</button>
    {!! $form['params_html'] !!}
</form>

Copy link
Owner

@duncanmcclean duncanmcclean left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this PR - it looks great! 🙌

I hope you don't mind, there's a couple of changes I'd like to make:

1. Form Params

Instead of requiring developers to need to loop through Simple Commerce's form parameters, I wonder if it might be easier for them to do something like this:

@php
$form = Statamic::tag('sc:cart:addItem')->params([
    'redirect' => '/cart',
])->fetch();
@endphp
<form action="{{ $form['attrs']['action'] }}" method="{{ $form['attrs']['method'] }}">
    {!! $formParams !!}

    <input type="hidden" name="product" value="{{ $id }}" />
    <input type="text" name="quantity" value="1" />
    <button>Add to Cart</button>
</form>

In this case, $formParams would be a string containing the hidden inputs etc needed for the form. It leaves the developer with slightly cleaner code.

Tests

I don't use Blade personally in Statamic projects so I'd like to ensure it's covered in case I touch something which breaks it.

If you have some time, would you be able to add in some tests to this PR? No worries if not, I can take a look.

@jacksleight jacksleight marked this pull request as draft January 28, 2023 09:58
@jacksleight
Copy link
Contributor Author

jacksleight commented Jan 30, 2023

Instead of requiring developers to need to loop through Simple Commerce's form parameters, I wonder if it might be easier for them to do something like this.

Agreed, TBH I never loved the fact that you have to loop those with the original core PR, but that was really just a quick fix to expose the raw data so it was usable in Blade.

How about best of both worlds? Keep the arrays of params and attrs, but also include param_html and attr_html values? Thinking if someone is using Alpine or Vue or making those requests in some other mysterious way they might want the raw data as an array still. Also remains consistent with how core returns those.

FYI, I’m working on a core PR that might make this even simpler in future.

@duncanmcclean
Copy link
Owner

Yeah, I'm happy to have both and array and a string with the HTML for the form parameters. 👍

@jacksleight
Copy link
Contributor Author

I've updated this with new params_html and attrs_html values, updated the examples above to match, and added tests wherever I could find an existing outputs form tag test.

I've also fixed what I think is a bug. The sc:cart:removeItem and sc:cart:updateItem tags accept product and item params, but these were not being included in the known params list so they were being rendered as <form> tag attributes as well. I've fixed that by adding a new argument to the createForm() method, so that each tag can specify additional known params.

@jacksleight jacksleight marked this pull request as ready for review February 2, 2023 11:37
@duncanmcclean
Copy link
Owner

Thanks! I'll review this when I can.

Copy link
Owner

@duncanmcclean duncanmcclean left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is all working great, thank you!

I've added some tests to ensure the item isn't added as parameters to the <form> tags and I've added a note to the documentation.

This will be included in the next release.

@duncanmcclean duncanmcclean merged commit be9bcba into duncanmcclean:main Feb 4, 2023
@jacksleight jacksleight deleted the blade-forms branch February 4, 2023 18:57
@github-actions
Copy link

github-actions bot commented Feb 4, 2023

Released as part of v4.5.3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants