Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:

strategy:
matrix:
php-version: [ '8.0', '8.1', '8.2', '8.3', '8.4', '8.5' ]
php-version: [ '8.1', '8.2', '8.3', '8.4', '8.5' ]

steps:
- name: Checkout
Expand Down
15 changes: 10 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,16 @@
"require": {
"php": ">=8.0",
"latte/latte": "^3.0",
"nette/forms": "^3.0",
"nette/forms": "^3.1",
"nette/utils": "^3.0 || ^4.0"
},
"require-dev": {
"nette/application": "^3.0",
"nette/bootstrap": "^3.0",
"nette/bootstrap": "^3.1",
"nette/di": "^3.0",
"phpstan/phpstan": "~1.8",
"phpstan/phpstan-nette": "~1.0",
"phpstan/phpstan": "^2.2",
"phpstan/phpstan-deprecation-rules": "^2.0",
"phpstan/phpstan-nette": "^2.0",
"tracy/tracy": "^2.5"
},
"extra": {
Expand All @@ -42,6 +43,10 @@
"psr-4": {
"NextrasDemos\\FormsRendering\\LatteMacros\\": "examples/lattemacros/",
"NextrasDemos\\FormsRendering\\Renderers\\": "examples/renderers/"
}
},
"exclude-from-classmap": [
"examples/lattemacros/temp/",
"examples/renderers/temp/"
]
}
}
2 changes: 0 additions & 2 deletions examples/.gitignore

This file was deleted.

2 changes: 1 addition & 1 deletion examples/lattemacros/LatteMacrosPresenter.latte
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<div class="container">
<h1>Form LatteMacros rendering</h1>
<hr>
{form form class => form-horizontal}
{form form, class => form-horizontal}
<div class="form-group">
{bsLabel text class => "label-control col-sm-3" /}
<div class="col-sm-9">{bsInput text}{inputError text}</div>
Expand Down
4 changes: 2 additions & 2 deletions examples/lattemacros/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
namespace NextrasDemos\FormsRendering\LatteMacros;

use Nette\Application\Application;
use Nette\Configurator;
use Nette\Bootstrap\Configurator;

require_once __DIR__ . '/../../vendor/autoload.php';


$configurator = new Configurator;
$configurator->enableDebugger(__DIR__ . '/log');
$configurator->enableTracy(__DIR__ . '/log');
$configurator->setTempDirectory(__DIR__ . '/temp');
$configurator->addConfig(__DIR__ . '/config.neon');

Expand Down
2 changes: 2 additions & 0 deletions examples/lattemacros/log/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
2 changes: 2 additions & 0 deletions examples/lattemacros/temp/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
5 changes: 3 additions & 2 deletions examples/renderers/RenderersPresenter.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace NextrasDemos\FormsRendering\Renderers;

