import from la bonne adresse and first refactoring for ouidade.com
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
# v0.6.0
|
||||
## 10/21/2015
|
||||
|
||||
1. [](#improved)
|
||||
* Added links to learn site for form examples
|
||||
1. [](#bugfix)
|
||||
* Fixed for missing attributes in textarea field
|
||||
* Fixed checkbox inputs
|
||||
|
||||
# v0.5.0
|
||||
## 10/15/2015
|
||||
|
||||
1. [](#new)
|
||||
* New `operation` param to allow different file saving strategies
|
||||
* Ability to add new file saving strategies
|
||||
* Now calls a `process()` method during form processing
|
||||
1. [](#improved)
|
||||
* Added server-side captcha validation and removed front-end validation
|
||||
* Allow `filename` instead of `prefix`, `format` + `extension`
|
||||
1. [](#bugfix)
|
||||
* Fixed radio inputs
|
||||
|
||||
# v0.4.0
|
||||
## 9/16/2015
|
||||
|
||||
1. [](#new)
|
||||
* PHP server-side form validation
|
||||
* Added new Google Catpcha field with front-end validation
|
||||
1. [](#improved)
|
||||
* Add defaults for forms, moved from the themes to the Form plugin
|
||||
* Store multi-line fields with line endings converted to HTML
|
||||
|
||||
# v0.3.0
|
||||
## 9/11/2015
|
||||
|
||||
1. [](#improved)
|
||||
* Refactored all the forms fields
|
||||
|
||||
# v0.2.1
|
||||
## 08/24/2015
|
||||
|
||||
1. [](#improved)
|
||||
* Translated tooltips
|
||||
|
||||
# v0.2.0
|
||||
## 08/11/2015
|
||||
|
||||
1. [](#improved)
|
||||
* Disable `enable` in admin
|
||||
|
||||
# v0.1.0
|
||||
## 08/04/2015
|
||||
|
||||
1. [](#new)
|
||||
* ChangeLog started...
|
||||
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Grav
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,31 @@
|
||||
# Grav Form Plugin
|
||||
|
||||
The **form plugin** for [Grav](http://github.com/getgrav/grav) adds the ability to create and use forms. This is currently used extensively by the **admin** and **login** plugins.
|
||||
|
||||
| IMPORTANT!!! This plugin is currently in development as is to be considered a **beta release**. As such, use this in a production environment **at your own risk!**. More features will be added in the future.
|
||||
|
||||
# Installation
|
||||
|
||||
The form plugin is easy to install with GPM.
|
||||
|
||||
```
|
||||
$ bin/gpm install form
|
||||
```
|
||||
|
||||
# Configuration
|
||||
|
||||
Simply copy the `user/plugins/forms/forms.yaml` into `user/config/plugins/forms.yaml` and make your modifications.
|
||||
|
||||
```
|
||||
enabled: true
|
||||
```
|
||||
|
||||
# How to use the Form Plugin
|
||||
|
||||
The Learn site has two pages describing how to use the Form Plugin:
|
||||
- [Forms](http://learn.getgrav.org/advanced/forms)
|
||||
- [Add a contact form](http://learn.getgrav.org/advanced/contact-form)
|
||||
|
||||
# Using email
|
||||
|
||||
Note: when using email functionality in your forms, make sure you have configured the Email plugin correctly. In particular, make sure you configured the "Email from" and "Email to" email addresses in the Email plugin with your email address
|
||||
@@ -0,0 +1,26 @@
|
||||
name: Form
|
||||
version: 0.6.0
|
||||
description: Enables the forms handling
|
||||
icon: check-square
|
||||
author:
|
||||
name: Team Grav
|
||||
email: devs@getgrav.org
|
||||
url: http://getgrav.org
|
||||
keywords: plugin, form
|
||||
homepage: https://github.com/getgrav/grav-plugin-form
|
||||
bugs: https://github.com/getgrav/grav-plugin-form/issues
|
||||
license: MIT
|
||||
|
||||
form:
|
||||
validation: strict
|
||||
fields:
|
||||
enabled:
|
||||
type: hidden
|
||||
label: Plugin status
|
||||
highlight: 1
|
||||
default: 0
|
||||
options:
|
||||
1: Enabled
|
||||
0: Disabled
|
||||
validate:
|
||||
type: bool
|
||||
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
namespace Grav\Plugin;
|
||||
|
||||
use Grav\Common\Iterator;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\GravTrait;
|
||||
use Grav\Common\Page\Page;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
|
||||
class Form extends Iterator
|
||||
{
|
||||
use GravTrait;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $values = array();
|
||||
|
||||
/**
|
||||
* @var Page $page
|
||||
*/
|
||||
protected $page;
|
||||
|
||||
/**
|
||||
* Create form for the given page.
|
||||
*
|
||||
* @param Page $page
|
||||
*/
|
||||
public function __construct(Page $page)
|
||||
{
|
||||
$this->page = $page;
|
||||
|
||||
$header = $page->header();
|
||||
$this->rules = isset($header->rules) ? $header->rules : array();
|
||||
$this->data = isset($header->data) ? $header->data : array();
|
||||
$this->items = $header->form;
|
||||
|
||||
// Set form name if not set.
|
||||
if (empty($this->items['name'])) {
|
||||
$this->items['name'] = $page->slug();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return page object for the form.
|
||||
*
|
||||
* @return Page
|
||||
*/
|
||||
public function page()
|
||||
{
|
||||
return $this->page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value of given variable (or all values).
|
||||
*
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function value($name = null)
|
||||
{
|
||||
if (!$name) {
|
||||
return $this->values;
|
||||
}
|
||||
return $this->getField($name, 'values');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value of given variable (or all values).
|
||||
*
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function setValue($name = null, $value = '')
|
||||
{
|
||||
if (!$name) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->values[$name] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset values.
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->values = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle form processing on POST action.
|
||||
*/
|
||||
public function post()
|
||||
{
|
||||
if (isset($_POST)) {
|
||||
$this->values = (array) $_POST;
|
||||
}
|
||||
|
||||
foreach($this->items['fields'] as $field) {
|
||||
if ($field['type'] == 'checkbox') {
|
||||
if (isset($this->values[$field['name']])) {
|
||||
$this->values[$field['name']] = true;
|
||||
} else {
|
||||
$this->values[$field['name']] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$process = isset($this->items['process']) ? $this->items['process'] : array();
|
||||
if (is_array($process)) {
|
||||
foreach ($process as $action => $data) {
|
||||
if (is_numeric($action)) {
|
||||
$action = \key($data);
|
||||
$data = $data[$action];
|
||||
}
|
||||
self::getGrav()->fireEvent('onFormProcessed', new Event(['form' => $this, 'action' => $action, 'params' => $data]));
|
||||
}
|
||||
} else {
|
||||
// Default action.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $scope
|
||||
* @return mixed|null
|
||||
* @internal
|
||||
*/
|
||||
protected function getField($name, $scope = 'value')
|
||||
{
|
||||
$path = explode('.', $name);
|
||||
|
||||
$current = $this->{$scope};
|
||||
foreach ($path as $field) {
|
||||
if (is_object($current) && isset($current->{$field})) {
|
||||
$current = $current->{$field};
|
||||
} elseif (is_array($current) && isset($current[$field])) {
|
||||
$current = $current[$field];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return $current;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,276 @@
|
||||
<?php
|
||||
namespace Grav\Plugin;
|
||||
|
||||
use Grav\Common\Plugin;
|
||||
use Grav\Common\Page\Page;
|
||||
use Grav\Common\Page\Pages;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Uri;
|
||||
use Grav\Common\Twig;
|
||||
use Grav\Plugin\Form;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
use RocketTheme\Toolbox\File\File;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
class FormPlugin extends Plugin
|
||||
{
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $active = false;
|
||||
|
||||
/**
|
||||
* @var Form
|
||||
*/
|
||||
protected $form;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return [
|
||||
'onPageInitialized' => ['onPageInitialized', 0],
|
||||
'onTwigTemplatePaths' => ['onTwigTemplatePaths', 0],
|
||||
'onTwigSiteVariables' => ['onTwigSiteVariables', 0],
|
||||
'onFormProcessed' => ['onFormProcessed', 0]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize form if the page has one. Also catches form processing if user posts the form.
|
||||
*/
|
||||
public function onPageInitialized()
|
||||
{
|
||||
/** @var Page $page */
|
||||
$page = $this->grav['page'];
|
||||
if (!$page) {
|
||||
return;
|
||||
}
|
||||
|
||||
$header = $page->header();
|
||||
if (isset($header->form) && is_array($header->form)) {
|
||||
$this->active = true;
|
||||
|
||||
// Create form.
|
||||
require_once __DIR__ . '/classes/form.php';
|
||||
$this->form = new Form($page);
|
||||
|
||||
// Handle posting if needed.
|
||||
if (!empty($_POST)) {
|
||||
$this->form->post();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add current directory to twig lookup paths.
|
||||
*/
|
||||
public function onTwigTemplatePaths()
|
||||
{
|
||||
$this->grav['twig']->twig_paths[] = __DIR__ . '/templates';
|
||||
}
|
||||
|
||||
/**
|
||||
* Make form accessible from twig.
|
||||
*/
|
||||
public function onTwigSiteVariables()
|
||||
{
|
||||
if (!$this->active) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->grav['twig']->twig_vars['form'] = $this->form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle form processing instructions.
|
||||
*
|
||||
* @param Event $event
|
||||
*/
|
||||
public function onFormProcessed(Event $event)
|
||||
{
|
||||
$form = $event['form'];
|
||||
$action = $event['action'];
|
||||
$params = $event['params'];
|
||||
|
||||
if (!$this->active) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$this->validate($form)) {
|
||||
/** @var Language $l */
|
||||
$l = $this->grav['language'];
|
||||
$this->form->message = $l->translate('FORM_PLUGIN.NOT_VALIDATED');
|
||||
$uri = $this->grav['uri'];
|
||||
$route = $uri->route();
|
||||
|
||||
/** @var Twig $twig */
|
||||
$twig = $this->grav['twig'];
|
||||
$twig->twig_vars['form'] = $form;
|
||||
|
||||
/** @var Pages $pages */
|
||||
$pages = $this->grav['pages'];
|
||||
$page = $pages->dispatch($route, true);
|
||||
unset($this->grav['page']);
|
||||
$this->grav['page'] = $page;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->process($form);
|
||||
|
||||
switch ($action) {
|
||||
case 'captcha':
|
||||
// Validate the captcha
|
||||
$query = http_build_query([
|
||||
'secret' => $params['recatpcha_secret'],
|
||||
'response' => $this->form->value('g-recaptcha-response')
|
||||
]);
|
||||
$url = 'https://www.google.com/recaptcha/api/siteverify?'.$query;
|
||||
$response = json_decode(file_get_contents($url), true);
|
||||
|
||||
if (!isset($response['success']) || $response['success'] !== true) {
|
||||
throw new \RuntimeException('Error validating the Captcha');
|
||||
}
|
||||
break;
|
||||
case 'message':
|
||||
$this->form->message = (string) $params;
|
||||
break;
|
||||
case 'redirect':
|
||||
$this->grav->redirect((string) $params);
|
||||
break;
|
||||
case 'reset':
|
||||
if (in_array($params, array(true, 1, '1', 'yes', 'on', 'true'), true)) {
|
||||
$this->form->reset();
|
||||
}
|
||||
break;
|
||||
case 'display':
|
||||
$route = (string) $params;
|
||||
if (!$route || $route[0] != '/') {
|
||||
/** @var Uri $uri */
|
||||
$uri = $this->grav['uri'];
|
||||
$route = $uri->route() . ($route ? '/' . $route : '');
|
||||
}
|
||||
|
||||
/** @var Twig $twig */
|
||||
$twig = $this->grav['twig'];
|
||||
$twig->twig_vars['form'] = $form;
|
||||
|
||||
/** @var Pages $pages */
|
||||
$pages = $this->grav['pages'];
|
||||
$page = $pages->dispatch($route, true);
|
||||
unset($this->grav['page']);
|
||||
$this->grav['page'] = $page;
|
||||
break;
|
||||
case 'save':
|
||||
$prefix = !empty($params['fileprefix']) ? $params['fileprefix'] : '';
|
||||
$format = !empty($params['dateformat']) ? $params['dateformat'] : 'Ymd-His-u';
|
||||
$ext = !empty($params['extension']) ? '.' . trim($params['extension'], '.') : '.txt';
|
||||
$filename = !empty($params['filename']) ? $params['filename'] : '';
|
||||
$operation = !empty($params['operation']) ? $params['operation'] : 'create';
|
||||
|
||||
if (!$filename) {
|
||||
$filename = $prefix . $this->udate($format) . $ext;
|
||||
}
|
||||
|
||||
/** @var Twig $twig */
|
||||
$twig = $this->grav['twig'];
|
||||
$vars = array(
|
||||
'form' => $this->form
|
||||
);
|
||||
|
||||
$fullFileName = DATA_DIR . $this->form->name . '/' . $filename;
|
||||
|
||||
$file = File::instance($fullFileName);
|
||||
|
||||
if ($operation == 'create') {
|
||||
$body = $twig->processString(
|
||||
!empty($params['body']) ? $params['body'] : '{% include "forms/data.txt.twig" %}',
|
||||
$vars
|
||||
);
|
||||
$file->save($body);
|
||||
} elseif ($operation == 'add') {
|
||||
$vars = $vars['form']->value();
|
||||
|
||||
foreach ($form->fields as $field) {
|
||||
if (isset($field['process']) && isset($field['process']['ignore']) && $field['process']['ignore']) {
|
||||
unset($vars[$field['name']]);
|
||||
}
|
||||
}
|
||||
|
||||
if (file_exists($fullFileName)) {
|
||||
$data = Yaml::parse($file->content());
|
||||
if (count($data) > 0) {
|
||||
array_unshift($data, $vars);
|
||||
} else {
|
||||
$data[] = $vars;
|
||||
}
|
||||
} else {
|
||||
$data[] = $vars;
|
||||
}
|
||||
|
||||
$file->save(Yaml::dump($data));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a form
|
||||
*
|
||||
* @param Form $form
|
||||
* @return bool
|
||||
*/
|
||||
protected function validate($form) {
|
||||
foreach ($form->fields as $field) {
|
||||
if (isset($field['validate']) && isset($field['validate']['required']) && $field['validate']['required']) {
|
||||
if (!$form->value($field['name'])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a form
|
||||
*
|
||||
* Currently available processing tasks:
|
||||
*
|
||||
* - fillWithCurrentDateTime
|
||||
*
|
||||
* @param Form $form
|
||||
* @return bool
|
||||
*/
|
||||
protected function process($form) {
|
||||
foreach ($form->fields as $field) {
|
||||
if (isset($field['process'])) {
|
||||
if (isset($field['process']['fillWithCurrentDateTime']) && $field['process']['fillWithCurrentDateTime']) {
|
||||
$form->setValue($field['name'], gmdate('D, d M Y H:i:s', time()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create unix timestamp for storing the data into the filesystem.
|
||||
*
|
||||
* @param string $format
|
||||
* @param int $utimestamp
|
||||
* @return string
|
||||
*/
|
||||
private function udate($format = 'u', $utimestamp = null)
|
||||
{
|
||||
if (is_null($utimestamp)) {
|
||||
$utimestamp = microtime(true);
|
||||
}
|
||||
|
||||
$timestamp = floor($utimestamp);
|
||||
$milliseconds = round(($utimestamp - $timestamp) * 1000000);
|
||||
|
||||
return date(preg_replace('`(?<!\\\\)u`', \sprintf('%06d', $milliseconds), $format), $timestamp);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
enabled: true
|
||||
@@ -0,0 +1,3 @@
|
||||
en:
|
||||
FORM_PLUGIN:
|
||||
NOT_VALIDATED: Form not validated. One or more required fields are missing.
|
||||
@@ -0,0 +1 @@
|
||||
{% extends "forms/default/data.html.twig" %}
|
||||
@@ -0,0 +1 @@
|
||||
{% extends "forms/default/data.txt.twig" %}
|
||||
@@ -0,0 +1,5 @@
|
||||
{% for field in form.fields %}
|
||||
{% block field %}
|
||||
<div>{% block field_label %}<strong>{{ field.label }}</strong>{% endblock %}: {% block field_value %}{{ string(form.value(field.name)|e) }}{% endblock %}</div>
|
||||
{% endblock %}
|
||||
{% endfor %}
|
||||
@@ -0,0 +1,3 @@
|
||||
{% for field in form.fields %}
|
||||
{{ field.name }}: {{ string(form.value(field.name)|e|nl2br)|replace({"\n":' ', "\r":' '}) }}
|
||||
{% endfor %}
|
||||
@@ -0,0 +1,18 @@
|
||||
<div class="alert">{{ form.message }}</div>
|
||||
|
||||
<form name="{{ form.name }}"
|
||||
action="{{ uri.rootUrl ~ (form.action|default(page.route)) }}"
|
||||
method="{{ form.method|upper|default('POST') }}">
|
||||
{% for field in form.fields %}
|
||||
{% set value = form.value(field.name) %}
|
||||
<div>
|
||||
{% include "forms/fields/#{field.type}/#{field.type}.html.twig" %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<div class="buttons">
|
||||
{% for button in form.buttons %}
|
||||
<button class="button" type="{{ button.type|default('submit') }}">{{ button.value|default('Submit') }}</button>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</form>
|
||||
@@ -0,0 +1,58 @@
|
||||
{% set originalValue = originalValue is defined ? originalValue : value %}
|
||||
{% set value = (value is null ? field.default : value) %}
|
||||
{# {% set vertical = field.style == 'vertical' %} #}
|
||||
{% set vertical = true %}
|
||||
|
||||
{% block field %}
|
||||
<div class="form-field {% if vertical %} vertical{% endif %}">
|
||||
{% block contents %}
|
||||
<div class="form-label{% if not vertical %} block size-1-3{% endif %}">
|
||||
<label class="inline">
|
||||
{% block label %}
|
||||
{% if field.help %}
|
||||
<span class="tooltip" data-asTooltip-position="w" title="{{ field.help|e }}">{{ field.label }}</span>
|
||||
{% else %}
|
||||
{{ field.label }}
|
||||
{% endif %}
|
||||
{{ field.validate.required in ['on', 'true', 1] ? '<span class="required">*</span>' }}
|
||||
{% endblock %}
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-data{% if not vertical %} block size-2-3{% endif %}"
|
||||
{% block global_attributes %}
|
||||
data-grav-field="{{ field.type }}"
|
||||
data-grav-disabled="{{ originalValue is null ? 'true' : 'false' }}"
|
||||
data-grav-default="{{ field.default|json_encode()|e('html_attr') }}"
|
||||
{% endblock %}
|
||||
>
|
||||
{% block group %}
|
||||
{% block input %}
|
||||
<div class="form-input-wrapper {{ field.size }}">
|
||||
<input
|
||||
{# required attribute structures #}
|
||||
name="{{ (scope ~ field.name)|fieldName }}"
|
||||
value="{{ value|join(', ') }}"
|
||||
{# input attribute structures #}
|
||||
{% block input_attributes %}
|
||||
{% if field.classes is defined %}class="{{ field.classes }}" {% endif %}
|
||||
{% if field.id is defined %}id="{{ field.id|e }}" {% endif %}
|
||||
{% if field.style is defined %}style="{{ field.style|e }}" {% endif %}
|
||||
{% if field.disabled %}disabled="disabled"{% endif %}
|
||||
{% if field.placeholder %}placeholder="{{ field.placeholder }}"{% endif %}
|
||||
{% if field.autofocus in ['on', 'true', 1] %}autofocus="autofocus"{% endif %}
|
||||
{% if field.novalidate in ['on', 'true', 1] %}novalidate="novalidate"{% endif %}
|
||||
{% if field.readonly in ['on', 'true', 1] %}readonly="readonly"{% endif %}
|
||||
{% if field.autocomplete in ['on', 'off'] %}autocomplete="{{ field.autocomplete }}"{% endif %}
|
||||
{% if field.validate.required in ['on', 'true', 1] %}required="required"{% endif %}
|
||||
{% if field.validate.pattern %}pattern="{{ field.validate.pattern }}"{% endif %}
|
||||
{% if field.validate.message %}title="{{ field.validate.message|e|tu }}"
|
||||
{% elseif field.title is defined %}title="{{ field.title|e|tu }}" {% endif %}
|
||||
{% endblock %}
|
||||
/>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,27 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block input %}
|
||||
<script src="https://www.google.com/recaptcha/api.js?onload=captchaOnloadCallback&render=explicit"
|
||||
async defer>
|
||||
</script>
|
||||
|
||||
<script>
|
||||
var captchaOnloadCallback = function captchaOnloadCallback() {
|
||||
grecaptcha.render('g-recaptcha', {
|
||||
'sitekey': "{{field.recatpcha_site_key}}",
|
||||
'callback': captchaValidatedCallback,
|
||||
'expired-callback': captchaExpiredCallback
|
||||
});
|
||||
}
|
||||
|
||||
var captchaValidatedCallback = function captchaValidatedCallback() {
|
||||
|
||||
};
|
||||
|
||||
var captchaExpiredCallback = function captchaExpiredCallback() {
|
||||
grecaptcha.reset();
|
||||
};
|
||||
</script>
|
||||
|
||||
<div class="g-recaptcha" id="g-recaptcha"></div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,29 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block label %}
|
||||
{% endblock %}
|
||||
|
||||
{% block input %}
|
||||
<div class="form-input-wrapper {{ field.size }}">
|
||||
<input
|
||||
{# required attribute structures #}
|
||||
name="{{ (scope ~ field.name)|fieldName }}"
|
||||
value="{{ value|join(', ') }}"
|
||||
type="checkbox"
|
||||
{% if value == true %} checked="checked" {% endif %}
|
||||
|
||||
{# input attribute structures #}
|
||||
{% block input_attributes %}
|
||||
{% if field.classes is defined %}class="{{ field.classes }}" {% endif %}
|
||||
{% if field.id is defined %}id="{{ field.id|e }}" {% endif %}
|
||||
{% if field.style is defined %}style="{{ field.style|e }}" {% endif %}
|
||||
{% if field.disabled %}disabled="disabled"{% endif %}
|
||||
{% if field.autofocus in ['on', 'true', 1] %}autofocus="autofocus"{% endif %}
|
||||
{% if field.novalidate in ['on', 'true', 1] %}novalidate="novalidate"{% endif %}
|
||||
{% if field.validate.required in ['on', 'true', 1] %}required="required"{% endif %}
|
||||
{% endblock %}
|
||||
/>
|
||||
|
||||
<label class="inline">{{ field.label|e }} {{ field.validate.required in ['on', 'true', 1] ? '<span class="required">*</span>' }}</label>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,11 @@
|
||||
field:
|
||||
checkbox:
|
||||
node: boolean
|
||||
key: name
|
||||
fields:
|
||||
name:
|
||||
type: text
|
||||
validation:
|
||||
required: true
|
||||
value:
|
||||
type: text
|
||||
@@ -0,0 +1,34 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% set originalValue = value %}
|
||||
{% set value = (value is null ? field.default : value) %}
|
||||
{% if field.use == 'keys' and field.default %}
|
||||
{% set value = field.default|merge(value) %}
|
||||
{% endif %}
|
||||
|
||||
{% block global_attributes %}
|
||||
{{ parent() }}
|
||||
data-grav-keys="{{ field.use == 'keys' ? 'true' : 'false' }}"
|
||||
data-grav-field-name="{{ field.name|fieldName }}"
|
||||
{% endblock %}
|
||||
|
||||
{% block input %}
|
||||
{% for key, text in field.options %}
|
||||
|
||||
{% set id = field.id|default(field.name) ~ '-' ~ key %}
|
||||
{% set name = field.use == 'keys' ? key : id %}
|
||||
{% set val = field.use == 'keys' ? '1' : key %}
|
||||
{% set checked = (field.use == 'keys' ? value[key] : key in value) %}
|
||||
|
||||
<span class="checkboxes">
|
||||
<input type="checkbox"
|
||||
id="{{ id|e }}"
|
||||
value="{{ val|e }}"
|
||||
name="{{ field.name|fieldName ~ '[' ~ name ~ ']' }}"
|
||||
{% if checked %}checked="checked"{% endif %}
|
||||
{% if field.validate.required %}required="required"{% endif %}
|
||||
>
|
||||
<label style="display: inline" for="{{ id|e }}">{{ text|e }}</label>
|
||||
</span>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,8 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block input_attributes %}
|
||||
type="date"
|
||||
{% if field.validate.min %}min="{{ field.validate.min }}"{% endif %}
|
||||
{% if field.validate.max %}max="{{ field.validate.max }}"{% endif %}
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,18 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% set default_php_dateformat = "d-m-Y H:i" %}
|
||||
{% set php_dateformat = config.system.pages.dateformat.default ?: default_php_dateformat %}
|
||||
{% set js_dateformat = admin.dateformat2Kendo(php_dateformat) %}
|
||||
{% set value = (value is null ? field.default : value) %}
|
||||
{% set value = (value is null ? value : value|date(php_dateformat)) %}
|
||||
|
||||
|
||||
{% block input_attributes %}
|
||||
type="text"
|
||||
data-grav-field-datetime
|
||||
data-date-formats="{{ {'format': js_dateformat} | json_encode | e('html_attr') }}"
|
||||
{% if field.validate.min %}min="{{ (field.validate.min is null ? field.validate.min : field.validate.min|date(php_dateformat)) }}"{% endif %}
|
||||
{% if field.validate.max %}max="{{ (field.validate.max is null ? field.validate.max : field.validate.max|date(php_dateformat)) }}"{% endif %}
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block input %}
|
||||
<div class="form-display-wrapper {{ field.size }}">
|
||||
{% if field.markdown %}
|
||||
{{ field.content|markdown }}
|
||||
{% else %}
|
||||
{{ field.content }}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,6 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block input_attributes %}
|
||||
type="email"
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,3 @@
|
||||
{% set value = (value is null ? field.default : value) %}
|
||||
|
||||
<input data-grav-field="hidden" data-grav-disabled="false" type="hidden" class="input" name="{{ (scope ~ field.name)|fieldName }}" value="{{ value|join(', ') }}" />
|
||||
@@ -0,0 +1,7 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block input_attributes %}
|
||||
type="password"
|
||||
class="input"
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,21 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% set originalValue = value %}
|
||||
{% set value = (value is null ? field.default : value) %}
|
||||
|
||||
{% block input %}
|
||||
{% for key, text in field.options %}
|
||||
{% set id = field.id|default(field.name) ~ '-' ~ key %}
|
||||
|
||||
<span class="radio">
|
||||
<input type="radio"
|
||||
value="{{ key|e }}"
|
||||
id="{{ id|e }}"
|
||||
name="{{ field.name|fieldName }}"
|
||||
{% if key == value %}checked="checked" {% endif %}
|
||||
{% if field.validate.required in ['on', 'true', 1] %}required="required"{% endif %}
|
||||
/>
|
||||
<label style="display: inline" for="{{ id|e }}">{{ text|e }}</label>
|
||||
</span>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,22 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block global_attributes %}
|
||||
data-grav-selectize="{{ (field.selectize is defined ? field.selectize : {})|json_encode()|e('html_attr') }}"
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
|
||||
{% block input %}
|
||||
<div class="form-select-wrapper {{ field.size }}">
|
||||
<select class="{{ field.classes }}" name="{{ (scope ~ field.name)|fieldName ~ (field.multiple ? '[]' : '') }}"
|
||||
{% if field.autofocus in ['on', 'true', 1] %}autofocus="autofocus"{% endif %}
|
||||
{% if field.novalidate in ['on', 'true', 1] %}novalidate="novalidate"{% endif %}
|
||||
{% if field.validate.required in ['on', 'true', 1] %}required="required"{% endif %}
|
||||
{% if field.multiple in ['on', 'true', 1] %}multiple="multiple"{% endif %}
|
||||
{% if field.form %}form="{{ field.form }}"{% endif %}
|
||||
>
|
||||
{% for key, text in field.options %}
|
||||
<option {% if key == value or (field.multiple and text in value) %}selected="selected"{% endif %} value="{{ field.multiple ? text : key }}">{% if grav.twig.twig.filters['tu'] is defined %}{{ text|tu }}{% else %}{{ text|t }}{% endif %}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,13 @@
|
||||
<div class="form-spacer">
|
||||
{% if field.title %}
|
||||
<h3>{{ field.title }}</h3>
|
||||
{% endif %}
|
||||
|
||||
{% if field.text %}
|
||||
<p>{{ field.text }}</p>
|
||||
{% endif %}
|
||||
|
||||
{% if field.underline %}
|
||||
<hr />
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -0,0 +1,6 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block input_attributes %}
|
||||
type="text"
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,25 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block input %}
|
||||
<div class="form-textarea-wrapper {{ field.size }}">
|
||||
<textarea class="input" name="{{ (scope ~ field.name)|fieldName }}"
|
||||
{# required attribute structures #}
|
||||
name="{{ (scope ~ field.name)|fieldName }}"
|
||||
{# input attribute structures #}
|
||||
{% block input_attributes %}
|
||||
{% if field.classes is defined %}class="{{ field.classes }}" {% endif %}
|
||||
{% if field.id is defined %}id="{{ field.id|e }}" {% endif %}
|
||||
{% if field.style is defined %}style="{{ field.style|e }}" {% endif %}
|
||||
{% if field.disabled %}disabled="disabled"{% endif %}
|
||||
{% if field.placeholder %}placeholder="{{ field.placeholder }}"{% endif %}
|
||||
{% if field.autofocus in ['on', 'true', 1] %}autofocus="autofocus"{% endif %}
|
||||
{% if field.novalidate in ['on', 'true', 1] %}novalidate="novalidate"{% endif %}
|
||||
{% if field.readonly in ['on', 'true', 1] %}readonly="readonly"{% endif %}
|
||||
{% if field.autocomplete in ['on', 'off'] %}autocomplete="{{ field.autocomplete }}"{% endif %}
|
||||
{% if field.validate.required in ['on', 'true', 1] %}required="required"{% endif %}
|
||||
{% if field.validate.pattern %}pattern="{{ field.validate.pattern }}"{% endif %}
|
||||
{% if field.validate.message %}title="{% if grav.twig.twig.filters['tu'] is defined %}{{ field.validate.message|tu }}{% else %}{{ field.validate.message|t }}{% endif %}"{% endif %}
|
||||
{% endblock %}
|
||||
>{{ value|trim|e('html') }}</textarea>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1 @@
|
||||
{% extends "forms/default/form.html.twig" %}
|
||||
Reference in New Issue
Block a user