PHP: Générer une Image à la Volée pour l’Indice Energétique d’un Logement

Voici un petit script php permettant de générer à la volée l’indice énergétique d’un logement. Pour réaliser cette image, nous utilisons deux images: une affichant les différents niveaux et une autre pour le curseur. Ce dernier est affiché par-dessus la première image en fonction de la valeur passée en paramètres. La valeur est écrite dans le curseur.

Voici le résultat pour une valeur de 50 (le src de l’image est http://leblogduwebmaster.fr/demos/indicesenergetiques/img.php?valeur=50).

indice énergétique 50

pour une valeur de 500

indice énergétique 500

<?php

// Create image instances
$src = imagecreatefrompng('indicesanscurseur.png');
$dest = imagecreatetruecolor(389, 365);

// BACKGROUND
imagecopy($dest, $src, 0, 0, 0, 0, 389, 365);

$cursorY = 0;
$cursorCenterY = 20;
if(isset($_GET['valeur'])){
    $valeur = $_GET['valeur'];
} else {
    $valeur = 0;
}


if ($valeur <= 50) {
    $cursorY = 51 - $cursorCenterY;
} elseif ($valeur >= 51 &amp;&amp; $valeur <= 90) {
    $cursorY = 94 - $cursorCenterY;
} elseif ($valeur >= 91 &amp;&amp; $valeur <= 150) {
    $cursorY = 137 - $cursorCenterY;
} elseif ($valeur >= &amp;&amp; $valeur <= 230) {
    $cursorY = 180 - $cursorCenterY;
} elseif ($valeur >= 231 &amp;&amp; $valeur <= 330) {
    $cursorY = 224 - $cursorCenterY;
} elseif ($valeur >= 331 &amp;&amp; $valeur <= 450) {
    $cursorY = 268 - $cursorCenterY;
} elseif ($valeur > 450) {
    $cursorY = 312 - $cursorCenterY;
}

$textY = $cursorY+10;

$cursor = imagecreatefrompng('cursor.png');
imagecopy($dest, $cursor, 300, $cursorY, 0, 0, 78, 59);

$textcolor = imagecolorallocate($dest, 255, 255, 255);
imagestring($dest, 20, 325, $textY, $valeur, $textcolor);

// Output and free from memory
header('Content-Type: image/png');
imagepng($dest);

imagedestroy($dest);
imagedestroy($src);
imagedestroy($cursor);
?>

Les deux images: background et le curseur.

Améliorations possibles: ajouter une ligne partant du curseur et allant jusqu’à la flèche de la classe énergétique.

Publié dans PHP

Symfony2: exemple d’un Champ de Type Slider

Je vous propose de découvrir une solution pour doter un formulaire Symfony 2 d’un champ de type slider. La grande flexibilité du constructeur de formulaires du framework, nous permet en quelques lignes de code d’utiliser le très bon plugin Ion.RangeSlider.

Etant très pressé je vais simplement poser le code. L’utilisation du plugin n’a pas été conservé dans le projet sur lequel je travaillais, donc de nombreuses améliorations sont possibles.

Vous trouverez à l’adresse citée au-dessus le lien pour télécharger le plugin, qui fonctionne avec JQuery. Placez ces fichiers dans le dossier Site\MonBundle\Ressources\Public\js\. Placez dans Site\MonBundle\Ressources\Public\css\ le css du plugin.

Le template

{#Site\MonBundle\Ressources\views/Form/fields.html.twig#}

{% block range_widget %}
<noscript>Vous devrez entrer une température entre {{ min }} et {{ max }}.</noscript>
    {% spaceless %}
        <div id="slider{{ form.vars.id }}">
        {{ form_widget( form, {'type' : 'text'} ) }}
        </div>
        {# This script allows you use range with unsupported browsers #}
    {% endspaceless %}
    {# https://github.com/IonDen/ion.rangeSlider #}
    <script>

        $("#{{ form.vars.id }}")
                .ionRangeSlider({
                        min:{{ min }},
                        max:{{ max }},
                        from: 19,
                        postfix: '{{ postfix }}',
                        {% if values == null %}
                            step: {{ step }},               
                        {% endif %}
                        {% if values != null %}
                            values: [
                            {% for value in values %}
                                {{ value }}
                                {% if not loop.last %},{% endif %}
                            {% endfor %}
                            ]
                        {% endif %}
                });

    </script>
{% endblock %}

Le champ personnalisé Pour me simplifier la déclaration de services, j’utilise le bundle https://packagist.org/packages/jms/di-extra-bundle.

<?php
// namespace Site\MonBundle\Form\Custom;

use Symfony\Component\Form\AbstractType;
use JMS\DiExtraBundle\Annotation\Service;
use JMS\DiExtraBundle\Annotation\Tag;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormInterface;

/**
 *
 * @Service("site_monbundle.form.type.range")
 * @Tag("form.type", attributes = {"alias" = "range"})
 */
class RangeType extends AbstractType {

    private $min, $max, $default, $step, $values, $postfix;

    /**
     * Get parent
     *
     * @return string
     */
    public function getParent() {
        return 'text';
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName() {
        return 'range';
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver) {
        $resolver->setDefaults(array(
            'min' => $this->min,
            'max' => $this->max,
            'default' => $this->default,
            'step' => $this->step,
            'values' => $this->values,
            'postfix' => $this->postfix
        ));
    }

    public function buildView(FormView $view, FormInterface $form, array $options) {
        $view->vars['min'] = $options['min'];
        $view->vars['max'] = $options['max'];
        $view->vars['default'] = $options['default'];
        $view->vars['step'] = $options['step'];
        $view->vars['values'] = $options['values'];
        $view->vars['postfix'] = $options['postfix'];
    }

}

l’appel à ce champ personnalisé dans un builder de form

 ->add(
          $builder->create('temperature', 'range', array(
          'min' => 0, 'max' => 40, 'default' => 19,
          'step' => 0.5, 'values' => "", 'postfix' => '°',
          'invalid_message' => "Ce n'est pas un nombre correct.")
          )
          ->addModelTransformer($transformerfloat)
          )

Le ModelTransformer permet de convertir un nombre à virgule en nombre à point afin de s’assurer d’avoir un float bien compris par Symfony 2.

<?php 
// namespace Site\MonBundle\Form\DataTransformer;

use Symfony\Component\Form\DataTransformerInterface;

class FloatFrenchTransformer implements DataTransformerInterface{

    public function transform($number)
    {
        if (null === $number) {
            return null;
        }

        return $number;
    }
    
    public function reverseTransform($number)
    {
        if (!$number) {
            return null;
        }
        
        $number = str_replace(",", ".", $number);
        
        return $number;
    }
}

le champ dans l’entité (avec contrainte de validation utilisation les Assert)

// Site\MonBundle\Entity\

// ...

/**
     * @var float
     *
     * @ORM\Column(name="temperature", type="float")
     * @Assert\Type(type="numeric", message="Vous devez entrer un nombre valide.")
     * @Assert\NotBlank()
     * @Assert\Range(
     *      min = 0,
     *      max = 40,
     *      minMessage = "La température entrée doit être comprise entre 0 et 40.",
     *      maxMessage = "La température entrée doit être comprise entre 0 et 40.",
     *      invalidMessage = "Erreur!")
     */
    private $temperature;

// ...
Publié dans PHP

Exemple d’un Top Menu Responsive

La barre haute de navigation est devenue sans conteste l’élément essentiel pour la navigation sur mobile et tablette. Si de nombreux plugins existent pour créer facilement un slider, il est peut-être nécessaire de créer son propre panel sortant du côté gauche de la page. Créer son propre top menu responsive est la garantie d’en avoir le contrôle total. Par exemple, les plugins proposés peuvent inciter à dupliquer les liens du menu de navigation.
Le fonctionnement de ce panel de navigation repose sur le css et ses transitions et aussi sur JQuery, qui nous permet de lancer les transitions avec des ajouts de classes sur le panel, qui est situé en dehors de l’écran, et sur le content, qui glissera vers la gauche afin de laisser de la place au panel.

Avant de débuter la lecture, jetez un oeil à la démo.

Pour commencer, je vous propose de mettre en place la structure de notre page HTML.

<!doctype html>
<html lang="fr">
	<head>
		<meta charset="utf-8">
		<title>Slider Panel Left</title>
		<link rel="stylesheet" href="sliderstyle.css">
		<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
		<script src="sliderleft.js"></script>
	</head>
	<body>
		<div id="sliderleft">
			
		</div>
		
		<div id="container">
			
			<nav id="topmenu">
				<div id="topmenu-hamburger"></div>
				
				<a id="brand" href="#">BRAND</a>
				
				<ul>
					<li><a href="#">Item 1</a></li>
					<li><a href="#">Item 2</a></li>
				</ul>
				
				<form>
					<input type="text" placeholder="chercher..." />
					<input type="submit" value="?" />
				</form>
			</nav>
			
			<div id="page">
				<:-- le content -->
			</div>
			
			
		</div>
		
	</body>
</html>

Le div d’id « topmenu-hamburger » sera affiché uniquement sur les mobiles et les tablettes et permettra d’afficher notre panel de navigation. Le div d’id « sliderleft » est notre panel. Il sera rempli avec les liens du nav et ce avec JQuery. Nous évitons ainsi la duplication de code.

Voici le code css pour cette page:

body{
	margin:0;padding:0;
	overflow-x:hidden;
	font-size:16px;
}

/* container */

#container{
	position:absolute;
	top:0;
	left:0;
	width:100%;
	height:100%;
	transition: transform 0.6s;
}

/* panelleft */

#sliderleft{
	min-height:100%;
	background:#DBE2E9;
	position:fixed;
	top:0;left:-50%;
	-webkit-touch-callout: none;
	-webkit-user-select: none;
	-khtml-user-select: none;
	-moz-user-select: none;
	-ms-user-select: none;
	user-select: none;
	width:50%;
	transition: transform 0.6s;
}

#sliderleft ul{
	list-style:none;
	margin:0px;padding:0px;
}
#sliderleft ul li{
	padding:4px;
}
#sliderleft ul li a{
	font-size:16px;
	color:black;
	text-decoration:none;
}

.sliderleft-transition{
	transform: translateX(100%);
}

.sliderleft-shadow{
	box-shadow: 3px 0 5px -2px black;
}

#slider-close{
	padding:10px;
	border-radius:50%;
	float:right;
	border:2px solid darkgray;
	cursor:pointer;
	font-weight:bold;
	margin:5px;
	transition: transform 0.4s;
	background:white;
	color:black;
	font-size:18px;
}
#slider-close:hover{
	transform: rotateY(360deg);
}

/* page content */

#page{
	margin-top:65px;
	padding:15px;
}

.content-transition{
	transform: translateX(50%);
}

/* top menu */
#topmenu{
	position:fixed;
	top:0;
	left:0;
	width:100%;
	background:black;
	height:60px;
	font-size:20px;
	color:white;
}
#topmenu ul{
	list-style:none;
	margin:0;padding:0;
	margin-top:20px;
	padding-left:10px;
	float:left;
}
#topmenu ul li{
	display:inline;
	padding-left:7px;
}
#topmenu ul li a{
	color:lightgrey;
	text-decoration:none;
}

#topmenu ul li a:hover{
	color:yellow;
}

#brand{
	font-size:30px;
	float:left;
	color:darkgrey;
	text-decoration:none;
	font-weight:bold;
	font-style:italic;
	margin-top:15px;
	margin-left:10px;
}

#brand:hover{
	color:red;
}

#topmenu-hamburger{
	float:left;
	width:50px;height:50px;
	margin-top:5px;
	background-image:url(hamburger.png);
	cursor:pointer;
	display:none;
}

#topmenu form{
	display:block;
	float:right;
	margin-top:5px;
}

#topmenu input[type="text"]{
	height:30px;
	font-size:20px;
	padding:5px;
	border-radius:4px;
	border:1px solid lightgrey;
	width:150px;
}

#topmenu input[type="submit"]{
	border-radius:50%;
	border:1px solid lightgrey;
	width:30px;
	height:30px;
	margin-top:10px;
	margin-right:10px;
}

/* responsive */

@media screen and (max-width: 480px) {
	#topmenu-hamburger {
		display:block;
	}
	#topmenu ul{
		display:none;
	}
	#topmenu input[type="text"]{
		width:95px;
		font-size:15px;
	}
	#brand{
		font-size:20px;
		margin-top:20px;
		margin-left:3px;
		
	}
}

@media screen and (max-width: 300px) {
	#topmenu form{
		display:none;
	}
}

Nous utilisons les medias queries afin d’afficher et de cacher notre bouton « hamburger » permettant à l’utilisateur d’afficher le panel de navigation. Ce dernier est placé en dehors de l’écran avec left:-50% et sera affiché à l’écran grâce à la classe .sliderleft-transition qui fera effectuer une translation de -50% à 0% à notre panel. De même, la classe content-transition permettra de faire glisser le contenu de notre page afin de laisser la place à notre panel.
La propriété « overflow-y: hidden » pour le body permet de ne pas avoir une barre de défilement latérale quand nous faisons glisser le content vers la gauche.

Voici le code javascript.

$( document ).ready(function() {
	
	isOpen = false;
	menuAdd = false;
	
	$('#topmenu-hamburger').click(function(event) {
		
		if(isOpen===false){
			open();
			} else {
			close();	
		}
		event.stopPropagation();
	});
	$('#container').click(function() {
		close();
	});
	
	
	$(document).on('click', "#slider-close" , function() {
		close();		
	});
	
	function open(){
		isOpen = true;
		if(menuAdd === false){
			text = "";
			$('#topmenu ul li a').each(function() {
				
				text = text + '<li><a href="'+($(this).attr('href'))+'">'+($(this).text())+'</a></li>';
				
			})
			
			
			text = 
			'<div id="slider-close">X</div>'+
			'<ul>'+text+'</ul>'; 
			
			$("#sliderleft").append(text);
			menuAdd = true;
		}	
		$('#container').addClass("content-transition");
		$('#sliderleft').addClass("sliderleft-transition");
		$('#sliderleft').addClass("sliderleft-shadow");
	}
	
	function close(){
		$('#container').removeClass("content-transition");
		$('#sliderleft').removeClass("sliderleft-transition");
		$('#sliderleft').removeClass("sliderleft-shadow");
		isOpen = false;
		
	}
	
});

Ce code permet dans un premier temps de récupérer tous les liens du menu de navigation et de les ajouter à notre panel de navigation. Dans un second temps, le script ajoute ou enlève les classes de transition au content et au panel.

Publié dans HTML5

Voici comment insérer une photo Instagram dans une page web

Si vous souhaitez intégrer une photo publiée sur instagram dans une page de votre site web, le réseau social met à votre disposition un code d’embed. Pour obtenir ce code, il faut dans un premier temps cliquer sur la photo de votre choix puis dans le coin en bas à droite de cliquer sur les trois petits points. Un menu avec « Intégrer » apparaît, cliquez sur ce dernier.

instagram embed

Ensuite, il ne vous reste plus qu’à copier le code affiché dans la boîte pour enfin le coller dans votre page ou votre article. Prenez-soin si vous utiliser un éditeur wysiwyg de passer en mode HTML ou Texte.

code embed instagram

Voici un exemple d’intégration d’une photo instagram du compte de Cristiano Ronaldo

Happy birthday @realmadrid for the 113 years of success.

Une photo publiée par Cristiano Ronaldo (@cristiano) le

Publié dans Réseaux Sociaux

l’Outil de Google pour Tester la Compatibilité Mobile

Google vient d’annoncer que les sites web devraient être mobile friendly pour le 21 avril prochain. Le moteur de recherche va sans nul doute appliquer un filtre à son index, ou même en créer un deuxième – si ce n’est déjà pas le cas, pour les recherches effectuées sur mobile. Pour vérifier la compatibilité mobile de votre site web, Google propose l’analyseur suivant:

https://www.google.com/webmasters/tools/mobile-friendly/?hl=fr

Vous pouvez évidemment déjà vérifier la compatibilité de votre site avec votre compte Google Webmaster Tools.

test compatibilité mobile google

Publié dans Outils

Code pour Créer un Bouton Rond en CSS

Découvrez comment créer facilement un bouton rond en CSS. Avec cette technique, vous n’aurez plus besoin d’ouvrir votre logiciel de graphisme et surtout d’intégrer à votre design une image supplémentaire. Vous gagnerez donc en performance avec seulement quelques lignes de CSS! Pour créer un bouton rond ou tout autre élément d’ailleurs comme un div ou une image, il suffit de donner une largeur et une hauteur identiques au bouton et un border-radius de 50%.

La page démo. Le code source:

<!doctype html>
<html lang="fr">
	<head>
		<meta charset="utf-8">
		<title>Bouton Rond en CSS</title>
		<style>
			.rond{
				border-radius:50%;
				width:100px;
				height:100px;
				background: linear-gradient(#f7f7f7, #e7e7e7); 
				box-shadow: 0px 3px 8px #aaa, inset 0px 2px 3px #fff;
				border:none;
				outline:none;
				font: 18px Tahoma bold;
				color: #a7a7a7;
				text-shadow: 1px 1px 1px lighgrey;
				margin:20px;
			}
			div.rond{
				text-align:center;
			}
			div.rond span{
				position:relative;
				font-size:20px;
				top:40px;
			}
		</style>
	</head>
	<body>
	
		<h1>Bouton, Div et Image Ronds en CSS</h1>
	
		<button class="rond">Bouton Rond</button>
		
		<div class="rond"><span>Div</span></div>
		
		<img src="cat.jpg" width="100" height="100" alt="Chat Rond" class="rond" />
	</body>
</html>
Publié dans CSS

Exemple d’une Structure Minimale d’une Page HTML5

Retrouvez la structure minimale d’une page HTML5 valide avec le code présenté ci-dessous. Le HTML5 fait dorénavant partie du quotidien de plusieurs centaines de milliers de professionnels voir même plus certainement de plusieurs millions. HTML5, HyperText Markup Language 5, a été finalisée le 28 octobre 2014. Cette nouvelle révision du langage de présentation des documents impose dorénavant la structure suivante pour nos pages web:

<!doctype html>
<html lang="fr">
<head>
  <meta charset="utf-8">
  <title>Titre de la page</title>
  <link rel="stylesheet" href="style.css">
  <script src="script.js"></script>
</head>
<body>
<!-- contenu -->
</body>
</html>

Remarque sur cette nouvelle structure: le doctype est spécifié très facilement, la langue du document est précisée avec un attribut de la balise html.

Publié dans HTML5

CSS: utiliser une image comme curseur!

Il est possible en jouant avec le CSS de remplacer le curseur de la souris de l’internaute par une image. Cette substitution de curseur n’est pas toujours très heureuse. Les utilisateurs peuvent en effet être quelque peu décontenancés par ce remplacement de leur habituel flèche mais il est peut être de savoir que ce changement de curseur est possible.

Dans cet exemple, le curseur de la page est remplacé par une image avec la propriété cursor. Le premier attribut indique l’url de l’image servant de curseur, « 0,0 » permet de configurer le point chaud (haut,gauche) et auto permet d’indiquer au navigateur quel curseur utilisé si notre image est indisponible.

<!doctype html>
<html lang="fr">
<head>
  <meta charset="utf-8">
	<head>
	<style>
	<title>Changement de curseur</title>
		body{
			cursor: url(chatcurseur.gif) 0 0, auto;
		}
	</style>
	</head>
	<body>
		Changement de curseur.
	</body>
</html> 

la page de démo, plus d’infos: http://www.w3schools.com/cssref/pr_class_cursor.asp

Publié dans CSS

CSS3: Créer un Effet de Zoom au Survol des Images

Découvrez comment réaliser très simplement avec CSS3 un effet de zoom au survol d’une image de votre site. Pour réussir cet effet sympa qui attirera l’attention de vos visiteurs, nous allons utiliser les transitions de CSS3.
Nous allons en effet définir dans notre fichier CSS pour les images visées, un agrandissement de l’image quand la souris est au-dessus de l’image et appliquée une transition à cette transformation. L’image est contenue dans un div, dont la taille et fixée et les dépassements masqués.

La démo, le code:

.divImageZoom{
	/* on définit la taille du div et on empêche les débordements */
	width:300px;
	height:225px;
	overflow:hidden;
	/* on ajoute une ombre à notre div */
	-webkit-box-shadow: 5px 5px 5px #111;
	box-shadow: 5px 5px 5px #111;  
}

.divImageZoom img{
	-webkit-transition: all 1s ease; /* Safari and Chrome */
	-moz-transition: all 1s ease; /* Firefox */
	-o-transition: all 1s ease; /* IE 9 */
	-ms-transition: all 1s ease; /* Opera */
	transition: all 1s ease;
	max-width: 100%;
}
			
.divImageZoom img:hover{
	-webkit-transform:scale(1.25); /* Safari and Chrome */
	-moz-transform:scale(1.25); /* Firefox */
	-ms-transform:scale(1.25); /* IE 9 */
	-o-transform:scale(1.25); /* Opera */
	transform:scale(1.25);
}
Publié dans CSS

include wp-blog-header.php: ne pas renvoyer une erreur 404

Si vous souhaitez utiliser les fonctions de worpdress hors du blog avec l’inclusion require_once(« wp-blog-header.php »); vous allez sans nul doute découvrir avec étonnement que votre page php va renvoyer une erreur 404. Ce problème peut-être très facilement résolu en remplaçant require_once(« wp-blog-header.php »); par

require_once("wp-config.php");
$wp->init(); $wp->parse_request(); $wp->query_posts();
$wp->register_globals(); $wp->send_headers();

Vous pourrez ainsi sortir de jolies pages pour par exemple vos applications mobiles sans avoir des plantages dus à des erreurs 404.

source: https://cooltrainer.org/fixing-false-404-headers-on-external-pages-including-wp-blog-header-php/.

Publié dans Wordpress

quand j’aurai le temps

  • les filtres wordpress
  • plugin wordpress et enregistrement de données
  • les wordpress custom post type
  • la bdd d'un blog wordpress
  • la balise more de wp
  • personnaliser une galerie wp
  • gérer les longueurs des extraits de wp
  • les animations css3
  • le memento symphony2
  • le squelette d'une page html5
  • liste sur plusieurs colonnes
  • le responsive design
  • exemple d'un jeu basique en html5
  • la réplication des bases de données
  • mettre en place une architecture en silo avec wp
  • parser un fichier xml (donc un rss) avec php5
  • mettre en place lightbox sans plugin
  • améliorer les performances de son wp
  • ajouter un bouton à l'éditeur de texte de wp
  • ...