Une bonne interface utilisateur
Voici un site qui donne plein de bonnes idées pour faire une bonne interface utilisateur :
Tout ce qui concerne le développement en général, que ce soit des choses générales, ou des choses bien précises. Cela va de la gestion de projet à la recherche du fonctionnement de pointeurs en C.
Voici un site qui donne plein de bonnes idées pour faire une bonne interface utilisateur :
Après bon nombre de commentaires, voire d’insultes (si si), je résume l’article qui suit :
Vous allez toujours entendre le même discours pour ceux qui commencent avec Symfony et qui n’ont jamais vraiment développé d’autres choses, qui est quelque part logique : Symfony c’est génial, c’est super, c’est la réponse à la vie, l’univers, et au reste, il aurait dû s’appeler « Php – 42 » ou quelque chose comme ça (et si vous ne comprenez pas l’allusion c’est qu’on n’a ni le même background, ni le même humour). C’est, de plus, très souvent le genre de personnes qui n’admettent pas qu’ils n’ont pas d’expérience et cela finit à l’insulte ou au pugilat.
S’ils avaient vraiment pratiqué d’autres choses, il verraient qu’il y a plein d’autres trucs ailleurs, et ils verraient qu’à d’autres endroits il y a des choses mieux.
Ceux qui n’ont pas d’expérience mais l’esprit ouvert me demandent ce qu’il y a comme autres choses à tester, et je leur réponds avec plaisir ! Ceux qui n’ont pas d’expérience et ont besoin de justifier leur existence diront « c’est un gros con il est dépassé il n’y comprend rien ». Je ne donne des cours que pour les premiers. Les autres je les laisse faire alt-tab en permanence entre Facebook et Symfony (et si vous saviez tout ce que je pense quand je parle ainsi…).
Après avoir développé deux applications relativement basiques, voici les inconvénients que j’ai relevé de Symfony :
$_SERVER
pour suivre quelques infos.… bref, refaire des milliers de choses d’une inutilité absolument affligeante, tout ça pour faire un simple resize. Après avoir passé plusieurs heures à installer le LiipImagineBundle : et m’être aperçu que pour faire un resize, il fallait déclarer vouloir utiliser un service dans ‘app/config/config.yml’, je vois qu’il y a un exemple qui est censé fonctionner sur stackoverflow ici. Et puis là le code qui fonctionne utilise getRequest()
. Et le container. Moi j’en avais besoin dans l’entité, car c’est ici qu’on écrit les informations en base de données. Pour pouvoir accéder à un container dans une entité, il faut faire un méga hack, ou pire (lire les deux réponses ici). La seule réponse viable c’et de.. créer un service ! Non mais allô quoi ! Juste pour un crop ! Vraiment on est en plein délire. Hop, top chrono : google =» php imageresize, copier coller, et en moins de 5 minutes, tout fonctionnait. Symfony clame haut et fort qu’il vous fait gagner des heures de boulot ? C’est une blague, une grosse blague ! Posez les pieds sur terre, voici la réalité concrète du terrain : Symfony essaie de pousser encore et encore l’abstraction à son maximum mais on arrive à des non-sens comme celui-là : une entité qui appelle deux services différents, surchargés à mort, des centaines de lignes de code totalement inutiles, juste pour faire un resize. C’est tellement grossier comme problème qu’on en arriverait presque à croire que c’est faux… mais c’est vrai, et les liens que j’ai mis sont bien là pour le prouver.
"SELECT COS(5) as distance;"
. Non non ça n’est pas une blague, c’est du sérieux. Voir tout mon article détaillé ici.Je n’ai pas le temps de lister toutes les autres choses qui m’ont fait perdre un temps fou. J’ai vendu un site que je comptais faire en maximum dix jours, et je l’ai fait en un mois. Symfony était tout bonnement un mauvais choix.
Pour la petite note, les personnes qui m’ont sous traité le projet – qui tourne bien actuellement – ont été déçues parce que je n’ai pas tenu mes délais, et que mes premières livraisons n’étaient pas de bonne qualité – alors que je « semblais » compétent. Je ne jette pas tout sur Symfony, mais bon sang quelle grossière erreur de ma part ! Pour vous donner une idée de comparaison : j’ai terminé en 3 jours un site qui devrait être mis en ligne incessamment sous peu : un site spécialisé la constatation fiable de sites Web. Il contient :
CSRF
protection, re-Captcha
etc) ;Webkit
(très gros boulot) ;Smarty
pour modifier l’habillage rapidement ;PhpDocumentor
;SQL
pur. Ouf, je respire, des heures entières de gagnées.PHPMailer
, un outil simple, ultra facile d’utilisation, et utilisé dans ma classe, finit par un code ainsi :
$mail = new ObjetMail( EMAIL_DEFAUT_FROM, EMAIL_DEFAUT_FROM_NAME, EMAIL_DEFAUT_REPLYTO, EMAIL_DEFAUT_REPLYTO_NAME, $email, 'Capture bien prise', /*... Texte HTML ...*/, /*... Texte alternatif ...*/ ); try { $mail->send(); array_push( $this->_TabResult, $this->trad->get( 'mail_envoye_en_attente_confirmation' ) ); } catch (Exception $e) { $this->addTabErr( $this->trad->get('err_envoi_email') ); $ok = false; }
Faire la même chose avec Symfony ? Je vous laisse estimer le temps de faire les estimations, le cahier des charges, le devis, le développement, mais attention, grâce à Symfony vous allez gagner énormément de temps : Symfony peut générer le CRUD pour l’administration en ligne de commande, regardez ici. Oulah que de temps gagné ! Sachant que je génère un custom getter-setter en 3 touches avec vim, même s’il y a plusieurs centaines de champs, et plusieurs dizaines de tables, je ferais ça « à la main » au maximum en une journée… enfin bon en comparant avec Symfony je peux dire sans éxagérer : sans Symfony, une journée de perdue, mais dix d’économisées ! Mais pourquoi je continue à essayer de prouver que Symfony ne fait jamais gagner de temps, moi ? Même ces personnes expertes Symfony ont décidé de le laisser tomber et de n’utiliser que Silex pour tous leur nouveaux projets à moins qu’ils n’aient vraiment besoin de choses spécifiques à Symfony… et personnellement je n’arrive pas à voir ce que Symfony a de si spécifique dont on ne peut pas se passer 🙂 … A l’inverse, je vois vraiment toutes les raisons pour lesquelles on peut se passer de Symfony.
Tutoriel :
https://developers.google.com/maps/documentation/javascript/tutorial?hl=FR
Fichier JSON qu’il faut créer :
{
pos: {
"lat": 0.123123,
"lng": 0.5934257
},
"titre": "Titre Ma maison",
"contenu": "Maison de chez mes parents etc etc"
}
Exemple de début de code Javascript qui charge le document :
$.getJSON("maison.json")
.done(function (data) {
/* Code qui crée une google map dans un div */
})
.error(function(obj) {
alert('Erreur, regardez la console');
console.log(obj);
});
Dans l’idéal, voici ce qu’il faudrait faire pour le ready()
:
$(document).ready(function() {
/* fonction qui lance le chargement du fichier JSON,
* et le met dans le div concerné
*/
ajaxChargeGoogleMaps(
"maison_parents.json",
"#id-map1"
);
ajaxChargeGoogleMaps(
"maison_personnelle.json",
"#id-map2"
);
});
Voici le code de base pour changer l’heure de votre RaspberryPi :
sudo date -s "12 MAR 2014 12:50:00"
Saviez vous qu’il était possible d’automatiser la plupart des applications google ?
Allez simplement sur cette adresse : https://script.google.com.
Vous verrez : c’est extrêmement pratique.
Ce site donne même cinq exemples de scripts pour automatiser certaines tâches rébarbatives :
Si vous ne connaissez pas ExtJs, c’est « à peine » du JavaScript, « à peine » utilisé par IBM, et plein d’autres « petites » entreprises 😉 .
Très puissant mais il manque parfois d’exemple.
En voici un pratique que j’ai eu du mal à mettre en place : pourtant c’est du classique de chez classique.
Je veux ouvrir un onglet qui charge automatiquement des informations de base de données : un onglet dans lequel il y a les informations d’un dossier : nom, prénom, date de naissance, etc.
Assez classique.
Mais disons… que je veux en faire le moins possible. Avec ExtJs, c’est très simple. Enfin simple… après avoir bien cherché !
En fait, l’astuce est qu’il faut appeler la fonction autoLoad, pour que le chargement soit automatique, et avant même d’afficher l’onglet.
Dans mon cas, je voulais afficher Homme ou Femme dans un combo. Donc il fallait avant même d’afficher l’onglet, qu’il précharge le truc dans un magasin de données = store.
Options de lancement de Chrome si on veut pouvoir faire de l’AJAX avec les fichiers en local sans installer de serveur Web :
--allow-file-access-from-files
--incognito
-start-maximized
Voici un exemple à suivre : tout un livre écrit par la communauté, donc tout un chacun – et ce pourraît même être vous – qui explique de manière très compréhensible, le HTML5.
# make bash autocomplete with up arrow bind '"\e[A":history-search-backward' bind '"\e[B":history-search-forward'
Si jamais vous commencez à découvrir la chose super pratique qu’est un shortcode alors voici une petite astuce, si vous êtes sur Linux : comment lister les shortcodes présents.
Il suffit dans le shell
, d’aller dans votre répertoire WordPress et de taper cette ligne de commande :
find . -type f -print0 | grep -z php$ | xargs -0 grep 'add_shortcode' | more
Et vous aurez le listing de tous les endroits où on appelle cette fonction. Il ne vous reste plus qu’à regarder ce qu’ont fait les personnes ! Il existe même des shortcodes cachés dans certains thèmes, que les auteurs ont dû faire pour eux, mais qu’ils n’ont pas documenté ! Très pratique !
Exemple :
...ygen/library/functions/shortcodes.php: add_shortcode( 'entry-title', 'hybrid_entry_title_shortcode' );
...ygen/library/functions/shortcodes.php: add_shortcode( 'entry-author', 'hybrid_entry_author_shortcode' );
...ygen/library/functions/shortcodes.php: add_shortcode( 'entry-terms', 'hybrid_entry_terms_shortcode' );
...ygen/library/functions/shortcodes.php: add_shortcode( 'entry-comments-link', 'hybrid_entry_comments_link_shortcode' );
...ygen/library/functions/shortcodes.php: add_shortcode( 'entry-published', 'hybrid_entry_published_shortcode' );
...ygen/library/functions/shortcodes.php: add_shortcode( 'entry-edit-link', 'hybrid_entry_edit_link_shortcode' );
...ygen/library/functions/shortcodes.php: add_shortcode( 'entry-shortlink', 'hybrid_entry_shortlink_shortcode' );
...ygen/library/functions/shortcodes.php: add_shortcode( 'entry-permalink', 'hybrid_entry_permalink_shortcode' );
...ygen/library/functions/shortcodes.php: add_shortcode( 'post-format-link', 'hybrid_post_format_link_shortcode' );
...ygen/library/functions/shortcodes.php: add_shortcode( 'comment-published', 'hybrid_comment_published_shortcode' );
...ygen/library/functions/shortcodes.php: add_shortcode( 'comment-author', 'hybrid_comment_author_shortcode' );
...ygen/library/functions/shortcodes.php: add_shortcode( 'comment-edit-link', 'hybrid_comment_edit_link_shortcode' );
...ygen/library/functions/shortcodes.php: add_shortcode( 'comment-reply-link', 'hybrid_comment_reply_link_shortcode' );
...ygen/library/functions/shortcodes.php: add_shortcode( 'comment-permalink', 'hybrid_comment_permalink_shortcode' );
...gelines/includes/class.shortcodes.php: add_shortcode( $shortcode, array( &$this, $data['function']) );
...b/library/shortcodes.php:add_shortcode('gallery', 'gallery_shortcode_tbs');
...b/library/shortcodes.php:add_shortcode('button', 'buttons');
...b/library/shortcodes.php:add_shortcode('alert', 'alerts');
...b/library/shortcodes.php:add_shortcode('block-message', 'block_messages');
...b/library/shortcodes.php:add_shortcode('blockquote', 'blockquotes');
...ean-retina/library/shortcodes/cleanretina-shortcodes.php: * Creates new shortcodes for use in any shortcode-ready area. This function uses the add_shortcode()
...ean-retina/library/shortcodes/cleanretina-shortcodes.php: * @uses add_shortcode() to create new shortcodes.
...ean-retina/library/shortcodes/cleanretina-shortcodes.php: add_shortcode( 'the-year', 'cleanretina_the_year_shortcode' );
...ean-retina/library/shortcodes/cleanretina-shortcodes.php: add_shortcode( 'site-link', 'cleanretina_site_link_shortcode' );
...ean-retina/library/shortcodes/cleanretina-shortcodes.php: add_shortcode( 'wp-link', 'cleanretina_wp_link_shortcode' );
...ean-retina/library/shortcodes/cleanretina-shortcodes.php: add_shortcode( 'th-link', 'cleanretina_themehorse_link_shortcode' );
...ntra/includes/theme-shortcodes.php:add_shortcode('mantra-site', 'mantra_site_link_fn');
...ntra/includes/theme-shortcodes.php:add_shortcode('mantra-author', 'mantra_the_author_fn');
...ntra/includes/theme-shortcodes.php:add_shortcode('mantra-tag-cloud', 'mantra_tag_cloud_fn');
...ntra/includes/theme-shortcodes.php:add_shortcode('mantra-multi', 'mantra_multi_column_fn');
...ntra/includes/theme-shortcodes.php:add_shortcode('mantra-column', 'mantra_column_fn');
...ntra/includes/theme-shortcodes.php:add_shortcode( 'mantra-pullquote', 'mantra_pullquote_fn' );
...ntra/includes/theme-shortcodes.php:add_shortcode( 'mantra-button-light', 'mantra_button_light_fn' );
...ntra/includes/theme-shortcodes.php:add_shortcode( 'mantra-button-dark', 'mantra_button_dark_fn' );
...ntra/includes/theme-shortcodes.php:add_shortcode( 'mantra-button-color', 'mantra_button_color_fn' );
...ntra/includes/theme-shortcodes.php:add_shortcode('cryout-site', 'mantra_site_link_fn');
...ntra/includes/theme-shortcodes.php:add_shortcode('cryout-author', 'mantra_the_author_fn');
...ntra/includes/theme-shortcodes.php:add_shortcode('cryout-tag-cloud', 'mantra_tag_cloud_fn');
...ntra/includes/theme-shortcodes.php:add_shortcode('cryout-multi', 'mantra_multi_column_fn');
...ntra/includes/theme-shortcodes.php:add_shortcode('cryout-column', 'mantra_column_fn');
...ntra/includes/theme-shortcodes.php:add_shortcode( 'cryout-pullquote', 'mantra_pullquote_fn' );
...ntra/includes/theme-shortcodes.php:add_shortcode( 'cryout-button-light', 'mantra_button_light_fn' );
...ntra/includes/theme-shortcodes.php:add_shortcode( 'cryout-button-dark', 'mantra_button_dark_fn' );
...ntra/includes/theme-shortcodes.php:add_shortcode( 'cryout-button-color', 'mantra_button_color_fn' );
...artupwp/functions.php:add_shortcode('wp_caption', 'fixed_img_caption_shortcode');
...artupwp/functions.php:add_shortcode('caption', 'fixed_img_caption_shortcode');
...p:add_shortcode('wp_caption', 'img_caption_shortcode');
...p:add_shortcode('caption', 'img_caption_shortcode');
...p:add_shortcode('gallery', 'gallery_shortcode');
...p:add_shortcode( 'audio', 'wp_audio_shortcode' );
...p:add_shortcode( 'video', 'wp_video_shortcode' );
...-embed.php: add_shortcode( 'embed', '__return_false' );
...-embed.php: * @uses add_shortcode()
...-embed.php: add_shortcode( 'embed', array( $this, 'shortcode' ) );
...es.php: * add_shortcode('footag', 'footag_func');
...es.php: * add_shortcode('bartag', 'bartag_func');
...es.php: * add_shortcode('baztag', 'baztag_func');
...es.php:function add_shortcode($tag, $func) {