3

I'm working on a project using Craft CMS for the first time, so far so good, however i'm stumped on how to do the following:

Create a button on each entry in a structure that states you have read the follow article. When you click you have read the article, it reflects on your account page that you have read the follow article(s).

Hopefully this makes sense, but it's almost like a LMS, you learn about something on the page you click you have completed the stage then move on to the next stage.

Thanks!

2

I'd add an Entries field in your User field layout called Articles Read or such. Then whenever they click that they've read a particular article, I'd add the id of article entry that they've read to that field.

I'd do that probably via a custom plugin, but you could also do it with a simple form that passes the correct data to the the actionUrl('users/save-user') UsersController

1
  • how could i go about doing this inside the template file exactly? I've tried to use the save-user action url but when it submits it says they have read every article on the page rather than just the article they clicked they read (if this makes sense). I appreciate your help so far, thank you
    – Kevin Love
    Jul 24 '18 at 4:29
1

In addition to Andrews answer just a little example how to store information for a user via custom plugin. There are many resources how to create a plugin, so [if] you wanna make a Craft 3 plugin you should read those.

You form could look like this

<form method="post" accept-charset="UTF-8">
    {{ csrfInput() }}
    <input type="hidden" name="action" value="plugin/controller/function">
    <input type="hidden" name="entryId" value="1">
    <button type="submit">Submit</button>
</form>

And your controller

public function actionSave():Response
{
    $user = Craft::$app->getUser()->getIdentity();
    if($user === null){
        // error, no user is logged in
        // handle it somehow
    }

    // check for a valid entry id
    $newId = Craft::$app->getRequest()->getBodyParam('entryId');
    if($newId === null){
        // error, no entry id provided...
    }

    // get the existing entries and add the new one to the array
    $existingIds = $user->getFieldValue('fieldHandle')->ids();
    $existingIds[] = $newId;

    // set the new value and store the element
    $user->setFieldValue('fieldHandle', $existingIds);
    if(!Craft::$app->getElements()->saveElement($user)){
        // could not save user due to validation errors, do something about it
    }

    // everything was successful, render a template or redirect or whatever you need
    return $this->renderTemplate('some/path', ['message' => 'hooooray']);
}
5
  • i created a plugin, but for some reason cannot hit that path to my controller with the function, it just tells me the page doesnt exist. any ideas?
    – Kevin Love
    Jul 24 '18 at 21:50
  • Without seeing your code? No - but that's a different question, please visit slack to get in touch or ask a new question to keep everything clean Jul 24 '18 at 22:08
  • I actually got the correct value now and the form is submitting, however i created the field for the entry, but not sure what to do next. i was a bit unclear on addin the field to the user field or the entry field.
    – Kevin Love
    Jul 24 '18 at 22:09
  • You should add the entries field to the user as @andrew.welch suggested. You can store every entry in your users. Jul 24 '18 at 22:11
  • I got exactly what i needed, however there's one more thing, on the return after the function runs, the redirect, i want to disable a button after submission that states they finished the course.
    – Kevin Love
    Jul 25 '18 at 4:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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