use Nette\Application\Attributes\Persistent;
use Nette\Application\UI\Form;
use Nette\Application\UI\Presenter;
use Nextras\FormsRendering\Renderers\Bs3FormRenderer;
Expand All @@ -14,14 +15,14 @@ class RenderersPresenter extends Presenter
{
/**
* @var string
* @persistent
*/
#[Persistent]
public $renderer = 'bs3';

/**
* @var bool
* @persistent
*/
#[Persistent]
public $showBulky = true;


Expand Down
4 changes: 2 additions & 2 deletions examples/renderers/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
namespace NextrasDemos\FormsRendering\Renderers;

use Nette\Application\Application;
use Nette\Configurator;
use Nette\Bootstrap\Configurator;

require_once __DIR__ . '/../../vendor/autoload.php';


$configurator = new Configurator;
$configurator->enableDebugger(__DIR__ . '/log');
$configurator->enableTracy(__DIR__ . '/log');
$configurator->setTempDirectory(__DIR__ . '/temp');
$configurator->addConfig(__DIR__ . '/config.neon');

Expand Down
2 changes: 2 additions & 0 deletions examples/renderers/log/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
2 changes: 2 additions & 0 deletions examples/renderers/temp/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
12 changes: 12 additions & 0 deletions phpstan.dist.neon
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
includes:
- vendor/phpstan/phpstan-deprecation-rules/rules.neon
- vendor/phpstan/phpstan-nette/extension.neon
- vendor/phpstan/phpstan-nette/rules.neon

Expand All @@ -7,3 +8,14 @@ parameters:
paths:
- src
- examples

excludePaths:
- examples/**/log/*
- examples/**/temp/*

ignoreErrors:
-
message: '#^Call to function method_exists\(\) with ''Nette\\\\Bridges\\\\FormsLatte\\\\Runtime'' and ''renderFormBegin'' will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
reportUnmatched: false
path: src/LatteTags/InputNode.php
8 changes: 5 additions & 3 deletions src/LatteTags/Bs3/Bs3InputNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,19 @@

class Bs3InputNode extends BaseInputNode
{
private const INPUT_CONTROLS = ['radio', 'checkbox', 'file', 'hidden', 'range', 'image', 'submit', 'reset'];

public static function input(Html $input, BaseControl $control, bool $isSubItem): Html
{
static $inputControls = ['radio', 'checkbox', 'file', 'hidden', 'range', 'image', 'submit', 'reset'];
$name = $input->getName();
if (
$name === 'select' ||
$name === 'textarea' ||
($name === 'input' && !in_array($input->type, $inputControls, true))
($name === 'input' && !in_array($input->type, self::INPUT_CONTROLS, true))
) {
$input->addClass('form-control');
} elseif ($name === 'input' && ($input->type === 'submit' || $input->type === 'reset')) {
} elseif ($name === 'input' && ($input->type === 'submit' || $input->type === 'reset') && is_string($input->value)) {
// is_string above is needed by PHPStan since phpstan-nette claims all properties are mixed.
$input->setName('button');
$input->addHtml($input->value);
$input->addClass('btn');
Expand Down
5 changes: 3 additions & 2 deletions src/LatteTags/InputNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

namespace Nextras\FormsRendering\LatteTags;

use Latte\Compiler\Nodes\Php\Scalar\StringNode;
use Latte\Compiler\PrintContext;
use Nette\Bridges\FormsLatte\Nodes\InputNode as NetteInputNode;
use Nette\Forms\Controls\BaseControl;
Expand All @@ -21,8 +20,10 @@ abstract class InputNode extends NetteInputNode
public function print(PrintContext $context): string
{
$class = static::class;
$hasForms33 = method_exists(\Nette\Bridges\FormsLatte\Runtime::class, 'renderFormBegin');
$input = $hasForms33 ? 'Nette\Bridges\FormsLatte\Runtime::item(%node, $this->global)' : '$this->global->forms->get(%node);';
return $context->format(
'$ʟ_input = Nette\Bridges\FormsLatte\Runtime::item(%node, $this->global);'
'$ʟ_input = ' . $input
. 'echo ' . $class . '::input($ʟ_input->'
. ($this->part ? ('getControlPart(%node)') : 'getControl()')
. ($this->attributes->items ? '->addAttributes(%2.node)' : '')
Expand Down
9 changes: 8 additions & 1 deletion src/LatteTags/LabelNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@
use Nette\Utils\Html;


/**
* These are fake properties to satisfy PHPStan, at least one of them
* should exist depending on the versions of installed dependencies.
* TODO: Drop these once we no longer support forms < 3.3.
* @property-read array<mixed> $tagRanges
* @property-read mixed $endLine
*/
abstract class LabelNode extends NetteLabelNode
{
public function print(PrintContext $context): string
Expand All @@ -34,7 +41,7 @@ public function print(PrintContext $context): string
$this->position,
$this->content,
// TODO: Drop the `endLine` support once we no longer support forms < 3.3.
property_exists($this, 'endLine') ? $this->endLine : end($this->tagRanges),
isset($this->endLine) ? $this->endLine : end($this->tagRanges),
);
}

