Relating Submissions to Elements 3.2.0+ Pro

Freeform Relations become a suitable replacement for Comments, Ratings, Product Reviews, simple sign-up forms for Calendar events and more!

Overview

Freeform allows you to intuitively relate form submissions to any other Craft (or third party) Element. This is done by feeding the Craft Element ID to Freeform's relations parameter in the freeform.form function, thus allowing you to use Freeform forms to do anything such as allow users to submit comments on Craft Entries, post ratings and reviews for Entries or Commerce Products, relate submissions to Users and more!

How it Works

When pairing the Freeform Submissions element fieldtype with the relations parameter in the freeform.form function, you can automate attaching/relating of Freeform submissions to other Craft elements when the form is submitted. The submission(s) are then attached to the other element and appear visually in those elements the same way as Assets do in the control panel, and more importantly, can then be used to easily display those submissions tied to the Craft Element inside your templates.

How to Setup

See the options below for some examples to get you started quickly:

Simple Setup

Here's instructions for setting up a simple relation of Freeform submissions to Craft Entries. A common use-case might be allowing comments or reviews for a product (being a Craft Entry). Let's assume you're on a single entry page.

  1. First, create a new Craft field inside the Craft CP with a field handle of productReviews, using the Freeform Submissions field type. Then be sure to add it to the relevant Craft Entry channel/section.
  2. Now, for the templating part. To start, you might be pulling your Entry data like the following:
    <h2>{{ entry.title }}</h2>
    <p>Posted on {{ entry.postDate.format('F d, Y') }}</p>
    <p>{{ entry.description }}</p>
    
    1
    2
    3
  3. Let's add a simple form to the page template using the Freeform simple render approach now:




     

    <h2>{{ entry.title }}</h2>
    <p>Posted on {{ entry.postDate.format('F d, Y') }}</p>
    <p>{{ entry.description }}</p>
    
    {{ craft.freeform.form("productReviewsForm").render() }}
    
    1
    2
    3
    4
    5
  4. And here's the special sauce... this is where we add the relations parameter and feed it the Entry ID to allow attaching the submission to the Entry:





     
     
     


    <h2>{{ entry.title }}</h2>
    <p>Posted on {{ entry.postDate.format('F d, Y') }}</p>
    <p>{{ entry.description }}</p>
    
    {{ craft.freeform.form("productReviewsForm").render({
        relations: {
            productReviews: entry.id,
        },
    }) }}
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
  5. Submit the form, and you'll see that the Freeform submissions should now be relating to the productReviews field of the Craft Entries (can see/confirm this inside the control panel by viewing the Craft Entry).

Relating More Than One Element

Let's take the above example a little further. The following guide will show you how to relate Freeform submissions to Craft Entries and the currently logged in user. A common use-case might be allowing comments or reviews for a product (being a Craft Entry) and also tying them to the currently logged in user. Let's assume you're on a single entry page again...

  1. First, create a new Craft field inside the Craft CP with a field handle of productReviews, using the Freeform Submissions field type. Then be sure to add it to the relevant Craft Entry channel/section.
  2. Second, we'll create another Craft field with a handle of userReviews, using the Freeform Submissions field type. Then be sure to add it to the Craft Users field layout.
  3. Now, for the templating part. To start, you might be pulling your Entry data like the following:
    <h2>{{ entry.title }}</h2>
    <p>Posted on {{ entry.postDate.format('F d, Y') }}</p>
    <p>{{ entry.description }}</p>
    
    1
    2
    3
  4. Let's add a simple form to the page template using the Freeform simple render approach now:




     

    <h2>{{ entry.title }}</h2>
    <p>Posted on {{ entry.postDate.format('F d, Y') }}</p>
    <p>{{ entry.description }}</p>
    
    {{ craft.freeform.form("productReviewsForm").render() }}
    
    1
    2
    3
    4
    5
  5. And now let's relate the form submissions to both the current Craft Entry and the currently logged in User by feeding those ID's to the relations parameter:





     
     
     
     


    <h2>{{ entry.title }}</h2>
    <p>Posted on {{ entry.postDate.format('F d, Y') }}</p>
    <p>{{ entry.description }}</p>
    
    {{ craft.freeform.form("productReviewsForm").render({
        relations: {
            productReviews: entry.id,
            userReviews: currentUser.id,
        },
    }) }}
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
  6. Submit the form, and you'll see that the Freeform submissions should now be relating to the productReviews field of the Craft Entries as well as the userReviews field for the User that submitted the form.

If you'd like to display submissions that are related to any given Craft Element, you would do this by calling the Freeform Submissions field in your element, and using the ID(s) it contains to populate a freeform.submissions function.

Let's work off of the Relating More Than One Element example above. If you used the Simple Setup example, just ignore the Users part of this guide. Again, we're assuming you have a Freeform Submissions field with a handle of productReviews for Craft Entries, and another Freeform Submissions field with a handle of userReviews for Craft Users.

  1. To start, you might be pulling your Entry data like the following:
    <h2>{{ entry.title }}</h2>
    <p>Posted on {{ entry.postDate.format('F d, Y') }}</p>
    <p>{{ entry.description }}</p>
    
    1
    2
    3
  2. And with the Freeform form using the Freeform simple render approach and the relations parameter setup:




     
     
     
     
     
     

    <h2>{{ entry.title }}</h2>
    <p>Posted on {{ entry.postDate.format('F d, Y') }}</p>
    <p>{{ entry.description }}</p>
    
    {{ craft.freeform.form("productReviewsForm").render({
        relations: {
            productReviews: entry.id,
            userReviews: currentUser.id,
        },
    }) }}
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
  3. Now let's pull Freeform submissions that have been related to the Craft Entry, and also use the related User ID to populate User data about the user that submitted the review (submission):











     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     

    <h2>{{ entry.title }}</h2>
    <p>Posted on {{ entry.postDate.format('F d, Y') }}</p>
    <p>{{ entry.description }}</p>
    
    {{ craft.freeform.form("productReviewsForm").render({
        relations: {
            productReviews: entry.id,
            userReviews: currentUser.id,
        },
    }) }}
    
    {% if entry.productReviews|length %}
    
        <h3>Reviews</h3>
    
        {% set submissions = craft.freeform.submissions({
            id: entry.productReviews.ids(),
            orderBy: "dateCreated DESC",
            status: "open"
        }) %}
    
        <div class="reviews">
        {% for submission in submissions.all() %}
            <div class="review">
                <h4>{{ submission.title }}</h4>
                <p>
                    {% set relatedUser = craft.users().relatedTo(submission.id).one() %}
                    <i>Submitted by: <a href="{{ url('profiles/'~relatedUser.username) }}">{{ relatedUser.name }}</a></i>
                </p>
                <p>{{ submission.message }}</p>
            </div>
        {% endfor %}
        </div>
    
    {% endif %}
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
Last Updated: 7/11/2019, 1:16:49 AM