Catégorie : Uncategorized
[Twig] Utiliser le tag Set et la fonction Include pour récupérer les informations d’un fichier JSON dans un template Twig
Source: Set twig variable to json file as an include.
Fichier _data/test.json
:
1 |
{ "name":"John", "age":30, "car":null } |
Fichier template.twig
:
1 2 3 4 5 6 7 |
{% set json %} {% include "_data/test.json" %} {% endset %} [...] <h1>{{ json }}</h1> |
[Javascript] Récupérer la largeur ou la hauteur d’un élément sans les padding, margin, bordure et scrollbar associés avec clientHeight, offsetHeight et parseFloat
Sources:
- Get the height of an element minus padding, margin, border widths
- JavaScript DOM / Getting the Width and Height of an Element
- MDN WebDocs – element.offsetHeight
Dégageage du padding avec getComputedStyle
Faire un console.log(computedStyle);
vous donnera une liste de toutes les données récupérées via la méthode getComputedStyle
et que vous pourrez exploiter ensuite.
1 2 3 4 5 6 7 |
var computedStyle = getComputedStyle(element); elementHeight = element.clientHeight; // height with padding elementWidth = element.clientWidth; // width with padding elementHeight -= parseFloat(computedStyle.paddingTop) + parseFloat(computedStyle.paddingBottom); elementWidth -= parseFloat(computedStyle.paddingLeft) + parseFloat(computedStyle.paddingRight); |
Dans la pratique:
Je veux récupérer la hauteur du contenu de l’élément de DOM .page-leftColumn
sans le padding:
1 2 3 4 |
let $leftColumn = document.querySelector('.page-leftColumn'), computedStyle = getComputedStyle($leftColumn), leftColumnHeight = $leftColumn.clientHeight - (parseFloat(computedStyle.paddingTop) + parseFloat(computedStyle.paddingBottom)); // console.log(leftColumnHeight); |
Tenir compte de la scrollbar
Voir aussi ici pour ce bout de code modifié pour tenir compte de la scrollbar:
1 2 3 4 5 6 7 8 9 10 11 |
var cs = getComputedStyle(element); var paddingX = parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight); var paddingY = parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom); var borderX = parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth); var borderY = parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth); // Element width and height minus padding and border elementWidth = element.offsetWidth - paddingX - borderX; elementHeight = element.offsetHeight - paddingY - borderY; |
[Magento 2] Gérer l’affichage des formulaires avec les mixins LESS de la Magento UI Library
Documentation officielle: Magento UI Library – Forms mixins.
Bonnes pratiques
Si vous avez simplement l’intention de changer les valeurs des variables existantes (regardez la doc, il y en a beaucoup, vous pouvez probablement vous en tirer sans aller plus loin que ça…) faites le dans le fichier _theme.less
de votre thème.
Fields customization variables – The .lib-form-field()
mixin variables
Libellés au-dessus des champs, une colonne
1 2 3 4 5 6 7 8 9 |
& when (@media-common = true) { .fieldset { > .field { .lib-form-field( @_type: block ); } } } |
Libellés au-dessus des champs, deux colonnes
A savoir: lorsqu’on affiche le champ sur plusieurs colonnes, on peut utiliser la variable (appartenant au mixin) @_column-number
(qui répond elle-même à la variable globale @form-field-column__number
paramétrée par défaut à 2
pour modifier le nombre de colonnes sur lesquelles le formulaire va s’étaler.
1 2 3 4 5 6 7 8 9 10 |
& when (@media-common = true) { .fieldset { > .field { .lib-form-field( @_type: block, @_column: true ); } } } |
Libellés à côté des champs, une colonne
1 2 3 4 5 6 7 8 9 |
& when (@media-common = true) { .fieldset { > .field { .lib-form-field( @_type: inline ); } } } |
Libellés à côté des champs, deux colonnes
A savoir: (je me répète…) lorsqu’on affiche le champ sur plusieurs colonnes, on peut utiliser la variable (appartenant au mixin) @_column-number
(qui répond elle-même à la variable globale @form-field-column__number
paramétrée par défaut à 2
pour modifier le nombre de colonnes sur lesquelles le formulaire va s’étaler.
1 2 3 4 5 6 7 8 9 10 |
& when (@media-common = true) { .fieldset { > .field { .lib-form-field( @_type: inline, @_column: true ); } } } |
[crossbrowsertesting.com] Effectuer des tests dans un environnement local sous Linux (Ubuntu) avec la fonctionnalité Local connection
Au moment où j’écris cet article, le plug-in pour Chrome ne fonctionne pas sous Ubuntu. Il faut donc passer par l’outil packagé de connexion locale. Documentation complète ici.
Commencer par récupérer l’outil cbt_tunnel-linux-x64 en cliquant sur le lien « Latest Releases for cbt_tunnels » dans la section « Binaries » de la page « Local Connection Overview ». Au moment où j’écris ces lignes, la dernière release est le tag v1.2.2, mais vérifiez qu’il n’y ait pas eu de release plus récente depuis.
Dézippez le fichier téléchargé dans un dossier auquel vous aurez accès depuis un bash. Ouvrez un bash et placez vous à la racine du dossier qui contient le fichier cbt_tunnel-linux-x64 dézippé, puis exécutez le en tapant la commande:
1 |
$ ./cbt_tunnel-linux-x64 |
Il y a plusieurs types de connexion disponibles, mais l’outil vous demandera toujours un username et une authkey. Ces deux arguments de la commande font référence à des informations de votre compte crossbrowsertesting. Vous les trouverez sur le site, dans la page « Manage Account » sous la section « User Profile ». Le username est votre email (votre username apparaît en haut à droite de l’interface crossbrowsertesting lorsque vous êtes connecté) et l’authkey se trouve juste en-dessous de votre email sous la forme o8s9a4f2sm86w34 (fake authkey).
La commande à taper en bash pour ouvrir un tunnel de connexion local est donc un truc qui ressemble à ceci:
1 |
$ ./cbt_tunnel-linux-x64 --username moi@email.com --authkey o8s9a4f2sm86w34 |
Patientez quelques secondes… « Connected for internal websites »!
[CSS] Hauteur égale d’éléments à l’intérieur d’un grid item avec CSS Grid Layout
A Complete Guide to Grid chez CSS Tricks.
Source: Equal height of elements inside grid item with CSS grid layout, codepen et version PDF.
Pré-requis typique d’une liste de produits…
Quelques essais perso:
[Docker] Faire un dump d’une table spécifique dans une base de données et récupérer le contenu dans un fichier txt hors container
Note: pour faire la même chose, mais via mysql: Dump a specific table or few rows (MySQL). $ mysqldump -u username -ppassword database_name table_name > single_table_dump.sql
Faire un dump d’une table spécifique via un container db Docker:
Log toi dans le container db
après : $ mysqldump -uroot -proot magento core_config_data --tab="/tmp" --fields-enclosed-by='"' --fields-terminated-by=,
ce qui nous intéresse, c’est le fichier /tmp/core_config_data.txt qui sera généré. tu le copie via docker cp.
ça doit te donner un rendu qui ressemble à ça (sample):
1 |
"1","default","0","yotpo/module_info/yotpo_installation_date","2020-02-12","2020-02-28 11:06:07" |
Récupérer le contenu du dump dans un fichier TXT avec la commande docker cp
:
Sortir du container db. On se retrouve à la racine de notre projet.
1 |
$ docker cp vitalconcept_db_1:/tmp/core_config_data.txt . |
en décomposant : $ docker cp nom_du_container:path_dans_le_container path_local (. == l'endroit où tu es)
Le fichier core_config_data.txt devrait être disponible à la racine de notre projet (où à l’endroit depuis lequel la commande ci-dessus a été exécutée).
[Magento 2] Créer une page monsite.com/customer/account/activate/
Les fichiers que nous allons devoir créer (MyVendor
et MyModule
doivent commencer par une Majuscule):
- app/code/MyVendor/MyModule/Block/Activate.php
- app/code/MyVendor/MyModule/Controller/Account/Activate.php
- app/code/MyVendor/MyModule/etc/frontend/routes.xml
- app/code/MyVendor/MyModule/view/frontend/layout/customer_account_activate.xml
- app/code/MyVendor/MyModule/view/frontend/templates/activate.phtml
app/code/MyVendor/MyModule/Block/Activate.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?php /** * Copyright © 2020 MyVendor. All rights reserved. * See COPYING.txt for license details. */ namespace MyVendor\MyModule\Block; /** * MyModule activate block * * @category MyVendor * @package MyVendor_MyModule * @author MyVendor Magento Team <magento@team.fr> */ class Activate extends \Magento\Framework\View\Element\Template { } |
app/code/MyVendor/MyModule/Controller/Account/Activate.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
<?php /** * Copyright © 2020 MyVendor. All rights reserved. * See COPYING.txt for license details. */ namespace MyVendor\MyModule\Controller\Account; /** * MyModule activate view action * * @category MyVendor * @package MyVendor_MyModule * @author MyVendor Magento Team <magento@team.fr> */ class Activate extends \Magento\Framework\App\Action\Action { /** * @var \Magento\Framework\View\Result\PageFactory $resultPageFactory */ protected $resultPageFactory; /** * Summary constructor * * @param \Magento\Framework\App\Action\Context $context * @param \Magento\Framework\View\Result\PageFactory $resultPageFactory */ public function __construct( \Magento\Framework\App\Action\Context $context, \Magento\Framework\View\Result\PageFactory $resultPageFactory ) { $this->resultPageFactory = $resultPageFactory; parent::__construct( $context ); } /** * @return \Magento\Framework\Controller\Result\Redirect|\Magento\Framework\View\Result\Page */ public function execute() { /** @var \Magento\Framework\View\Result\Page $resultPage */ $resultPage = $this->resultPageFactory->create(); $resultPage->getConfig()->getTitle()->set(__('Activate my account')); return $resultPage; } } |
app/code/MyVendor/MyModule/etc/frontend/routes.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?xml version="1.0"?> <!-- /** * Copyright © 2020 MyVendor. All rights reserved. * See COPYING.txt for license details. * * @category MyVendor * @package MyVendor_MyModule * @author MyVendor Magento Team <magento@team.fr> */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd"> <router id="standard"> <route id="customer"><!-- URL qui commence par customer/ --> <module name="MyVendor_MyModule" before="Magento_Customer" /> </route> </router> </config> |
app/code/MyVendor/MyModule/view/frontend/layout/customer_account_activate.xml
1 2 3 4 5 6 7 8 9 |
<?xml version="1.0"?> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <update handle="customer_account"/> <body> <referenceContainer name="content"> <block template="MyVendor_MyModule::activate.phtml" class="MyVendor\MyModule\Block\Activate" name="customer.account.activate" cacheable="false" /> </referenceContainer> </body> </page> |
app/code/MyVendor/MyModule/view/frontend/templates/activate.phtml
1 |
<h1>activate.phtml</h1> |
[CSS] Un mega menu horizontal incremental avec flexbox (pure CSS)
Demo jsfiddle.net et code source zippé à télécharger.
Source HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
<div class="navDesktop navDesktopType-normal"> <h2>.navDesktop.navDesktopType-normal</h2> <nav id="navDesktop"> <ul class="navDesktop-level0"> <li> <a href="#">chemises & couvertures HORSEWIN</a> <ul class="navDesktop-level1"> <li> <a href="#">chemises de box</a> </li> <li> <a href="#">couvertures d'écurie</a> </li> <li> <a href="#">couvertures d'extérieur</a> </li> </ul> </li> <li> <a href="#">nutrition</a> <ul class="navDesktop-level1"> <li> <a href="#">aliments complets</a> <ul class="navDesktop-level2"> <li> <a href="#">gamme club & loisirs</a> </li> <li> <a href="#">gamme sport</a> </li> <li> <a href="#">gamme course</a> </li> </ul> </li> </ul> </li> <li> <a href="#">litière</a> </li> </ul> </nav> </div> <div class="navDesktop navDesktopType-incremental"> <h2>.navDesktop.navDesktopType-incremental</h2> <nav id="navDesktop"> <ul class="navDesktop-level0"> <li> <a href="#">bovins</a> <ul class="navDesktop-level1"> <li> <a href="#">alimentation & compléments</a> <ul class="navDesktop-level2"> <li> <a href="#">matières premières</a> <ul class="navDesktop-level3"> <li> <a href="#">matières premières</a> </li> <li> <a href="#">matières grasses</a> </li> <li> <a href="#">argiles et charbon</a> </li> </ul> </li> <li> <a href="#">seaux et pierres à lécher</a> <ul class="navDesktop-level3"> <li> <a href="#">pierres à lécher</a> </li> <li> <a href="#">seaux à lécher</a> </li> <li> <a href="#">supports pour seaux et pierres</a> </li> </ul> </li> <li> <a href="#">bolus</a> <ul class="navDesktop-level3"> <li> <a href="#">power bol</a> </li> <li> <a href="#">bolus longue durée pressés</a> </li> <li> <a href="#">bolus à diffusion rapide</a> </li> </ul> </li> <li> <a href="#">Minéraux</a> <ul class="navDesktop-level3"> <li> <a href="#">Max-ME</a> </li> <li> <a href="#">Max-MS</a> </li> <li> <a href="#">Max-MH</a> </li> <li> <a href="#">Maxor</a> </li> <li> <a href="#">Formules vaches taries</a> </li> </ul> </li> </ul> </li> <li> <a href="#">Veaux</a> </li> <li> <a href="#">Pâturage</a> </li> <li> <a href="#">Reproduction</a> </li> </ul> </li> <li> <a href="#">porcs</a> </li> <li> <a href="#">volailles</a> </li> </ul> </nav> </div> |
Source CSS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
/* reset */ ul, li { margin: 0; padding: 0; list-style-type: none; } /* core */ .navDesktop {} .navDesktop-level1, .navDesktop-level2 { display: none; } .navDesktopType-normal {} .navDesktopType-incremental {} .navDesktop-level0 > li:hover > .navDesktop-level1, .navDesktopType-incremental .navDesktop-level1 > li:hover > .navDesktop-level2 { display: flex; } /* layout */ .navDesktop-level0 { position: relative; display: flex; } .navDesktop-level1, .navDesktopType-incremental .navDesktop-level2 { position: absolute; z-index: 1; left: 0; top: 100%; width: 100%; } .navDesktopType-normal .navDesktop-level1, .navDesktopType-incremental .navDesktop-level2 { flex-direction: column; flex-wrap: wrap; align-content: flex-start; } /* skin */ .navDesktopType-normal .navDesktop-level1, .navDesktopType-incremental .navDesktop-level2 { max-height: 200px; } .navDesktop a { padding-right: 15px; } .navDesktopType-normal .navDesktop-level1, .navDesktopType-incremental .navDesktop-level2 { background: #ececec; } .navDesktopType-normal .navDesktop-level1 > li > a, .navDesktopType-incremental .navDesktop-level2 > li > a { font-size: 1.1em; font-weight: 700; } .navDesktopType-incremental .navDesktop-level1 { background: pink; } |
[crossbrowsertesting.com] Erreur « Invalid Host Header » où comment accéder à un site en localhost
Source: What is this “Invalid Host Header” error?
Dans le cadre d’un projet Angular
Angular CLI 6 dans mon exemple, mais voir la documentation officielle de Cross Browser Testing pour des projets Angular 2 ou Webpack.
-
Stopper le serveur (si il tourne) et le relancer en incluant les paramètres suivants dans la commande:
--host 0.0.0.0 --disableHostCheck=true
.
Si vous utilisez NPM et que vous exécutez votre serveur via unnpm start
, éditez le fichier package.json (ligne « scripts » > « start ») pour y ajouter les paramètres cités plus haut. Exemple:
123"scripts": {"start": "ng serve --host 0.0.0.0 --disableHostCheck=true --port 4200 --proxy-config proxy.conf.js",}, - Sur Quel Est Mon IP, récupérez votre IP Locale (qui commence probablement par 192.168… Dans mon cas 192.168.67.219).
- Dans l’interface de crossbrowsertesting, commencer par activer la connexion locale (depuis le bandeau « Local Connection OFF/ON »)
- Taper dans la barre d’adresse de l’appli: http://votre_IP_locale:4200 (exemple: http://192.168.67.219:4200/)