Expand Down
6 changes: 5 additions & 1 deletion src/Renderers/Bs3FormRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,11 @@ private function controlsInit(): void
if ($control instanceof Controls\Checkbox) {
$control->getContainerPrototype()->setName('div')->appendAttribute('class', $control->getControlPrototype()->type);
} else {
$control->getItemLabelPrototype()->addClass($control->getControlPrototype()->type . '-inline');
$type = $control->getControlPrototype()->type;
// For PHPStan: Both control types initialize it to constructor in string.
\assert(is_string($type));

$control->getItemLabelPrototype()->addClass($type . '-inline');
}
}
}
Expand Down
8 changes: 6 additions & 2 deletions src/Renderers/Bs4FormRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,10 @@ private function controlsInit(): void

foreach ($this->form->getControls() as $control) {
if ($this->layout === FormLayout::INLINE && !$control instanceof Controls\Checkbox && method_exists($control, 'getLabelPrototype')) {
$control->getLabelPrototype()->addClass('my-1')->addClass('mr-2');
$labelPrototype = $control->getLabelPrototype();
\assert($labelPrototype instanceof Html); // For PHPStan

$labelPrototype->addClass('my-1')->addClass('mr-2');
}

if ($control instanceof Controls\Button) {
Expand All @@ -167,7 +170,8 @@ private function controlsInit(): void
} elseif ($control instanceof Controls\Checkbox || $control instanceof Controls\CheckboxList || $control instanceof Controls\RadioList) {
$control->getControlPrototype()->addClass('form-check-input');

$control->getSeparatorPrototype()
$wrapper = $control instanceof Controls\Checkbox ? $control->getContainerPrototype() : $control->getSeparatorPrototype();
$wrapper
->setName('div')
->appendAttribute('class', 'form-check')
->appendAttribute('class', 'form-check-inline', $this->layout == FormLayout::INLINE);
Expand Down
17 changes: 12 additions & 5 deletions src/Renderers/Bs5FormRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -158,20 +158,26 @@ private function controlsInit(): void
// The checkboxes are exception since they have their own inline class.

if (!$control instanceof Controls\Checkbox && !$control instanceof Controls\CheckboxList && !$control instanceof Controls\RadioList && method_exists($control, 'getControlPrototype')) {
$control->getControlPrototype()->addClass('d-inline-block');
$controlPrototype = $control->getControlPrototype();
\assert($controlPrototype instanceof Html); // For PHPStan

$controlPrototype->addClass('d-inline-block');

// But setting `display: inline-block` is not enough since the widgets will inherit
// `width: 100%` from `.form-control` and end up wrapped anyway.
// Let’s counter that using `width: auto`.
$control->getControlPrototype()->addClass('w-auto');
$controlPrototype->addClass('w-auto');
if ($control instanceof Controls\TextBase && $control->control->type === 'color') {
// `input[type=color]` is a special case since `width: auto` would make it squish.
$control->getControlPrototype()->addStyle('min-width', '3rem');
$controlPrototype->addStyle('min-width', '3rem');
}
}

$labelPrototype = $control->getLabelPrototype();
\assert($labelPrototype instanceof Html); // For PHPStan

// Also, we need to add some spacing between the label and the control.
$control->getLabelPrototype()->addClass('me-2');
$labelPrototype->addClass('me-2');
}

if ($control instanceof Controls\Button) {
Expand Down Expand Up @@ -204,7 +210,8 @@ private function controlsInit(): void
$control->getControlPrototype()->addClass('form-check-input');

// They also need to be individually wrapped in `div.form-check`.
$control->getSeparatorPrototype()
$wrapper = $control instanceof Controls\Checkbox ? $control->getContainerPrototype() : $control->getSeparatorPrototype();
$wrapper
->setName('div')
->appendAttribute('class', 'form-check')
// They support being displayed inline with `.form-check-inline`.
Expand Down
Loading