Added support for CMS Pages (Editor) October 2.
The following field types are supported:
- text
- checkbox
- mediafinder
You can also use Inspector Data schema configuration for more flexible fields configuration.
https://octobercms.com/docs/ui/inspector
Using fields:
{{viewBag.myfield}} {{viewBag.test}}
This plugin add custom fields to CMS Pages, RainLab.Blog posts and Rainlab.User
Available field types: text, textarea, checkbox, number, codeeditor, colorpicker, datepicker, taglist, markdown, richeditor, mediafinder
In this video, instructions for the outdated first version of October
Table of Contents
- Rainlab Blog Custom Fields
- Cms Page Custom Fields
- User Custom Fields
- API
- Custom registration form fields
- Yaml fields
1) Rainlab Blog Custom Fields
Video manual
Creating group fields
Go to Custom Fields Create group our cusom field Set Tab caption and target type page
Adding new fields.
Go to the blog post page and make sure that our fields are available.
Using fields
post.getField($name) - get field by name
{{ post.getField('name')}} {{ post.getField('customcolor')}} {{ post.getField('image') | media }} <img src="{{ post.getField('image') | media }}" />
post.getRepeatField - get repeated field by name
{% for item in post.getRepeatField('items') %} <p>{{ item.item }}</p> {% endfor %}
2) Cms Page Custom Fields
October 2
The following field types are supported:
- text
- checkbox
- mediafinder
You can also use Inspector Data schema configuration for more flexible fields configuration.
https://octobercms.com/docs/ui/inspector
Using fields:
{{viewBag.myfield}} {{viewBag.test}}
October 1
Video manual
Creating group fields
- Go to Custom Fields.
- Create group our cusom field.
- Set Tab caption and target type page.
- Adding new fields.
- Go to the CMS page and make sure that our fields are available.
Using fields
Simple {{ viewBag.group_fields_name[0].field_name }} where "firstfields" name of field
{{ viewBag.data[0].richtext | raw }} {{ viewBag.data[0].myitem | raw }} <img src="{{ viewBag.data[0].image | media }} " > {% for items in viewBag.items %} <p style="color:{{ items.itemcolor }}; font-weight: bold;" >{{ items.item }}</p> {% endfor %}
3) User Custom Fields
Using user custom fields
//get custom fields data on frontend {{ user.getField('first') }} {{ user.getField('second') }} //save custom fields data on frontend //param1 - group field name, param2 - fields data array $user->setField('usercustomfields', [[ "first" => input('first'), "second" => input('second'), "photo" => input('photo'), ]] ); //get repeated custom fields data on frontend {% for item in user.getRepeatField('items') %} <p>{{ item.item }}</p> {% endfor %}
Creating group fields
- Go to Custom Fields.
- Create group our cusom field.
- Set Tab caption and target type page.
- Adding new fields.
Add the custom fields
https://i.ibb.co/pbTCf7z/Manual.png
Add the user.htm Page
title = "user" url = "/user" layout = "default" is_hidden = 0 robot_index = "index" robot_follow = "follow" [session] security = "all" [account] paramCode = "code" forceSecure = 0 requirePassword = 0 == <?php use RainLab\User\Models\User as UserModel; function onSave() { $data = post(); $rules = [ 'name' => 'required', 'email' => 'required|email', 'password' => 'confirmed|min:8', ]; $validation = Validator::make($data, $rules); if ($validation->fails()) { throw new ValidationException($validation); } $id = input('id'); $user = UserModel::where('id', $id)->first(); $user->fill($data); if (Request::hasFile('photo')) { $mediafilename = '/media/avatars/' . $user->name . '/' . Request::file('photo')->getClientOriginalName(); $filename = 'avatars/' . $user->name . '/' . Request::file('photo')->getClientOriginalName(); Storage::put($mediafilename, file_get_contents(Request::file('photo')->getRealPath())); $user->setField('usercustomfields', [[ "first" => input('first'), "second" => input('second'), "photo" => $filename, ]]); } else { $user->setField('usercustomfields', [[ "first" => input('first'), "second" => input('second'), "photo" => input('notchangephoto'), ]]); } $user->save(); Flash::success('Successfully saved!'); if (array_key_exists('password', $data) && strlen($data['password'])) { Auth::login($user->reload(), true); } } ?> == <section id="demo" class="section demos bg-gray"> <div class="container"> <div class="row"> <div class="col-sm-12 text-center section-title"> <br> {% if not user %} {% component 'account' %} {% endif %} {% if user %} <div id="customfields"> {% partial 'user' %} </div> <p>Hello {{ user.name }}</p> <a data-request="onLogout" data-request-data="redirect: '/user'">Sign out</a> {% else %} <p>Nobody is logged in</p> {% endif %} </div> </div> </div> </section>
Add the user.htm Partial
[session] security = "all" == <form class="" data-request="onSave" data-request-flash data-request-files data-request-validate data-request-update="user: '#customfields'"> <input name="id" type="text" id="accountName" value="{{ user.id }}" hidden> <div class="form-group"> <label for="accountName">Full Name</label> <input name="name" type="text" class="form-control" id="accountName" value="{{ user.name }}"> <span data-validate-for="name"></span> </div> <div class="form-group"> <label for="accountEmail">Email</label> <input name="email" type="email" class="form-control" id="accountEmail" value="{{ user.email }}"> <span data-validate-for="email"></span> </div> <div class="form-group"> <label for="accountPassword">New Password</label> <input name="password" type="password" class="form-control" id="accountPassword"> <span data-validate-for="password"></span> </div> <div class="form-group"> <label for="accountPasswordConfirm">Confirm New Password</label> <input name="password_confirmation" type="password" class="form-control" id="accountPasswordConfirm"> <span data-validate-for="password_confirmation"></span> </div> <div class="form-group"> <label for="accountName">First test field</label> <input name="first" type="text" class="form-control" id="accountName" value="{{ user.getField('first') }}"> <span data-validate-for="first"></span> </div> <div class="form-group"> <label for="accountName">Second test field</label> <input name="second" type="text" class="form-control" id="accountName" value="{{ user.getField('second') }}"> <span data-validate-for="second"></span> </div> <div class="form-group"> <label for="accountName">Photo</label> <input type="file" name="photo" class="form-control" accept="image/*" > </div> <div class="form-group"> {% if user.getField('photo') %} <img style="width: 200px; height: : 100%" src="{{ user.getField('photo') | media }}"> {% endif %} </div> <input name="notchangephoto" type="text" value="{{ user.getField('photo') }}" hidden> <div class="form-group"> <button type="submit" class="btn btn-default">Save</button> </div> </form>
How to output and save a repeating custom field. And also how to add and remove fields in the repeater on the frontend.
Page user.htm
title = "user" url = "/user" layout = "default" is_hidden = 0 robot_index = "index" robot_follow = "follow" [session] security = "all" [account] paramCode = "code" forceSecure = 0 requirePassword = 0 == <?php use RainLab\User\Models\User as UserModel; function onSave() { $data = post(); $rules = [ 'name' => 'required', 'email' => 'required|email', 'password' => 'confirmed|min:8', ]; $validation = Validator::make($data, $rules); if ($validation->fails()) { throw new ValidationException($validation); } $id = input('id'); $user = UserModel::where('id', $id)->first(); $user->fill($data); $notescount = input('notescount'); $notes = []; for ($i = 1; $i <= $notescount; $i++) { if(input('note' . $i)){ $notes[] = ['notes' => input('note' . $i) ]; } } $user->setField('myfields', $notes); $user->save(); Flash::success('Successfully saved!'); if (array_key_exists('password', $data) && strlen($data['password'])) { Auth::login($user->reload(), true); } } ?> == <section id="demo" class="section demos bg-gray"> <div class="container"> <div class="row"> <div class="col-sm-12 text-center section-title"> <br> {% if not user %} {% component 'account' %} {% endif %} {% if user %} <div id="customfields"> {% partial 'user' %} </div> <p>Hello {{ user.name }}</p> <a data-request="onLogout" data-request-data="redirect: '/user'">Sign out</a> {% else %} <p>Nobody is logged in</p> {% endif %} </div> </div> </div> </section>
Partial user.htm
[session] security = "all" == <form class="" data-request="onSave" data-request-flash data-request-files data-request-validate data-request-update="user: '#customfields'"> <input name="id" type="text" id="accountName" value="{{ user.id }}" hidden> <div class="form-group"> <label for="accountName">Full Name</label> <input name="name" type="text" class="form-control" id="accountName" value="{{ user.name }}"> <span data-validate-for="name"></span> </div> <div class="form-group"> <label for="accountEmail">Email</label> <input name="email" type="email" class="form-control" id="accountEmail" value="{{ user.email }}"> <span data-validate-for="email"></span> </div> <div class="form-group"> <label for="accountPassword">New Password</label> <input name="password" type="password" class="form-control" id="accountPassword"> <span data-validate-for="password"></span> </div> <div class="form-group"> <label for="accountPasswordConfirm">Confirm New Password</label> <input name="password_confirmation" type="password" class="form-control" id="accountPasswordConfirm"> <span data-validate-for="password_confirmation"></span> </div> <!-- notes count --> <input id="notescount" name="notescount" value="{{ user.getRepeatField('notes') | length }}" hidden> <div id="notes"> <!-- textareas --> {% for item in user.getRepeatField('notes') %} <div id="note{{loop.index}}" class="form-group"> <label>Note</label> <button type="button" class="btn btn-default" onclick="$( '#note{{loop.index}}' ).remove();">Del</button> <textarea class="form-control" name="note{{loop.index}}">{{ item.notes }}</textarea> </div> {% endfor %} </div> <script> function addnote(){ $( "#notescount" ).val(Number.parseInt($( "#notescount" ).val()) + 1); var notecount = $( "#notescount" ).val() $( "#notes" ).append( `<div id="note` + notecount + `" class="form-group"> <label>Notes</label> <button type="button" class="btn btn-default" onclick="$( '#note` + notecount + `' ).remove();">Del</button> <textarea class="form-control" name="note` + notecount + `"></textarea> </div> ` ); } </script> <div class="form-group"> <button type="button" class="btn btn-default" onclick="addnote()">Add Notes</button> </div> <div class="form-group"> <button type="submit" class="btn btn-default">Save</button> </div> </form>
4)API
Get API key
Settings->Custom Fields->API KEY
List of field groups
GET|HEAD | api/v1/fields/list
URL: GET http://oct.pkurg.ru/api/v1/fields/list?key=5d37221eed8a7
Response:
[ { "id": 3, "type": "Blog", "name": "wwwwww", "custom_fields": [ { "name": "ww", "type": "text", "caption": "ww", "comment": "wwww" } ], "caption": "New Tabwww", "created_at": "2019-07-23 06:19:23", "updated_at": "2019-07-23 06:19:23" }, { "id": 6, "type": "Blog", .................. and more
Show by field group id
GET|HEAD | api/v1/fields/{field}
URL: GET http://oct.pkurg.ru/api/v1/fields/5?key=5d37221eed8a7
Response:
{ "id": 5, "type": "Blog", "name": "files", "custom_fields": [ { "name": "mark", "type": "markdown", "caption": "My mark", "comment": "comment" } ], "caption": "Test New Tab", "created_at": "2019-07-23 07:47:48", "updated_at": "2019-07-23 07:47:48" }
Create new fields group
possible types:
- CMS Page
- Blog
- User
POST | api/v1/fields
URL: POST http://oct.pkurg.ru/api/v1/fields?key=5d37221eed8a7
Payload:
{ "type": "Blog", "name": "filwesqqq", "custom_fields": [ { "name": "mark", "type": "markdown", "caption": "My mark", "comment": "comment" } ], "caption": "Test New Tab 2" }
Response:
'ok saved'
Delete fields group
DELETE | api/v1/fields/{field}
URL: DELETE http://oct.pkurg.ru/api/v1/fields/2?key=5d37221eed8a7
Response:
'ok deleted'
5) Custom registration form fields
https://www.youtube.com/watch?v=SRTNCMlqP9Q
Adding custom fields
Adding register page - register.htm
title = "register" url = "/register" layout = "default" is_hidden = 0 [account] redirect = "home" paramCode = "code" forceSecure = 0 requirePassword = 0 [session] security = "all" == <?php use RainLab\User\Models\User as UserModel; use RainLab\User\Models\Settings as UserSettings; use Multiwebinc\Recaptcha\Validators\RecaptchaValidator; use RainLab\Translate\Models\Message; function isRegisterThrottled() { if (!UserSettings::get('use_register_throttle', false)) { return false; } return UserModel::isRegisterThrottled(Request::ip()); } function makeRedirection($intended = false) { $method = $intended ? 'intended' : 'to'; $property = trim((string) $this->components['account']->property('redirect')); // No redirect if ($property === '0') { return; } // Refresh page if ($property === '') { return Redirect::refresh(); } $redirectUrl = $this->components['account']->pageUrl($property) ?: $property; if ($redirectUrl = post('redirect', $redirectUrl)) { return Redirect::$method($redirectUrl); } } function onRegister() { try { if (!$this->components['account']->canRegister()) { throw new ApplicationException(Lang::get(/*Registrations are currently disabled.*/'rainlab.user::lang.account.registration_disabled')); } if ($this->isRegisterThrottled()) { throw new ApplicationException(Lang::get(/*Registration is throttled. Please try again later.*/'rainlab.user::lang.account.registration_throttled')); } /* * Validate input */ $data = post(); //CUSTOM FIELSD VALIDATIONS $rules = [ 'fieldone' => 'required', 'fieldtwo' => 'required', ]; $customMessages = [ 'fieldone.required' => 'Your message1', 'fieldtwo.required' => 'Your message2', ]; $validation = Validator::make($data, $rules, $customMessages); if ($validation->fails()) { throw new ValidationException($validation); } //END CUSTOM FIELSD VALIDATIONS if (!array_key_exists('password_confirmation', $data)) { $data['password_confirmation'] = post('password'); } $rules = (new UserModel)->rules; if ($this->components['account']->loginAttribute() !== UserSettings::LOGIN_USERNAME) { unset($rules['username']); } $validation = Validator::make($data, $rules); if ($validation->fails()) { throw new ValidationException($validation); } /* * Record IP address */ if ($ipAddress = Request::ip()) { $data['created_ip_address'] = $data['last_ip_address'] = $ipAddress; } /* * Register user */ Event::fire('rainlab.user.beforeRegister', [&$data]); $requireActivation = UserSettings::get('require_activation', true); $automaticActivation = UserSettings::get('activate_mode') == UserSettings::ACTIVATE_AUTO; $userActivation = UserSettings::get('activate_mode') == UserSettings::ACTIVATE_USER; $adminActivation = UserSettings::get('activate_mode') == UserSettings::ACTIVATE_ADMIN; $user = Auth::register($data, $automaticActivation); Event::fire('rainlab.user.register', [$user, $data]); /* * Activation is by the user, send the email */ if ($userActivation) { $this->components['account']->sendActivationEmail($user); Flash::success(Lang::get(/*An activation email has been sent to your email address.*/'rainlab.user::lang.account.activation_email_sent')); } /* * Activation is by the admin, show message * For automatic email on account activation RainLab.Notify plugin is needed */ if ($adminActivation) { Flash::success(Lang::get(/*You have successfully registered. Your account is not yet active and must be approved by an administrator.*/'rainlab.user::lang.account.activation_by_admin')); } /* * Automatically activated or not required, log the user in */ if ($automaticActivation || !$requireActivation) { Auth::login($user); } //SAVE CUSTOM FIELDS $user->setField('userfields', [[ "fieldone" => input('fieldone'), "fieldtwo" => input('fieldtwo'), ]]); $user->save(); /* * Redirect to the intended page after successful sign in */ if ($redirect = $this->makeRedirection(true)) { return $redirect; } } catch (Exception $ex) { if (Request::ajax()) throw $ex; else Flash::error($ex->getMessage()); } } ?> == <div class="container"> {% if canRegister %} <h3>Register</h3> {{ form_ajax('onRegister') }} <!-- CUSTOMFIELDS --> <div class="form-group"> <label for="registerName">Custom field 1</label> <input name="fieldone" type="text" class="form-control" id="registerName" placeholder="fieldone" /> </div> <div class="form-group"> <label for="registerName">Custom field 2</label> <input name="fieldtwo" type="text" class="form-control" id="registerName" placeholder="fieldtwo" /> </div> <!-- /CUSTOMFIELDS --> <div class="form-group"> <label for="registerName">Full Name</label> <input name="name" type="text" class="form-control" id="registerName" placeholder="Enter your full name" /> </div> <div class="form-group"> <label for="registerEmail">Email</label> <input name="email" type="email" class="form-control" id="registerEmail" placeholder="Enter your email" /> </div> {% if loginAttribute == "username" %} <div class="form-group"> <label for="registerUsername">Username</label> <input name="username" type="text" class="form-control" id="registerUsername" placeholder="Enter your username" /> </div> {% endif %} <div class="form-group"> <label for="registerPassword">Password</label> <input name="password" type="password" class="form-control" id="registerPassword" placeholder="Choose a password" /> </div> <button type="submit" class="btn btn-default">Register</button> {{ form_close() }} {% else %} <!-- Registration is disabled. --> {% endif %} </div>
6) Yaml fields
-
Ayrosa
Found the plugin useful on 21 Jul, 2021
That's great! A good plugin that expands the capabilities of the cms! Also, the creator reacts quickly on the support forum!
-
Tiara Digital Advertising
Found the plugin useful on 17 Feb, 2021
Amazing plugin! very useful to add additional custom fields.
-
Andrew Rhyand
Found the plugin useful on 28 Sep, 2019
The support for this plugin is amazing! Author responds and provides solutions almost instantly. Can't wait to see what features will be added in the future.
-
Vadim Volkov
Found the plugin useful on 11 Jul, 2019
This great plugin can expand your blog and CMS page in two clicks. This plugin can make a full-featured catalog from a blog. Everything works and everything is clear. Wish. Make it possible to manage the sequence of tabs.
-
2.2.6 |
Compatibility fixes for October v3.6 Mar 28, 2024 |
---|---|
2.2.5 |
yaml fields Jul 21, 2021 |
2.2.4 |
small fix Jun 18, 2021 |
2.2.3 |
Added support for custom fields for CMS Pages (Editor) October 2 Jun 01, 2021 |
2.2.2 |
User Custom fields not saved. Fix Dec 16, 2020 |
2.2.1 |
Updated table pkurg_customfields_fields Sep 25, 2020 |
2.2.0 |
Import fix Nov 25, 2019 |
2.1.91 |
Adds Blog fields and data export/import Nov 25, 2019 |
2.1.9 |
Adds Blog fields and data export/import Nov 25, 2019 |
2.1.8 |
fix Oct 17, 2019 |
2.1.7 |
small fix Oct 15, 2019 |
2.1.6 |
Updated table pkurg_customfields_fields Sep 28, 2019 |
2.1.5 |
CMS Page select fix Sep 22, 2019 |
2.1.4 |
Adds User custom fields Sep 21, 2019 |
2.1.3 |
Created table pkurg_customfields_usertabvalueorder Sep 21, 2019 |
2.1.2 |
Created table pkurg_customfields_users_data Sep 21, 2019 |
2.1.1 |
Updated table pkurg_customfields_value_data Sep 21, 2019 |
2.1.0 |
fix Sep 21, 2019 |
2.0.9 |
Updated table pkurg_customfields_fields Sep 20, 2019 |
2.0.8 |
Updated table pkurg_customfields_value_data Sep 20, 2019 |
2.0.7 |
fix Sep 20, 2019 |
2.0.6 |
Fixed permissions for settings Jul 29, 2019 |
2.0.5 |
Fix Jul 25, 2019 |
2.0.4 |
Add API Jul 23, 2019 |
2.0.3 |
Add user permissions Jul 10, 2019 |
2.0.2 |
Small update Jun 11, 2019 |
2.0.1 |
Small update Jun 11, 2019 |
2.0.0 |
Second version Jun 11, 2019 |
1.0.6 |
Created table pkurg_customfields_tabvalueorder Jun 11, 2019 |
1.0.5 |
Updated table pkurg_customfields_value_data Jun 11, 2019 |
1.0.4 |
Updated table pkurg_customfields_value_data Jun 11, 2019 |
1.0.3 |
Created table pkurg_customfields_fields Jun 09, 2019 |
1.0.2 |
Created table pkurg_customfields_value_data Jun 09, 2019 |
1.0.1 |
Initialize plugin. Jun 09, 2019 |