Last active
July 5, 2020 12:50
-
-
Save wouterj/40b2e06479c29a886160d0d919dd33a5 to your computer and use it in GitHub Desktop.
DOCtor tokenizer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
TYPE_TITLE Bootstrap 4 Form Theme | |
====================== | |
TYPE_TEXT Symfony provides several ways of integrating Bootstrap into your application. The | |
most straightforward way is to add the required | |
TYPE_LITERAL ``<link>`` | |
TYPE_TEXT and | |
TYPE_LITERAL ``<script>`` | |
TYPE_TEXT elements in your templates (usually you only include them in the main layout | |
template which other templates extend from): | |
TYPE_DIRECTIVE .. code-block:: | |
TYPE_DIRECTIVE_TEXT html+twig | |
{# templates/base.html.twig #} | |
{# beware that the blocks in your template may be named different #} | |
{% block head_css %} | |
<!-- Copy CSS from https://getbootstrap.com/docs/4.4/getting-started/introduction/#css --> | |
{% endblock %} | |
{% block head_js %} | |
<!-- Copy JavaScript from https://getbootstrap.com/docs/4.4/getting-started/introduction/#js --> | |
{% endblock %} | |
TYPE_TEXT If your application uses modern front-end practices, it's better to use | |
TYPE_ROLE :doc:`Webpack Encore </frontend>` | |
TYPE_TEXT and follow | |
TYPE_ROLE :doc:`this tutorial </frontend/encore/bootstrap>` | |
TYPE_TEXT to import Bootstrap's sources into your SCSS and JavaScript files. | |
The next step is to configure the Symfony application to use Bootstrap 4 styles | |
when rendering forms. If you want to apply them to all forms, define this | |
configuration: | |
TYPE_DIRECTIVE .. configuration-block:: | |
.. code-block:: | |
TYPE_DIRECTIVE_TEXT yaml | |
# config/packages/twig.yaml | |
twig: | |
form_themes: ['bootstrap_4_layout.html.twig'] | |
TYPE_DIRECTIVE .. code-block:: | |
TYPE_DIRECTIVE_TEXT xml | |
<!-- config/packages/twig.xml --> | |
<?xml version="1.0" encoding="UTF-8" ?> | |
<container xmlns="http://symfony.com/schema/dic/services" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xmlns:twig="http://symfony.com/schema/dic/twig" | |
xsi:schemaLocation="http://symfony.com/schema/dic/services | |
https://symfony.com/schema/dic/services/services-1.0.xsd | |
http://symfony.com/schema/dic/twig | |
https://symfony.com/schema/dic/twig/twig-1.0.xsd"> | |
<twig:config> | |
<twig:form-theme>bootstrap_4_layout.html.twig</twig:form-theme> | |
<!-- ... --> | |
</twig:config> | |
</container> | |
TYPE_DIRECTIVE .. code-block:: | |
TYPE_DIRECTIVE_TEXT php | |
// config/packages/twig.php | |
$container->loadFromExtension('twig', [ | |
'form_themes' => [ | |
'bootstrap_4_layout.html.twig', | |
], | |
// ... | |
]); | |
TYPE_TEXT If you prefer to apply the Bootstrap styles on a form to form basis, include the | |
TYPE_LITERAL ``form_theme`` | |
TYPE_TEXT tag in the templates where those forms are used: | |
TYPE_DIRECTIVE .. code-block:: | |
TYPE_DIRECTIVE_TEXT html+twig | |
{# ... #} | |
{# this tag only applies to the forms defined in this template #} | |
{% form_theme form 'bootstrap_4_layout.html.twig' %} | |
{% block body %} | |
<h1>User Sign Up:</h1> | |
{{ form(form) }} | |
{% endblock %} | |
TYPE_TITLE Error Messages | |
-------------- | |
TYPE_TEXT Form errors are rendered | |
TYPE_STRONG **inside** | |
TYPE_TEXT the | |
TYPE_LITERAL ``<label>`` | |
TYPE_TEXT element to make sure there | |
is a strong connection between the error and its | |
TYPE_LITERAL ``<input>`` | |
TYPE_TEXT , as required by the | |
TYPE_REFERENCE `WCAG 2.0 standard`_ | |
TYPE_TEXT . To achieve this, | |
TYPE_LITERAL ``form_errors()`` | |
TYPE_TEXT is called by | |
TYPE_LITERAL ``form_label()`` | |
TYPE_TEXT internally. If you call to | |
TYPE_LITERAL ``form_errors()`` | |
TYPE_TEXT in your template, | |
you'll get the error messages displayed | |
TYPE_EM *twice* | |
TYPE_TEXT . | |
TYPE_TITLE Checkboxes and Radios | |
--------------------- | |
TYPE_TEXT For a checkbox/radio field, calling | |
TYPE_LITERAL ``form_label()`` | |
TYPE_TEXT doesn't render anything. | |
Due to Bootstrap internals, the label is already rendered by | |
TYPE_LITERAL ``form_widget()`` | |
TYPE_TEXT . | |
TYPE_TITLE Accessibility | |
------------- | |
TYPE_TEXT The Bootstrap 4 framework has done a good job making it accessible for functional | |
variations like impaired vision and cognitive ability. Symfony has taken this one | |
step further to make sure the form theme complies with the | |
TYPE_REFERENCE `WCAG 2.0 standard`_ | |
TYPE_TEXT . | |
This does not mean that your entire website automatically complies with the full | |
standard, but it does mean that you have come far in your work to create a design | |
for | |
TYPE_STRONG **all** | |
TYPE_TEXT users. | |
TYPE_TITLE Custom Forms | |
------------ | |
TYPE_TEXT Bootstrap 4 has a feature called " | |
TYPE_REFERENCE `custom forms`_ | |
TYPE_TEXT ". You can enable that on your | |
Symfony Form | |
TYPE_LITERAL ``RadioType`` | |
TYPE_TEXT and | |
TYPE_LITERAL ``CheckboxType`` | |
TYPE_TEXT by adding some classes to the label: | |
TYPE_UL * | |
TYPE_TEXT For a | |
TYPE_REFERENCE `custom radio`_ | |
TYPE_TEXT , use | |
TYPE_LITERAL ``radio-custom`` | |
TYPE_TEXT ; | |
TYPE_UL * | |
TYPE_TEXT For a | |
TYPE_REFERENCE `custom checkbox`_ | |
TYPE_TEXT , use | |
TYPE_LITERAL ``checkbox-custom`` | |
TYPE_TEXT ; | |
TYPE_UL * | |
TYPE_TEXT For having a | |
TYPE_REFERENCE `switch instead of a checkbox`_ | |
TYPE_TEXT , use | |
TYPE_LITERAL ``switch-custom`` | |
TYPE_TEXT . | |
TYPE_DIRECTIVE .. code-block:: | |
TYPE_DIRECTIVE_TEXT twig | |
{{ form_row(form.myRadio, {label_attr: {class: 'radio-custom'} }) }} | |
{{ form_row(form.myCheckbox, {label_attr: {class: 'checkbox-custom'} }) }} | |
{{ form_row(form.myCheckbox, {label_attr: {class: 'switch-custom'} }) }} | |
TYPE_REFERENCE_TARGET .. _`WCAG 2.0 standard`: | |
TYPE_TEXT https://www.w3.org/TR/WCAG20/ | |
TYPE_REFERENCE_TARGET .. _`custom forms`: | |
TYPE_TEXT https://getbootstrap.com/docs/4.4/components/forms/#custom-forms | |
TYPE_REFERENCE_TARGET .. _`custom radio`: | |
TYPE_TEXT https://getbootstrap.com/docs/4.4/components/forms/#radios | |
TYPE_REFERENCE_TARGET .. _`custom checkbox`: | |
TYPE_TEXT https://getbootstrap.com/docs/4.4/components/forms/#checkboxes | |
TYPE_REFERENCE_TARGET .. _`switch instead of a checkbox`: | |
TYPE_TEXT https://getbootstrap.com/docs/4.4/components/forms/#switches | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
/* | |
* This file is part of DOCtor-RST. | |
* | |
* (c) Oskar Stark <[email protected]> | |
* | |
* For the full copyright and license information, please view the LICENSE | |
* file that was distributed with this source code. | |
*/ | |
namespace App\Rule; | |
use App\Annotations\Rule\Description; | |
use App\Handler\Registry; | |
use App\Rst\RstParser; | |
use App\Rst\Value\LinkDefinition; | |
use App\Rst\Value\LinkUsage; | |
use App\Value\Lines; | |
use App\Value\RuleGroup; | |
use Symfony\Contracts\Service\ResetInterface; | |
/** | |
* @Description("Report all links which are not used in the file anymore.") | |
*/ | |
class UnusedLinks extends AbstractRule implements Rule | |
{ | |
public static function getGroups(): array | |
{ | |
return [ | |
RuleGroup::fromString(Registry::GROUP_SONATA), | |
RuleGroup::fromString(Registry::GROUP_SYMFONY), | |
]; | |
} | |
public function check(TokenStream $tokens): ?string | |
{ | |
$referenceTargets = []; | |
$usedTargets = []; | |
// find all TYPE_REFERENCE_TARGET or TYPE_REFERENCE tokens in this token stream (I can | |
// also imagine a findSequence() to find specific sequences of tokens in the stream) | |
foreach ($tokens->findAny([Tokenizer::TYPE_REFERENCE_TARGET, Tokenizer::TYPE_REFERENCE]) as $token) { | |
// @todo we may need a value object for $token instead of a [TYPE, VALUE] tuple | |
if (Tokenizer::TYPE_REFERENCE_TARGET === $token[0]) { | |
// @todo improve tokenizing REFERENCE_TARGETS to split up in target + label | |
preg_match('/\.\.\s*_`?([^`]+)`/', $token[1], $m); | |
$referenceTargets[] = $m[1]; | |
} else { | |
preg_match('/`.+?<(.+?)>`__?|`(.+?)`__?/', $token[1], $m); | |
$usedTargets[] = $m[1] ?: $m[2]; | |
} | |
} | |
$unusedTargets = array_diff($referenceTargets, $usedTargets); | |
if (!empty($unusedTargets)) { | |
return sprintf( | |
'The following link definitions aren\'t used anymore and should be removed: %s', | |
implode(', ', array_unique($unusedTargets)) | |
); | |
} | |
return null; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment