I wanted to build a commerce website using craft 3 cms. And I wanted to create parent registration form so each parent will have an account to use on the site. Then after they sign in I want them to be able to add their children.
Is this possible to do using craft 3 cms. The only thing I found is user registration form on the documentation.
If there is a blog of documentation to integrate this feature using craft 3 cms or is there anything I missed so far.
It depends how complex your parent - child relation will be.
The best solution would be is to write a custom plugin or module for that, with records and rules, some controllers ...etc
My solution would be the following
Allow public registration
Create two user groups:
Parent
Child
Set the default user group to Parent
Make sure the user group Parent has the permission:
Assign User Groups -> Assign users to "Child" checked
Create a field group with one field in it:
parentId > number (more precisely int)
Assign this field group to the users
Create a front-end user registration form for the parents so they can register.
And then you will need one more form for the parents, so they can register their children.For this, the parents are required to be logged in, otherwise it won't work.
You can check this with
{% if not craft.app.user.isGuest %}
{# Your child registration form #}
<input type="hidden" id="parentId" name="parentId" value="{{ craft.app.user.id }}">
{% else %}
{# The user is not logged in #}
{% endif %}
This way you can:
Differentiate Parent users from children using:
{% set userGroups = craft.app.user.identity.getGroups() %}
Get the logged in child's parent user object using:
{% set parent = craft.users().id( craft.app.user.identity.parentId ).one()%}
Get the logged in parents children
{% set children = craft.users().parentId( craft.app.user.id ).all() %}
Related
I'm creating an email template using Kentico's email marketing module. In which I have an email widget that retrieves and fills in holiday detail parameters based on some custom contact field values therefore making this dynamic for each user.
How can I pass custom contact fields in to the widgets from the recipient? The recipient object only contains set values.
Contacts for this email campaign are collected from a form submission that passes in the required values.
<div style="display:none;">
{% holidayDate = Recipient.GetValue("holidayDate"); #%}
{% holidayId = Recipient.GetValue("holidayId"); %}
{% ItineraryData = customNamespace.GetItineraryItem(holidayId, holidayDate) #%}
</div>
<h2 class="price">{% ItineraryData.GetValue("Price") #%}</div>
Something like the above is what I am trying to achieve but I can't seem to work out how to get these custom fields to use in the email widget.
Thanks,
Luke
The documentation states Recipient only has 4 available fields:
FirstName
LastName
Email
PersonaID
If you want to get custom fields, you'll have to look up the contact by the email address, first and last name in a macro.
Say I have a form named myform with an input field named myinput. By default, symfony will generate HTML widget like:
<input name="myform[myinput]" ... >
This doesn't work with my current javascripts and I need to get the following instead:
<input name="myinput" ...>
I've searched quite a bit and found 2 ways to achieve this:
return null in getBlockPrefix() method in form type class.
create the form using FormFactoryInterface::createNamed() and pass null as name.
It seems like the first method is not recommended, since it would limit the ability to customize form rendering using prefixed blocks.
The 2nd method was recommended here and here.
However both methods will change the name of the form to null and as a result symfony will generate the form like:
<form name="" ...>
This is probably because form_div_layout.html.twig looks like:
<form name="{{ name }}" ...
Which doesn't validate as HTML5.
According to this page, "this is not a bug".
I know I can override the form_start block in the template and remove the name altogether, but it seems that the form wasn't designed to be used with null names in general (hence no check for name length in the template).
So my question is: What is the recommended and HTML5 compatible way to remove input name prefixes for symfony forms?
It was a bug in form rendering. I've submitted a pull request to symfony repo which was accepted.
Until the change is released, a temporary solution would be to add this code to your form theme:
{# fix HTML5 validation of forms with null names #}
{% block form_start %}
{% set name = name|default(block_prefixes.1) %}
{{ parent() }}
{% endblock %}
Regarding PHP, I think either option is OK.
Regarding Twig, I'd go for creating a custom form theme and, optionally, apply it to all forms on the site. I think that's the Symfony way of rendering a form according to your, specific, needs (nullable form name).
I tried to create tags for my Posts as described in doc (tutorial My first website). But i need to show these tags in specific order. Is there some simple way or i just need to create own class with Orderable?
I have assumed you have gotten to this point in the docs - Tagging Posts and want to present the view of your BlogPage with the tags in a special order (eg. alphabetical). Orderable is if you want to do more complex admin interaction with InlinePanels and ordering of related models, where you are asking the page editor to order related items themselves.
The tutorial has this code for your template blog_page.html:
{% if page.tags.all.count %}
<div class="tags">
<h3>Tags</h3>
{% for tag in page.tags.all %}
<button type="button">{{ tag }}</button>
{% endfor %}
</div>
{% endif %}
To work with a custom ordering of your tags, you will need to set up a way to send your ordered tags to the template context. The easiest way to do this is to have a method added to your BlogPage model, we will call this get_ordered_tags.
class BlogPage(Page):
date = models.DateField("Post date")
# other fields...
def get_ordered_tags(self):
"""Specific ordered list of tags."""
# ordered_tags = self.tags.order_by('?') # order randomly
ordered_tags = self.tags.order_by('name') # order by tag name
return ordered_tags
Further up the page you would have seen the docs on Overriding Context, we will do something similar to add ordered_tags to our Page's context.
We can then easily make one minor change to our template, just replace:
{% for tag in page.tags.all %}
With:
{% for tag in page.get_ordered_tags %}
So instead of getting the tags in their default order, we are getting them in our specific order.
I got the solution for keeping the field data when having error here.
But my form fields are in loop so when I use
{{form.varName_ofField}} it does not work.
Please help...
You can only access the form variable within a form object. For example:
{% form 'contact' %}
available here: {{form.email}}
{% endform %}
but not here: {{form.email}}
I've got a form, with an embed form, and this embed form contains a form collection.
I can customize this collection doing :
{% block _form_refProspect_objects_widget %}
<div class="text_widget">
...
</div>
{% endblock %}
Having my form called form, the embed form called refProspect, and the collection called objects. That works, but what if I want to customize only one field ?
For example, having a field called name, none of thise works :
{% block _form_refProspect_objects_0_name_widget %}
{% block _form_refProspect_objects_name_widget %}
Is there any solution ?
Thanks !
EDIT :
At the same time I would like this customization to work on the form prototype, so I can use javascript to dynamically add some.
you can create your custom field type and add your logic to it.
a pretty good example would be How to Create a Custom Form Field Type
For example i use a custom CKEditor field type to make text fields as WYSIWYG editors. I used this bundle. You could check the source code to see how it works.