-
Notifications
You must be signed in to change notification settings - Fork 27
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
Added support for yaml aliases across all forms. #104
base: master
Are you sure you want to change the base?
Conversation
With a sample form: notification:
enabled: true
subject: 'Brewery Quote- {name}'
subject_prefix: '[Palladium Form]'
replyto_name: '{NAME}' # Email addresses and names can be either the
replyto_email: '{EMAIL}' # name of a field below or valid text.
to_name: 'Palladium'
to_email: '[email protected]'
from_name: 'PalladiumInsurance'
from_email: '[email protected]'
feedback:
success: 'Form submitted'
error: 'Please check your fields and resubmit'
redirect:
target: /page/thank-you
query: [ name, email ]
database:
contenttype:
name: brewery_forms
ignore_missing: true
fields:
Name: *name
Email: *email
Phone: *phone
TradeName:
type: text
options:
required: true
label: Operating/Trade Name
attr:
placeholder: Doe Brewery
constraints: [ NotBlank, { Length: { 'min': 3, 'max': 40 } } ]
Address: *address
City: *city
Province: *province
PostalCode: *postal
EquipmentLimit:
type: text
options:
label: Equipment Limit
StockLimit:
type: text
options:
label: Stock Limit
GeneralLimit:
type: text
options:
label: 'General Contents Limit (including: leasehold improvements, packaging, swag, other)'
FoodPrep:
<<: *true_false
options:
<<: *true_false.options
label: Is there any food preparation done on premises?
Entertainment:
<<: *true_false
options:
<<: *true_false.options
label: Any entertainment on premises?
GrossAnnualSales:
type: text
options:
label: Estimated Gross Annual Sales
attr:
placeholder: 220,000
class: money
constraints: [ NotBlank, { Length: { 'min': 2, 'max': 20 } } ]
GrossAnnualSalesTap:
type: text
options:
label: Of your gross annual sales, please estimate how much is from your taproom.
attr:
placeholder: 120,000
class: money
constraints: [ NotBlank, { Length: { 'min': 2, 'max': 20 } } ]
EmployeesCount:
type: integer
options:
required: true
label: Number of employees (excluding owners)
constraints: [ PositiveOrZero ]
SeatingCapacity:
type: integer
options:
required: true
label: Seating capacity inside the brewery "tap‑room"
constraints: [ PositiveOrZero ]
ToursMonthly:
type: integer
options:
required: true
label: Approximate number of brewery tours conducted monthly
constraints: [ PositiveOrZero ]
DeliveryVehicles:
type: integer
options:
required: true
label: How many vehicles used for deliveries?
constraints: [ PositiveOrZero ]
recaptcha:
type: captcha
options:
captcha_type: recaptcha_v2
row_attr:
class: full-row captcha
submit:
type: submit
options:
label: Submit my message
attr:
class: button primary
row_attr:
class: full-row based on yaml aliases: https://www.educative.io/blog/advanced-yaml-syntax-cheatsheet Note I did an unset unset($result[$formName]['global_aliases']); which might cause a crash if the ['global_aliases'] doesn't exist (haven't checked). |
Oh, and I added more info on exceptions since individual forms (when in separate files) weren't reporting errors. I think the line count gets thrown off in the error dialog (since the global get's "injected" into the parser, but I can fix that later. |
Hi @Halopend, Thank you for opening this PR. What a nice feature!! I've been doing some testing and this is what I found: Exceptions are thrown because the Using the yaml global alias functionality should be an extension of the default boltforms configuration file and only be enabled when the user creates an specific There are parsing exceptions in the Could you let me know what I'm missing to get this to work? |
@nestordedios Fair point. Looks like I need a better handling on when it isn't in place (which I didn't test deeply since I'm using it). I do agree putting it in the default config file is probably a better way to go (I was originally going that route but ran into an issue and was pushing this through for a project so I just moved to another file for simplicity). Now that I have some space I'll work on making a little more native bolt forms feeling. |
@nestordedios I changed it to just use the default config file now (bolt has enough config files tbh) with some error handing thrown in if it doesn't exist. I will say, the rest of the code seems to hint at this file being optional but I can't figure out exactly what's going on with the "replace recursive" call when loading a config is so I built most of my code after that part of the process with the assumption the default config file is needed (hence my throwing an error up the chain if not found). If that isn't clear, I'm no longer requiring a separate bolt-forms-global.yaml file and just developed a way (I'm hoping is robust) to extract it out of the base bolt forms config file using regex. It basically looks for "global_aliases:" and grabs everything up to the next line that starts with a non-whitespace/non-comment char (ie, the next variable). It's worked well in my testing and even has support of detecting if global aliases is commented out (ie. allowing it to be added as an optional parameter to the default config) but I haven't looked at the full yaml spec to see if there's any edge cases I need to look out for that will break it (for example, multiline comments). I am pretty sure I need to add support of "end of file" reached (ie. global_aliases can't be the last thing in the config), but as an intial step assuming the global aliases is near the top of the bolt forms config it would be helpful if you can test it out an let me know how it goes. |
Hi @Halopend, Thank you for your last commits. Nice job! I will take some time to test it out tomorrow and hopefully we can merge it in 💪 !! |
Hi @Halopend , I've taken more time to look into this and I'm a bit confuse. What I understood this feature would do is that it would allow you to create a I don't understand exactly what you have implemented but it seems to me that Bolt already supports YAML anchors and alias and the overrides of those aliases. This is allowed in a per file base but not in separate files. I've tried creating the This is the global_aliases:
name: &name
type: text
options: &name.options
required: true
label: Your Full Name
attr:
placeholder: John Doe
constraints: [ NotBlank, { Length: { 'min': 3, 'max': 128 } } ]
website: &website
type: text
options: &website.options
required: true
label: Website
attr:
placeholder: www.examplesite.com
constraints: [ NotBlank, { Length: { 'min': 3, 'max': 40 } } ]
phone: &phone
type: text
options: &phone.options
required: true
label: Phone
attr:
placeholder: (613) 555-5555
constraints: [ NotBlank, {Regex: { pattern: '/^(\+\d{1,2}\s?)?1?\-?\.?\s?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$/'} }]
email: &email
type: email
options: &email.options
required: true
label: Personal Email Address
attr:
placeholder: [email protected]
constraints: [ NotBlank, Email ]
postal: &postal
type: text
options: &postal.options
required: true
label: Postal Code
constraints: [ NotBlank, {Regex: {pattern: '/^([a-zA-Z]\d[a-zA-Z])\ {0,1}(\d[a-zA-Z]\d)$/'}} ]
address: &address
type: text
options: &address.options
required: true
label: Street Address
attr:
placeholder: 1234 Main St
constraints: [ NotBlank, { Length: { 'min': 5, 'max': 30 } } ]
row_attr:
class: street-pack
province: &province
type: choice
options: &province.options
required: true
label: Prov
choices:
Alberta: AB
British Columbia: BC
Manitoba: MB
New Brunswick: NB
Newfoundland: NL
Nova Scotia: NS
Ontario: ON
Prince Edward Island: PE
Quebec: QC
Saskatchewan: SK
Northwest Territories: NT
Nunavut: NU
Yellow Knife: YT
preferred_choices: [ON]
multiple: false
city: &city
type: text
options: &city.options
label: City
attr:
placeholder: Ottawa
date_year: &date_year
type: choice
options: &date_year.options
required: true
label: "Date of birth DD/MM/YY"
choices:
1940 : 1940
1941 : 1941
1942 : 1942
1943 : 1943
1944 : 1944
1945 : 1945
1946 : 1946
1947 : 1947
1948 : 1948
1949 : 1949
1950 : 1950
1951 : 1951
1952 : 1952
1953 : 1953
1954 : 1954
1955 : 1955
1956 : 1956
1957 : 1957
1958 : 1958
1959 : 1959
1960 : 1960
1961 : 1961
1962 : 1962
1963 : 1963
1964 : 1964
1965 : 1965
1966 : 1966
1967 : 1967
1968 : 1968
1969 : 1969
1970 : 1970
1971 : 1971
1972 : 1972
1973 : 1973
1974 : 1974
1975 : 1975
1976 : 1976
1977 : 1977
1978 : 1978
1979 : 1979
1980 : 1980
1981 : 1981
1982 : 1982
1983 : 1983
1984 : 1984
1985 : 1985
1986 : 1986
1987 : 1987
1988 : 1988
1989 : 1989
1990 : 1990
1991 : 1991
1992 : 1992
1993 : 1993
1994 : 1994
1995 : 1995
1996 : 1996
1997 : 1997
1998 : 1998
1999 : 1999
2000 : 2000
2001 : 2001
2002 : 2002
2003 : 2003
2004 : 2004
2005 : 2005
2006 : 2006
2007 : 2007
2008 : 2008
2009 : 2009
row_attr:
class: date year flex-111
date_month: &date_month
type: choice
options: &date_month.options
required: true
label: " "
choices:
January : January
February : February
March : March
April : April
May : May
June : June
July : July
August : August
September : September
October : October
November : November
December : December
row_attr:
class: date month flex-111
date_day: &date_day
type: choice
options: &date_day.options
required: true
label: " "
choices:
1 : 1
2 : 2
3 : 3
4 : 4
5 : 5
6 : 6
7 : 7
8 : 8
9 : 9
10 : 10
11 : 11
12 : 12
13 : 13
14 : 14
15 : 15
16 : 16
17 : 17
18 : 18
19 : 19
20 : 20
21 : 21
22 : 22
23 : 23
24 : 24
25 : 25
26 : 26
27 : 27
28 : 28
29 : 29
30 : 30
31 : 31
row_attr:
class: date day flex-111
true_false: &true_false
type: choice
options: &true_false.options
required: true
choices:
Yes: 1
No: 0
true_false_unknown: &true_false_unknown
type: choice
options: &true_false_unknown.options
required: false
choices:
Yes: 1
No: 0
Unknown: Unknown
choose_message: &choose_message
placeholder: 'Choose an option' And this the # BoltForms
## Debugging
#
# Global debugging on/off switch
#
# If enabled, ALL forms will go into debug mode.
debug:
enabled: true
address: [email protected]
## Various SPAM protection measures
#
# Enable CSRF protection for forms. You should leave this set to 'true', unless
# you know what you're doing.
csrf: true
honeypot: true
spam-action: mark-as-spam # Either 'block', 'none' or 'mark-as-spam'
# Global templates used for rendering forms and emails.
#
# You can find assorted templates to copy and modify in the templates/
# directory. Simply copy them to a directory of your choosing in your theme
# and set the template you want to override.
#
# More information on available template overrides can be found in the
# Templates section of docs.
#
# NOTE: All paths are relative of your running theme.
#
# e.g. You created your templates in the `extensions/boltforms/` directory
# inside your theme, you would use similar to:
#
# You can replace twig namespace @boltforms with @theme which will point to your active theme folder
# The namespace is configured in config/packages/twig.yaml
templates:
form: '@boltforms/form.html.twig'
email: '@boltforms/email_table.html.twig' # Replace with @boltforms/email.html.twig to send simple list-based emails.
subject: '@boltforms/subject.html.twig'
files: '@boltforms/file_browser.twig'
# If the default templates are used, customise the layout, or see all options here:
# https://symfony.com/doc/current/form/form_themes.html#symfony-builtin-forms
# Note that when using 'form_div_layout.html.twig', checkboxes and radio-buttons
# do not show labels by default.
layout:
form: 'bootstrap_5_layout.html.twig'
bootstrap: true # if set to `true`, Bootstrap's CSS will automatically be included from CDN
## Example 1
#
# Contact Form
contact:
notification:
enabled: true
subject: 'Brewery Quote- {name}'
subject_prefix: '[Palladium Form]'
replyto_name: '{NAME}' # Email addresses and names can be either the
replyto_email: '{EMAIL}' # name of a field below or valid text.
to_name: 'Palladium'
to_email: '[email protected]'
from_name: 'PalladiumInsurance'
from_email: '[email protected]'
feedback:
success: 'Form submitted'
error: 'Please check your fields and resubmit'
redirect:
target: /page/thank-you
query: [ name, email ]
database:
contenttype:
name: brewery_forms
ignore_missing: true
fields:
Name: *name
Email: *email
Phone: *phone
TradeName:
type: text
options:
required: true
label: Operating/Trade Name
attr:
placeholder: Doe Brewery
constraints: [ NotBlank, { Length: { 'min': 3, 'max': 40 } } ]
Address: *address
City: *city
Province: *province
PostalCode: *postal
EquipmentLimit:
type: text
options:
label: Equipment Limit
StockLimit:
type: text
options:
label: Stock Limit
GeneralLimit:
type: text
options:
label: 'General Contents Limit (including: leasehold improvements, packaging, swag, other)'
FoodPrep:
<<: *true_false
options:
<<: *true_false.options
label: Is there any food preparation done on premises?
Entertainment:
<<: *true_false
options:
<<: *true_false.options
label: Any entertainment on premises?
GrossAnnualSales:
type: text
options:
label: Estimated Gross Annual Sales
attr:
placeholder: 220,000
class: money
constraints: [ NotBlank, { Length: { 'min': 2, 'max': 20 } } ]
GrossAnnualSalesTap:
type: text
options:
label: Of your gross annual sales, please estimate how much is from your taproom.
attr:
placeholder: 120,000
class: money
constraints: [ NotBlank, { Length: { 'min': 2, 'max': 20 } } ]
EmployeesCount:
type: integer
options:
required: true
label: Number of employees (excluding owners)
constraints: [ PositiveOrZero ]
SeatingCapacity:
type: integer
options:
required: true
label: Seating capacity inside the brewery "tap‑room"
constraints: [ PositiveOrZero ]
ToursMonthly:
type: integer
options:
required: true
label: Approximate number of brewery tours conducted monthly
constraints: [ PositiveOrZero ]
DeliveryVehicles:
type: integer
options:
required: true
label: How many vehicles used for deliveries?
constraints: [ PositiveOrZero ]
recaptcha:
type: captcha
options:
captcha_type: recaptcha_v2
row_attr:
class: full-row captcha
submit:
type: submit
options:
label: Submit my message
attr:
class: button primary
row_attr:
class: full-row |
@nestordedios
This is exactly the behaviour I've attempted to get around. Anything in the global_aliases (which gets placed near the top of the bolt-boltforms.yaml, not the bolt-boltforms-global.yaml anymore) is shared across files. Namely, anything is config/extensions/bolt-boltforms/ ie: Those all have aliases shared across the forms. This allows you to have all the advantages of aliases with the code separation of multiple files (especially important since the yaml for forms get HUGE in bolt if you are doing anything complex). Hopefully that clears up what I've done. |
Hi @Halopend , Thank you! Your explanation is clear, I think It's me not knowing what I'm doing 😅. I might be missing something while trying to test it. Could you share a working example and how I could make it work? We definitely should not forget to document this once it's merged. |
@nestordedios I've only built 1 project in bolt so far, so I don't have a completely clean build starting point. I'm still figuring out the deployment system but I'll get you a simple setup to test on/see the benefits and how it works. |
Does anyone have a good starting setup with forms loaded in ready to go? Doesn't need to be perfect, just not loaded in with client (assuming that's an issue). |
@nestordedios Hopefully this helps. |
Hi @Halopend !! First of all, thank you a lot for taking the time to write back and even to make a great short video giving your explanation. I much appreciate it. I now have a better overview how things are set up on your end but I'm still having problems to make it work on my end. I'll tell you how I have it setup on my end. I have a global_aliases:
name: &name
type: text
options:
required: true
label: Your Full Name
attr:
placeholder: John Doe
constraints: [ NotBlank, { Length: { 'min': 3, 'max': 128 } } ]
website: &website
type: text
options:
required: true
label: Website
attr:
placeholder: www.examplesite.com
constraints: [ NotBlank, { Length: { 'min': 3, 'max': 40 } } ] And in test:
notification:
enabled: true
debug: false
debug_address: [email protected] # Email address used when debug mode is enabled
debug_smtp: false
subject: Test form
replyto_name: 'Test name' # Email addresses and names can be either the
replyto_email: '[email protected]' # name of a field below or valid text.
to_name: 'Test'
to_email: '[email protected]'
from_name: 'Test'
from_email: '[email protected]'
feedback:
success: Dank voor je bericht! We nemen contact met je op!
error: Er zijn fouten in het formulier, los ze op voordat u probeert opnieuw in te dienen
fields:
name: *name
website: *website When I try to render the test form in the template like {{ boltforms('test') }} I get the following error: What am I missing? Is this working for you as well or not? |
@nestordedios No worries. It's that start of some work I need to do anyway. So maybe I'm wrong, but I think your test.yaml should be: notification:
enabled: true
debug: false
debug_address: [email protected] # Email address used when debug mode is enabled
debug_smtp: false
subject: Test form
replyto_name: 'Test name' # Email addresses and names can be either the
replyto_email: '[email protected]' # name of a field below or valid text.
to_name: 'Test'
to_email: '[email protected]'
from_name: 'Test'
from_email: '[email protected]'
feedback:
success: Dank voor je bericht! We nemen contact met je op!
error: Er zijn fouten in het formulier, los ze op voordat u probeert opnieuw in te dienen
fields:
name: *name
website: *website I seems to remember being confused by this too when moving sub-forms from Note I'm using spaces rather than tabs here, but just make sure your consistent between the different files. |
Hi @Halopend , Unfortunately that did not work for me either. We are willing to get this PR merged because it looks like a nice feature, but before that we need to be sure this is working properly and how it can be configure so it works. |
@nestordedios Looks like you are using a modified code base starting point. If you use: "require": {
"bolt/forms": "dev-master",
}
"repositories": [
{
"type": "git",
"url": "https://github.com/Halopend/forms.git"
}
], See |
@Halopend I don't know on what you base that my code base is not the one you are using but I'm literally pulling the code base you have pushed to this Pull Request. Do I need to be pulling code from somewhere else instead to test? |
See: Line 43 in 460d2c6
It's clear by the commenting out on the image you posted your FormBuilder doesn't line up with either my code or the official base. Maybe something your were testing/messing with to add your recent features, or possibly trying to root out an actual issue you were having. Anyway, I clearly need to sync recent commits to my version of forms to make sure none of the new changes you've brought it break the functionality of what I've done, though I suspect it will go smoothly. |
To use, add a bolt-boltforms-global.yaml file to same loacation as bolt-boltforms.yaml, with a global aliases inside.
… currently is just the first letter of the key).
Hi @Halopend , Apologies for not replying earlier to your previous comment. Yes, the source code is different because I locally merge your branch to test if things are working. Although the source code is not the same, at the point it breaks your source code and mine are identical. I don't think that is the main reason of things not working on my end. It's nice to see some new commits are coming in. Let me know when it's ready to be tested again 👍 |
To use, add a bolt-boltforms-global.yaml file to same loacation as bolt-boltforms.yaml, with a global aliases inside.
An example bolt-boltforms-global.yaml: