feat: VivesPOS landing on Winter CMS 1.2 — theme + plugin + Dockerfile
Some checks are pending
Module sub-split / Sub-split (push) Waiting to run

- Base: wintercms/winter branch 1.2 (full framework)
- Theme vivespos: Canvas 7 + Bootstrap 5 CDN, custom CSS
- Layout: deferred GTM/GA4 tracking, JSON-LD SoftwareApplication
- Partials: hero (offline-first), features, modes (offline/nube toggle),
  screenshots, pricing (3 planes), comparison, FAQ, CTA
- Plugin VivesPOS.Site with ContactForm
- Dockerfile: PHP 8.2 Apache, port 80, healthcheck
- Added winter/wn-pages, blog, sitemap, seo plugins
- Active theme set to vivespos
This commit is contained in:
2026-08-21 19:29:00 -06:00
commit 1f72193a64
3266 changed files with 531480 additions and 0 deletions

View File

@@ -0,0 +1,119 @@
<?php namespace Backend\Console;
use System\Console\BaseScaffoldCommand;
use Winter\Storm\Support\Str;
/**
* @TODO:
* - Support creating related permissions and navigation items and injecting them into the plugin
*/
class CreateController extends BaseScaffoldCommand
{
/**
* @var string|null The default command name for lazy loading.
*/
protected static $defaultName = 'create:controller';
/**
* @var string The name and signature of this command.
*/
protected $signature = 'create:controller
{plugin : The name of the plugin. <info>(eg: Winter.Blog)</info>}
{controller : The name of the controller to generate. <info>(eg: Posts)</info>}
{--stubs : Create view files for local overwrites.}
{--force : Overwrite existing files with generated files.}
{--model= : Defines the model name to use. If not provided, the singular name of the controller is used.}
{--l|layout=standard : Set the formLayout to use (standard, sidebar, fancy)}
{--uninspiring : Disable inspirational quotes}
';
/**
* @var string The console command description.
*/
protected $description = 'Creates a new controller.';
/**
* @var string The type of class being generated.
*/
protected $type = 'Controller';
/**
* @var string The argument that the generated class name comes from
*/
protected $nameFrom = 'controller';
/**
* @var bool Allows the process to continue if an existing file is detected
*/
protected bool $throwOverwriteException = false;
/**
* @var array A mapping of stub to generated file.
*/
protected $stubs = [
'scaffold/controller/config_form.stub' => 'controllers/{{lower_name}}/config_form.yaml',
'scaffold/controller/config_list.stub' => 'controllers/{{lower_name}}/config_list.yaml',
'scaffold/controller/controller.stub' => 'controllers/{{studly_name}}.php',
];
/**
* Prepare variables for stubs.
*/
protected function prepareVars(): array
{
$vars = parent::prepareVars();
$layout = $this->option('layout');
/*
* Determine the model name to use,
* either supplied or singular from the controller name.
*/
$model = $this->option('model');
if (!$model) {
$model = Str::singular($vars['name']);
}
$vars['model'] = $model;
$vars['sidebar'] = $layout === 'sidebar';
$vars['fancy'] = $layout === 'fancy';
$vars['stubs'] = $this->option('stubs');
if ($this->option('stubs')) {
$this->stubs['scaffold/controller/index.stub'] = 'controllers/{{lower_name}}/index.php';
$this->stubs['scaffold/controller/_list_toolbar.stub'] = 'controllers/{{lower_name}}/_list_toolbar.php';
$this->stubs["scaffold/controller/{$layout}/create.stub"] = 'controllers/{{lower_name}}/create.php';
$this->stubs["scaffold/controller/{$layout}/update.stub"] = 'controllers/{{lower_name}}/update.php';
$this->stubs["scaffold/controller/{$layout}/preview.stub"] = 'controllers/{{lower_name}}/preview.php';
if ($layout === 'fancy') {
$this->stubs['scaffold/controller/fancy/_toolbar.stub'] = 'controllers/{{lower_name}}/_toolbar.php';
}
}
return $vars;
}
/**
* Adds controller & model lang helpers to the vars
*/
protected function processVars($vars): array
{
$vars = parent::processVars($vars);
$vars['controller_url'] = "{$vars['plugin_url']}/{$vars['lower_name']}";
$vars['model_lang_key_short'] = "models.{$vars['lower_model']}";
$vars['model_lang_key'] = "{$vars['plugin_id']}::lang.{$vars['model_lang_key_short']}";
return $vars;
}
/**
* Gets the localization keys and values to be stored in the plugin's localization files
* Can reference $this->vars and $this->laravel->getLocale() internally
*/
protected function getLangKeys(): array
{
return [
"{$this->vars['model_lang_key_short']}.label" => $this->vars['title_singular_name'],
"{$this->vars['model_lang_key_short']}.label_plural" => $this->vars['title_plural_name'],
];
}
}

View File

@@ -0,0 +1,56 @@
<?php namespace Backend\Console;
use System\Console\BaseScaffoldCommand;
class CreateFormWidget extends BaseScaffoldCommand
{
/**
* The default command name for lazy loading.
*
* @var string|null
*/
protected static $defaultName = 'create:formwidget';
/**
* The name and signature of this command.
*
* @var string
*/
protected $signature = 'create:formwidget
{plugin : The name of the plugin. <info>(eg: Winter.Blog)</info>}
{widget : The name of the form widget to generate. <info>(eg: PostList)</info>}
{--force : Overwrite existing files with generated files.}
{--uninspiring : Disable inspirational quotes}
';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Creates a new form widget.';
/**
* The type of class being generated.
*
* @var string
*/
protected $type = 'FormWidget';
/**
* @var string The argument that the generated class name comes from
*/
protected $nameFrom = 'widget';
/**
* A mapping of stub to generated file.
*
* @var array
*/
protected $stubs = [
'scaffold/formwidget/formwidget.stub' => 'formwidgets/{{studly_name}}.php',
'scaffold/formwidget/partial.stub' => 'formwidgets/{{lower_name}}/partials/_{{lower_name}}.php',
'scaffold/formwidget/stylesheet.stub' => 'formwidgets/{{lower_name}}/assets/css/{{lower_name}}.css',
'scaffold/formwidget/javascript.stub' => 'formwidgets/{{lower_name}}/assets/js/{{lower_name}}.js',
];
}

View File

@@ -0,0 +1,54 @@
<?php namespace Backend\Console;
use System\Console\BaseScaffoldCommand;
class CreateReportWidget extends BaseScaffoldCommand
{
/**
* The default command name for lazy loading.
*
* @var string|null
*/
protected static $defaultName = 'create:reportwidget';
/**
* The name and signature of this command.
*
* @var string
*/
protected $signature = 'create:reportwidget
{plugin : The name of the plugin. <info>(eg: Winter.Blog)</info>}
{widget : The name of the report widget to generate. <info>(eg: PostViews)</info>}
{--force : Overwrite existing files with generated files.}
{--uninspiring : Disable inspirational quotes}
';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Creates a new report widget.';
/**
* The type of class being generated.
*
* @var string
*/
protected $type = 'ReportWidget';
/**
* @var string The argument that the generated class name comes from
*/
protected $nameFrom = 'widget';
/**
* A mapping of stub to generated file.
*
* @var array
*/
protected $stubs = [
'scaffold/reportwidget/reportwidget.stub' => 'reportwidgets/{{studly_name}}.php',
'scaffold/reportwidget/widget.stub' => 'reportwidgets/{{lower_name}}/partials/_{{lower_name}}.php',
];
}

View File

@@ -0,0 +1,87 @@
<?php
namespace Backend\Console;
use Backend\Models\User;
use Backend\Models\UserRole;
use Illuminate\Support\Facades\Config;
use Winter\Storm\Console\Command;
class UserCreate extends Command
{
use \Winter\Storm\Console\Traits\ConfirmsWithInput;
/**
* @var string The console command name.
*/
protected static $defaultName = 'user:create';
/**
* @var string The name and signature of this command.
*/
protected $signature = 'user:create email
{email : The email address of the user to create.}
{--password= : The password for the user.}
{--fname= : The first name of the user.}
{--lname= : The last name of the user.}
{--role= : The role to assign the user to. <info>Use the role\'s code</info>}
{--f|force : Force the operation to run and ignore production warnings and confirmation questions.}';
/**
* @var string The console command description.
*/
protected $description = 'Creates a backend user.';
/**
* Execute the console command.
*/
public function handle(): int
{
$email = $this->argument('email');
if (
Config::get('app.env', 'production') !== 'local'
&& !$this->option('force')
&& !$this->confirmWithInput("CAUTION, currently working with non-local data. Please confirm the user email address", $email)
) {
return 1;
}
if (User::where('email', $email)->exists()) {
$this->error('A user with that email already exists.');
return 1;
}
$data = [
'email' => $email,
'password' => $this->option('password') ?: $this->secret('Password'),
'first_name' => $this->option('fname') ?: $this->ask('First name', ''),
'last_name' => $this->option('lname') ?: $this->ask('Last name', ''),
'role_id' => (
UserRole::where(
'code',
$this->option('role') ?: $this->choice(
'Role',
UserRole::lists('name', 'code')
)
)->firstOrFail()
)->id,
];
$data['password_confirmation'] = $data['password'];
$user = User::create([
'first_name' => $data['first_name'],
'last_name' => $data['last_name'],
'login' => $data['email'],
'email' => $data['email'],
'role_id' => $data['role_id'],
'password' => $data['password'],
'password_confirmation' => $data['password'],
]);
$this->info("User {$user->email} created successfully with the {$role->name} role.");
return 0;
}
}

View File

@@ -0,0 +1,135 @@
<?php namespace Backend\Console;
use Backend\Models\User;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Str;
use Symfony\Component\Console\Question\Question;
use Winter\Storm\Console\Command;
/**
* Console command to change the password of a Backend user via CLI.
*
* @package winter\wn-backend-module
* @author Ben Thomson
* @author Winter CMS
*/
class WinterPasswd extends Command
{
/**
* @var string|null The default command name for lazy loading.
*/
protected static $defaultName = 'winter:passwd';
/**
* @var string The name and signature of this command.
*/
protected $signature = 'winter:passwd
{username? : The username or email of the Backend user. <info>(eg: admin or admin@example.com)</info>}
{password? : The new password to set.}
';
/**
* @var string The console command description.
*/
protected $description = 'Change the password of a Backend user.';
/**
* @var array List of commands that this command replaces (aliases)
*/
protected $replaces = [
'october:passwd',
'winter:password',
];
/**
* @var bool Was the password automatically generated?
*/
protected $generatedPassword = false;
/**
* Execute the console command.
* @return int
*/
public function handle()
{
$username = $this->argument('username')
?? $this->ask('Username to reset');
// Check that the user exists
try {
$user = User::where('login', $username)
->orWhere('email', $username)
->firstOrFail();
} catch (ModelNotFoundException $e) {
$this->error('The specified user does not exist.');
return 1;
}
$password = $this->argument('password')
?? (
$this->optionalSecret(
'Enter new password (leave blank for generated password)',
false,
false
) ?: $this->generatePassword()
);
// Change password
$user->password = $password;
$user->forceSave();
$this->info('Password successfully changed.');
if ($this->generatedPassword) {
$this->output->writeLn('Password set to <info>' . $password . '</info>');
}
return 0;
}
/**
* Return the 20 most recently updated users for autocompletion of the "username" argument
*/
public function suggestUsernameValues(): array
{
$options = [];
$users = User::orderBy('updated_at', 'desc')->limit(20)->get();
foreach ($users as $user) {
if ($user->email) {
$options[] = $user->email;
} elseif ($user->username) {
$options[] = $user->username;
}
}
return $options;
}
/**
* Prompt the user for input but hide the answer from the console.
*
* Also allows for a default to be specified.
*
* @param string $question
* @param bool $fallback
* @return string
*/
protected function optionalSecret($question, $fallback = true, $default = null)
{
$question = new Question($question, $default);
$question->setHidden(true)->setHiddenFallback($fallback);
return $this->output->askQuestion($question);
}
/**
* Generate a password and flag it as an automatically-generated password.
*
* @return string
*/
protected function generatePassword()
{
$this->generatedPassword = true;
return Str::random(22);
}
}

View File

@@ -0,0 +1,21 @@
<div data-control="toolbar">
<a
href="<?= Backend::url('{{ controller_url }}/create') ?>"
class="btn btn-primary wn-icon-plus">
<?= e(trans('backend::lang.form.create_title', ['name' => trans('{{ model_lang_key }}.label')])); ?>
</a>
<button
class="btn btn-danger wn-icon-trash-o"
disabled="disabled"
onclick="$(this).data('request-data', { checked: $('.control-list').listWidget('getChecked') })"
data-request="onDelete"
data-request-confirm="<?= e(trans('backend::lang.list.delete_selected_confirm')); ?>"
data-trigger-action="enable"
data-trigger=".control-list input[type=checkbox]"
data-trigger-condition="checked"
data-request-success="$(this).prop('disabled', 'disabled')"
data-stripe-load-indicator>
<?= e(trans('backend::lang.list.delete_selected')); ?>
</button>
</div>

View File

@@ -0,0 +1,31 @@
# ===================================
# Form Behavior Config
# ===================================
# Record name
name: '{{ model_lang_key }}.label'
# Model Form Field configuration
form: $/{{ plugin_folder }}/models/{{ lower_model }}/fields.yaml
# Model Class name
modelClass: {{ plugin_namespace }}\Models\{{ studly_model }}
# Default redirect location
defaultRedirect: {{ controller_url }}
# Create page
create:
title: backend::lang.form.create_title
redirect: {{ controller_url }}/update/:id
redirectClose: {{ controller_url }}
# Update page
update:
title: backend::lang.form.update_title
redirect: {{ controller_url }}
redirectClose: {{ controller_url }}
# Preview page
preview:
title: backend::lang.form.preview_title

View File

@@ -0,0 +1,50 @@
# ===================================
# List Behavior Config
# ===================================
# Model List Column configuration
list: $/{{ plugin_folder }}/models/{{ lower_model }}/columns.yaml
# Model Class name
modelClass: {{ plugin_namespace }}\Models\{{ studly_model }}
# List Title
title: '{{ model_lang_key }}.label_plural'
# Link URL for each record
recordUrl: {{ controller_url }}/update/:id
# Message to display if the list is empty
noRecordsMessage: backend::lang.list.no_records
# Records to display per page
recordsPerPage: 20
# Options to provide the user when selecting how many records to display per page
perPageOptions: [20, 40, 80, 100, 120]
# Display page numbers with pagination, disable to improve performance
showPageNumbers: true
# Displays the list column set up button
showSetup: true
# Displays the sorting link on each column
showSorting: true
# Default sorting column
# defaultSort:
# column: created_at
# direction: desc
# Display checkboxes next to each record
showCheckboxes: true
# Toolbar widget configuration
toolbar:
# Partial for toolbar buttons
buttons: list_toolbar
# Search widget configuration
search:
prompt: backend::lang.list.search_prompt

View File

@@ -0,0 +1,54 @@
<?php
namespace {{ plugin_namespace }}\Controllers;
use Backend\Classes\Controller;
use Backend\Facades\BackendMenu;
/**
* {{ title_name }} Backend Controller
*/
class {{ studly_name }} extends Controller
{
/**
* @var array Behaviors that are implemented by this controller.
*/
public $implement = [
\Backend\Behaviors\FormController::class,
\Backend\Behaviors\ListController::class,
];
/**
* @var array Permissions required to view this page.
*/
protected $requiredPermissions = [
'{{ lower_author }}.{{ lower_plugin }}.{{ lower_name }}.manage_all',
];
{% if sidebar %}
/**
* @var string The form layout to use. One of standard, sidebar, fancy
*/
protected $formLayout = 'sidebar';
{% if stubs %}
/**
* @var string Classes to be added to the body element
*/
public $bodyClass = 'compact-container';
{% endif -%}
{% elseif fancy %}
/**
* @var string The form layout to use. One of standard, sidebar, fancy
*/
protected $formLayout = 'fancy';
{% if stubs %}
/**
* @var string Classes to be added to the body element
*/
public $bodyClass = 'fancy-layout compact-container breadcrumb-flush breadcrumb-fancy';
{% endif -%}
{% endif -%}
}

View File

@@ -0,0 +1,95 @@
<div class="form-buttons loading-indicator-container">
<?php if ($formContext === 'create'): ?>
<!-- Create and new -->
<button
type="submit"
data-request="onSave"
data-request-data="new:1"
data-browser-validate
data-hotkey="ctrl+shift+s, cmd+shift+s"
data-load-indicator="<?= e(trans('backend::lang.form.creating')); ?>"
data-request-before-update="$el.trigger('unchange.oc.changeMonitor')"
class="btn btn-primary wn-icon-plus">
<?= e(trans('backend::lang.form.create_and_new')); ?>
</button>
<!-- Create -->
<button
type="button"
data-request="onSave"
data-browser-validate
data-hotkey="ctrl+s, cmd+s"
data-load-indicator="<?= e(trans('backend::lang.form.creating')); ?>"
data-request-before-update="$el.trigger('unchange.oc.changeMonitor')"
class="btn btn-primary wn-icon-save">
<?= e(trans('backend::lang.form.create')); ?>
</button>
<!-- Create and close -->
<button
type="button"
data-request="onSave"
data-browser-validate
data-request-data="close:1"
data-hotkey="ctrl+enter, cmd+enter"
data-load-indicator="<?= e(trans('backend::lang.form.creating')); ?>"
data-request-before-update="$el.trigger('unchange.oc.changeMonitor')"
class="btn btn-default wn-icon-check">
<?= e(trans('backend::lang.form.create_and_close')); ?>
</button>
<a class="btn btn-default wn-icon-ban" href="<?= $this->actionUrl('') ?>"><?= e(trans('backend::lang.form.cancel')); ?></a>
<?php elseif ($formContext === 'update'): ?>
<!-- Save -->
<a
href="javascript:;"
class="btn btn-primary wn-icon-save save"
data-request="onSave"
data-browser-validate
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
data-request-before-update="$el.trigger('unchange.oc.changeMonitor')"
data-request-data="redirect:0"
data-hotkey="ctrl+s, cmd+s"
>
<?= e(trans('backend::lang.form.save')) ?>
</a>
<!-- Save and Close -->
<a
href="javascript:;"
class="btn btn-primary wn-icon-check save"
data-request-before-update="$el.trigger('unchange.oc.changeMonitor')"
data-request="onSave"
data-browser-validate
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
>
<?= e(trans('backend::lang.form.save_and_close')) ?>
</a>
<?php if ($formModel->url): ?>
<!-- Preview -->
<a
href="<?= e($formModel->url) ?>"
target="_blank"
class="btn btn-primary wn-icon-crosshairs"
data-control="preview-button"
>
<?= e(trans('backend::lang.form.save_and_close')) ?>
</a>
<?php endif ?>
<a class="btn btn-default wn-icon-ban" href="<?= $this->actionUrl('') ?>"><?= e(trans('backend::lang.form.cancel')); ?></a>
<!-- Delete -->
<button
type="button"
class="btn btn-default empty wn-icon-trash-o"
data-request="onDelete"
title="<?= e(trans('backend::lang.form.delete')); ?>"
data-load-indicator="<?= e(trans('backend::lang.form.deleting')); ?>"
data-request-before-update="$el.trigger('unchange.oc.changeMonitor')"
data-request-confirm="<?= e(trans('backend::lang.form.confirm_delete')); ?>"
data-control="delete-button"
></button>
<?php endif; ?>
</div>

View File

@@ -0,0 +1,21 @@
<?php Block::put('breadcrumb') ?>
<?= $this->makeLayoutPartial('breadcrumb') ?>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<div class="layout fancy-layout">
<?= Form::open([
'id' => $this->formGetId(),
'class' => 'layout',
'data-change-monitor' => 'true',
'data-window-close-confirm' => 'true',
]) ?>
<div class="layout-row">
<?= $this->formRender() ?>
</div>
<?= Form::close() ?>
</div>
<?php else: ?>
<p class="flash-message static error"><?= e($this->fatalError) ?></p>
<p><a href="<?= Backend::url($formConfig->defaultRedirect) ?>" class="btn btn-default"><?= e(trans('backend::lang.form.return_to_list')); ?></a></p>
<?php endif ?>

View File

@@ -0,0 +1,17 @@
<?php Block::put('breadcrumb') ?>
<?= $this->makeLayoutPartial('breadcrumb') ?>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<?= Form::open([
'id' => $this->formGetId(),
'class' => 'layout',
]) ?>
<div class="layout-row form-preview">
<?= $this->formRenderPreview() ?>
</div>
<?= Form::close() ?>
<?php else: ?>
<p class="flash-message static error"><?= e($this->fatalError) ?></p>
<p><a href="<?= Backend::url($formConfig->defaultRedirect) ?>" class="btn btn-default"><?= e(trans('backend::lang.form.return_to_list')); ?></a></p>
<?php endif ?>

View File

@@ -0,0 +1,21 @@
<?php Block::put('breadcrumb') ?>
<?= $this->makeLayoutPartial('breadcrumb') ?>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<div class="layout fancy-layout">
<?= Form::open([
'id' => $this->formGetId(),
'class' => 'layout',
'data-change-monitor' => 'true',
'data-window-close-confirm' => 'true',
]) ?>
<div class="layout-row">
<?= $this->formRender() ?>
</div>
<?= Form::close() ?>
</div>
<?php else: ?>
<p class="flash-message static error"><?= e($this->fatalError) ?></p>
<p><a href="<?= Backend::url($formConfig->defaultRedirect) ?>" class="btn btn-default"><?= e(trans('backend::lang.form.return_to_list')); ?></a></p>
<?php endif ?>

View File

@@ -0,0 +1 @@
<?= $this->listRender() ?>

View File

@@ -0,0 +1,39 @@
<?php Block::put('breadcrumb') ?>
<?= $this->makeLayoutPartial('breadcrumb') ?>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<?php Block::put('form-contents') ?>
<div class="layout">
<div class="layout-row">
<?= $this->formRenderOutsideFields() ?>
<?= $this->formRenderPrimaryTabs() ?>
</div>
<div class="form-buttons">
<?= $this->formMakePartial('toolbar') ?>
</div>
</div>
<?php Block::endPut() ?>
<?php Block::put('form-sidebar') ?>
<div class="hide-tabs"><?= $this->formRenderSecondaryTabs() ?></div>
<?php Block::endPut() ?>
<?php Block::put('body') ?>
<?= Form::open([
'id' => $this->formGetId(),
'class'=>'layout stretch',
]) ?>
<?= $this->makeLayout('form-with-sidebar') ?>
<?= Form::close() ?>
<?php Block::endPut() ?>
<?php else: ?>
<div class="control-breadcrumb">
<?= Block::placeholder('breadcrumb') ?>
</div>
<div class="padded-container">
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
<p><a href="<?= Backend::url('{{ controller_url }}') ?>" class="btn btn-default"><?= e(trans('backend::lang.form.return_to_list')); ?></a></p>
</div>
<?php endif ?>

View File

@@ -0,0 +1,39 @@
<?php Block::put('breadcrumb') ?>
<?= $this->makeLayoutPartial('breadcrumb') ?>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<?php Block::put('form-contents') ?>
<div class="layout">
<div class="layout-row">
<?= $this->formRenderOutsideFields() ?>
<?= $this->formRenderPrimaryTabs() ?>
</div>
</div>
<?php Block::endPut() ?>
<?php Block::put('form-sidebar') ?>
<div class="hide-tabs"><?= $this->formRenderSecondaryTabs() ?></div>
<?php Block::endPut() ?>
<?php Block::put('body') ?>
<?= Form::open([
'id' => $this->formGetId(),
'class'=>'layout stretch',
]) ?>
<?= $this->makeLayout('form-with-sidebar') ?>
<?= Form::close() ?>
<?php Block::endPut() ?>
<?php else: ?>
<div class="control-breadcrumb">
<?= Block::placeholder('breadcrumb') ?>
</div>
<div class="padded-container">
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
<p><a href="<?= Backend::url('{{ controller_url }}') ?>" class="btn btn-default"><?= e(trans('backend::lang.form.return_to_list')); ?></a></p>
</div>
<?php endif ?>

View File

@@ -0,0 +1,38 @@
<?php Block::put('breadcrumb') ?>
<?= $this->makeLayoutPartial('breadcrumb') ?>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<?php Block::put('form-contents') ?>
<div class="layout">
<div class="layout-row">
<?= $this->formRenderOutsideFields() ?>
<?= $this->formRenderPrimaryTabs() ?>
</div>
<div class="form-buttons">
<?= $this->formMakePartial('toolbar') ?>
</div>
</div>
<?php Block::endPut() ?>
<?php Block::put('form-sidebar') ?>
<div class="hide-tabs"><?= $this->formRenderSecondaryTabs() ?></div>
<?php Block::endPut() ?>
<?php Block::put('body') ?>
<?= Form::open([
'id' => $this->formGetId(),
'class'=>'layout stretch',
]) ?>
<?= $this->makeLayout('form-with-sidebar') ?>
<?= Form::close() ?>
<?php Block::endPut() ?>
<?php else: ?>
<div class="control-breadcrumb">
<?= Block::placeholder('breadcrumb') ?>
</div>
<div class="padded-container">
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
<p><a href="<?= Backend::url('{{ controller_url }}') ?>" class="btn btn-default"><?= e(trans('backend::lang.form.return_to_list')); ?></a></p>
</div>
<?php endif ?>

View File

@@ -0,0 +1,21 @@
<?php Block::put('breadcrumb') ?>
<?= $this->makeLayoutPartial('breadcrumb') ?>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<?= Form::open([
'id' => $this->formGetId(),
'class' => 'layout'],
) ?>
<div class="layout-row">
<?= $this->formRender() ?>
</div>
<div class="form-buttons">
<?= $this->formMakePartial('toolbar') ?>
</div>
<?= Form::close() ?>
<?php else: ?>
<p class="flash-message static error"><?= e($this->fatalError) ?></p>
<p><a href="<?= Backend::url('{{ controller_url }}') ?>" class="btn btn-default"><?= e(trans('backend::lang.form.return_to_list')); ?></a></p>
<?php endif ?>

View File

@@ -0,0 +1,16 @@
<?php Block::put('breadcrumb') ?>
<?= $this->makeLayoutPartial('breadcrumb') ?>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<div class="form-preview">
<?= $this->formRenderPreview() ?>
</div>
<?php else: ?>
<p class="flash-message static error"><?= e($this->fatalError) ?></p>
<p><a href="<?= Backend::url('{{ controller_url }}') ?>" class="btn btn-default"><?= e(trans('backend::lang.form.return_to_list')); ?></a></p>
<?php endif ?>

View File

@@ -0,0 +1,20 @@
<?php Block::put('breadcrumb') ?>
<?= $this->makeLayoutPartial('breadcrumb') ?>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<?= Form::open([
'id' => $this->formGetId(),
'class' => 'layout',
]) ?>
<div class="layout-row">
<?= $this->formRender() ?>
</div>
<div class="form-buttons">
<?= $this->formMakePartial('toolbar') ?>
</div>
<?= Form::close() ?>
<?php else: ?>
<p class="flash-message static error"><?= e($this->fatalError) ?></p>
<p><a href="<?= Backend::url('{{ controller_url }}') ?>" class="btn btn-default"><?= e(trans('backend::lang.form.return_to_list')); ?></a></p>
<?php endif ?>

View File

@@ -0,0 +1,59 @@
<?php
namespace {{studly_author}}\{{studly_plugin}}\FormWidgets;
use Backend\Classes\FormWidgetBase;
/**
* {{name}} Form Widget
*/
class {{studly_name}} extends FormWidgetBase
{
/**
* @inheritDoc
*/
protected $defaultAlias = '{{lower_author}}_{{lower_plugin}}_{{snake_name}}';
/**
* @inheritDoc
*/
public function init()
{
}
/**
* @inheritDoc
*/
public function render()
{
$this->prepareVars();
return $this->makePartial('{{lower_name}}');
}
/**
* Prepares the form widget view data
*/
public function prepareVars()
{
$this->vars['name'] = $this->formField->getName();
$this->vars['value'] = $this->getLoadValue();
$this->vars['model'] = $this->model;
}
/**
* @inheritDoc
*/
public function loadAssets()
{
$this->addCss('css/{{lower_name}}.css', '{{author}}.{{plugin}}');
$this->addJs('js/{{lower_name}}.js', '{{author}}.{{plugin}}');
}
/**
* @inheritDoc
*/
public function getSaveValue($value)
{
return $value;
}
}

View File

@@ -0,0 +1,5 @@
/*
* This is a sample JavaScript file used by {{name}}
*
* You can delete this file if you want
*/

View File

@@ -0,0 +1,17 @@
<?php if ($this->previewMode): ?>
<div class="form-control">
<?= $value ?>
</div>
<?php else: ?>
<input
type="text"
id="<?= $this->getId('input') ?>"
name="<?= $name ?>"
value="<?= $value ?>"
class="form-control"
autocomplete="off" />
<?php endif ?>

View File

@@ -0,0 +1,5 @@
/*
* This is a sample StyleSheet file used by {{name}}
*
* You can delete this file if you want
*/

View File

@@ -0,0 +1,65 @@
<?php
namespace {{studly_author}}\{{studly_plugin}}\ReportWidgets;
use Backend\Classes\ReportWidgetBase;
use Exception;
/**
* {{name}} Report Widget
*/
class {{studly_name}} extends ReportWidgetBase
{
/**
* @var string The default alias to use for this widget
*/
protected $defaultAlias = '{{studly_name}}ReportWidget';
/**
* Defines the widget's properties
* @return array
*/
public function defineProperties()
{
return [
'title' => [
'title' => 'backend::lang.dashboard.widget_title_label',
'default' => '{{title_name}} Report Widget',
'type' => 'string',
'validationPattern' => '^.+$',
'validationMessage' => 'backend::lang.dashboard.widget_title_error',
],
];
}
/**
* Adds widget specific asset files. Use $this->addJs() and $this->addCss()
* to register new assets to include on the page.
* @return void
*/
protected function loadAssets()
{
}
/**
* Renders the widget's primary contents.
* @return string HTML markup supplied by this widget.
*/
public function render()
{
try {
$this->prepareVars();
} catch (Exception $ex) {
$this->vars['error'] = $ex->getMessage();
}
return $this->makePartial('{{lower_name}}');
}
/**
* Prepares the report widget view data
*/
public function prepareVars()
{
}
}

View File

@@ -0,0 +1,9 @@
<div class="report-widget">
<h3><?= e($this->property('title')) ?></h3>
<?php if (!isset($error)): ?>
<p>This is the default partial content.</p>
<?php else: ?>
<p class="flash-message static warning"><?= e($error) ?></p>
<?php endif ?>
</div>