11

Product support

Get help in the plugin support forum.

  • Added on Jun 10, 2019
  • Current version: 2.2.6
  • Platform Compatibility
    v3.x use latest
    v2.x use latest
    v1.x use latest
  • License: Regular / Extended
  • Created by

Categories

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

  1. Rainlab Blog Custom Fields
  2. Cms Page Custom Fields
  3. User Custom Fields
  4. API
  5. Custom registration form fields
  6. 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

https://pastebin.com/Sig0BJz8

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

https://pastebin.com/1mUDz1rU

[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

  • 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!

  • Found the plugin useful on 17 Feb, 2021

    Amazing plugin! very useful to add additional custom fields.

  • 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.

  • 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