Catégorie : développement

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.

Django : les formulaires « sur mesure »

Voici les étapes lorsqu’on sort des sentiers battus et qu’on veut créer un formulaire sur mesure, ainsi qu’une vue sur mesure.

J’ai toujours eu besoin d’un ModelForm : je garde les champs que je veux, voici un code basique qui crée le champ label, avec toutes les traductions nécessaires :

class QuestionForm(forms.ModelForm):
    class Meta:
        model = Question
        fields = ('label', )
    e = {'required': _(u'This field is required'),
        'invalid': _(u'This field contains invalid data')}

    a = u'{}<span class="important-field">*</span>'.format(_(u'Question:'))
    label = forms.CharField(
        label=a, localize=True, required=True,
        widget=widgets.TextInput(attrs={
            'title': a,
            'class': 'form-control form-control'}),
        error_messages=e)

Ensuite pour cette classe, je crée un champ dynamiquement via le constructeur :

    def __init__(self, *args, **kwargs):
        super(QuestionForm, self).__init__(*args, **kwargs)
        # -----------------------------------------------------
        # Création dynamique de champs custom
        # self.fields est de type OrderedDict(), qui se base
        # sur l'ordre d'ajout des éléments. Alors si on veut
        # un autre ordre, pas d'autre choix que de reconstruire
        # le dictionnaire en y appliquant l'ordre qu'on veut :
        #
        # création dynamique de l'image :
        a = _(u'Picture')
        photo = ImageField(
            label=a, allow_empty_file=True, required=False,
            widget=forms.FileInput(attrs={
                'title': a,
                'placeholder': _(u'picture'),
                'class': 'form-control',
                'accept': "image/*", }),
            error_messages=e)
        new_fields = OrderedDict([
            ('label', self.fields['label']),
            ('photo', photo),
        ])
        self.fields = new_fields

Linux : compilation de Python en local

A l’IUT d’Aix en Provence, tous les ordinateurs sont gérés à distance, et sous Linux, aucune possibilité d’installer un logiciel.
Par contre, il est possible de compiler en local !

Compilation Python

Récupérez les dernières sources sur le site officiel.
Puis allez dans le dossier source et tapez :

./configure --prefix=$HOME/python
make && make install

A partir de là, sous PyCharm, précisez le chemin Python qui correspondra à votre $HOME/python et précisez que vous voulez installer les packages dans le répertoire de l’utilisateur courant (une case à cocher).

Et voilà : vous aurez un serveur Web Python et pourrez développer et installer tous les packages et librairies que vous voulez !

LibreOffice Impress : comment faire une macro

Comme ils l’expliquent officiellement ici, tout est en constante évolution, la documentation est pas forcément à jour etc, donc il vaut mieux aller jeter un coup d’oeil directement dans les rouages pour être sûr du fonctionnement de certains objets de LibreOffice. Ajoutez tout d’abord l’inspecteur d’objet. Il faut aller dans les Macros » Gestion des extensions, et ajouter en une extention en copiant/collant l’URL ici.

Tout d’abord le lieu de référence, celui que tout développeur cherche toujours : celui qui affiche tous les élements accessibles et ce qu’on peut faire avec : les namespaces !

List of all namespaces with brief descriptions

Je vous résume mon problème : la nouvelle mise à jour de LibreOffice change le comportement des animations et il n’est plus possible d’appliquer la même animation à un groupe. Il faut applique l’animation à la main, élément par élément ! Sur un slide de 40 pages j’ai déjà 40 fois à appliquer la même animation (ouverture en fondu), mais si je dois le faire pour 40 x 10 animations = 400 fois c’est du n’importe quoi.

Vous avez tout d’abord une liste d’exemples très intéressants ici. Mais le seul problème c’est qu’il y a très peu de choses concernant Impress. Il y a une super documentation ici, mais c’est sur des macros Python, et Python en macros, n’est utilisable que sur Write, pas sur Impress…

Voici un exemple très poussé et dont plein de choses fonctionnent à merveilles, mais certains appels ne fonctionnent pas.

C’est à partir de là que je me suis débrouillé pour écrire ma macro qui sélectionne toutes les animations du slide en cours, et les change au format « Ouverture en fondu -> Durée : 1.0s ».

Windows : astuce pour gagner du temps

  1. Placez un raccourci sont placés dans le répertoire C:\WINDOWS\system32\lnk.
  2. Ajoutez ce répertoire au PATH de Windows donc tous les raccourcis et autres programmes placés dans ce répertoire pourront être exécutés via DOS ou la commande Exécuter de Windows [WIN+R].
  3. Créez un fichier bat très court, moi j’ai, par exemple « h.bat »
  4. Dans ce fichier, si vous voulez ouvrir l’explorateur à un endroit spécifique, tapez « %SystemRoot%\explorer.exe "C:\BLABLA" » avec BLABLA étant le nom du dossier que vous voulez ouvrir

Note : si vous voulez que vos fenêtres s’ouvrent en mode « maximisé » (qui est différent de plein écran), ajoutez au début start /MAX. Exemple :
start /MAX %SystemRoot%\explorer.exe "C:\BLABLA"

Raccourci de liens

Depuis plus de 15 ans j’utilise cette astuce que peu de gens connaissent : cherchez à gagner du temps, vous verrez cela vous servira tôt ou tard !

IUT : jQuery / jQuery Mobile

Sujet

Ce que vous voulez tant que c’est dans le cadre de ce que l’on a vu. Vous avez tout le Web comme inspiration !
N’oubliez pas de me donner le nom et le mot de passe pour se connecter !

Voici les fonctionnalités obligatoires :

  • Connexion + déconnexion (vu en cours)
  • Effets jQuery sur les éléments
  • Appels JSON : au moins deux appels en plus de ceux vus en cours

Sujet imposé si vous n’avez pas d’idée

Cocktails : on se connecte, on a une liste d’éléments (récupérés en JSON) disponibles, on coche ceux qui nous intéressent, on valide, c’est envoyé, et le retour en JSON affiche les cocktails qu’il est possible de faire avec ce que l’on a coché.

Ce que vous devez me rendre

  1. Sur 4 points : le site HTML (bootstrap / design) et le code source du site HTML (HTML5, indentation)
  2. Sur 10 points : les appels AJAX, ainsi que des effets avec jQuery + de la construction dynamique d’éléments avec jQuery (indentation jQuery / JavaScript)
  3. Sur 6 points : le site HTML mobile avec du jQuery Mobile et des appels AJAX (indentation).

Pour favoriser votre organisation

  • Créez un dossier « SiteWeb » : vos pages HTML classiques, et votre code JavaScript
  • Créez un dossier « SiteMobile » : vos pages HTML pour jQuery Mobile, et votre code JavaScript pour jQuery Mobile
  • Créez un dossier « json » : tout votre code « serveur » (en Php sûrement), qui renvoie les pages au format JSON que les deux sites précedents appelleront. C’est la « référence » à n’écrire qu’une fois (copiez-collez ce dossier dans les deux dossiers précédents lorsque vous modifiez le code serveur (sous Linux, pas la peine, faites juste un lien symbolique (si vous voulez plus d’informations contactez moi)))

Librairies autorisées

Interdiction d’utiliser une librairie JavaScript qui ne vienne pas des sites autorisés précédemment

Dernier délai

Dimanche 2 avril à minuit

Fin de semaine de notre dernier cours, soit dimanche à minuit. Passé ce délai ce sera 1 pt par 2 heures de retard (je prendrai en compte la date de réception du mail).
Pour ceux qui essaient vraiment d’aller jusqu’à la dernière minute, toute heure entamée est comptée comme une heure complète. Exemple : un point en moins si je le reçois le lundi 3 avril à 00:01.
N’oubliez pas de me donner le nom et le mot de passe pour se connecter !

Rendu du TP

Vous ne m’envoyez que le code HTML et JavaScript, et un lien vers un site sur lequel vous avez tout réalisé. Ainsi, je n’aurais pas à installer / regarder ce qui a été fait en Php (ou Django/Python pour ceux qui veulent essayer les nouvelles technologies).

Avertissements

  • Copie sur une autre personne (« je se savais pas comment implémenter telle ou telle fonctionnalité dont j’avais besoin pour aller plus loin, je l’ai copiée sur un autre »), deux cas se distinguent :
    • si la personne est clairement nommée, cette fonctionnalité ne sera pas prise en compte dans la notation (= 0 pour cette fonctionnalité) ;
    • si la personne est clairement nommée, et qu’il y a une amélioration de la fonctionnalité : note pour la fonctionnalité divisée par 2 (uniquement la moitié du travail a été faite) ;
    • 0 aux deux personnes sinon ;
  • Si je m’aperçois que vous avez bêtement copié collé des sources Internet, je vous convoquerai pour vous demander de m’expliquer la fonctionnalité, et deux cas se distinguent :
    • si vous ne savez pas m’expliquer le code alors 0 ;
    • si vous savez m’expliquer tout le code alors votre note totale sera divisée par vous + le nombre de contributeurs à ce projet, ce qui se rapprochera certainement de 0 aussi.

HTML – CSS

Raccourcis pour gagner du temps :

Base d’une page Web (pris » ici)

<!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>
    ...
    <!-- Le reste du contenu -->
    ...
</body>
</html>
Commentaires fermés sur HTML – CSS Publié dans

Django : internationalisation des fichiers javascript : tutoriel complet

Django vient tout faire pour l’internationalisation de pages HTML, mais saviez-vous qu’il est aussi possible et de manière très simple d’internationaliser vos échanges AJAX ?

Vous avez un tutoriel ici.

Seul point noir : ils ont oublié deux éléments essentiels, je vais donc faire une explication courte ici, puis ajouter un résumé dans ma cheatsheet Django.

Dans l’ordre :

  • Configuration de urls.py :
    Ajouter le dictionnaire dans lequel vous précisez vos « packages ». Vos « packages », ce sont simplement les dossiers qui correspondent à l’application que vous voulez afficher. Normalement c’est un dossier racine de votre projet, moi je l’appelle très souvent « app » pour qu’il soit tout en haut des dossiers racine. Donc ici :

    js_info_dict = {
        'packages': ('app',)
    }
  • Configuration de urls.py :
    Ajouter l’URL jsi18n. Attention ! L’aide ne précise pas du tout où la mettre et c’est là où j’ai perdu énormément de temps, faites attention : il faut le mettre dans les patterns traduits, soit ici :

    urlpatterns += i18n_patterns(
        url(r'^jsi18n/$', javascript_catalog, js_info_dict,
            name='javascript_catalog'),
            # blabla...
    }
  • Includes des fichiers js dans les pages :
    <script src="{% url 'javascript_catalog' %}"></script>
  • Includes des fichiers js dans les pages :
    <script src="{% static 'js/globals.js' %}"></script>
  • Dans le fichier précédent, j’ai le code suggéré dans la documentation :
    function _(a) {
         return gettext(a);
    }
  • Générer les chaînes à traduire. Là aussi dans la documentation ils en parlent mais très mal. Pour résumer, il faut préciser le domaine djangojs :
    Exemple d’ordre qui lance la recherche de toutes les chaînes à traduire, en ignorant le dossier third_party (où je mets les outils externes que je ne veux pas toucher) :

    makemessages -d djangojs -i third_party --locale fr --locale en
  • Traduire. Ce sont les fichiers djangojs.domaine djangojs.po qu’il faut modifier, pas le classique django.po (sans strong>js).

Et à partir de là, tout fonctionne : dans tous les fichiers JavaScript qui suivent, je peux traduire à la fois ce qui arrive en AJAX, ou bien tout simplement afficher un message via _(). Exemple :

$('#menu').empty().append(
    $('<h5 />').html(_('Waiting...'))
);

From Django/Python to NodeJS. Une année après : from NodeJS to Django/Python

Tiens, un blog d’un geek qui explique pourquoi il est passé de python à NodeJS.

Why I’m switching from Python to NodeJS

Ah j’oubliais le plus important : un an après avoir utilisé nodejs en production :

After a year of nodejs in production: back to Python

Au moins ça vient d’un développeur talentueux qui a bossé jour et nuit sur du NodeJS pendant toute une année et il sait bien de quoi il parle.

Spoiler :

  • Easy to learn, impossible to master
  • Good luck handling errors: You’ll need to double your client invoices to makeup for debug time
  • Would I recommend it for large-scale products? Absolutely not.

Traduction de ce qui importe le plus : votre client devra payer le double pour le même projet : développement + autant de temps pour déboguer.

Je vous laisse faire votre propre expérience, moi j’ai la mienne qui se rapproche assez de ces billets de blog.

Javascript et jQuery : comment créer un svg dynamiquement

Saviez vous qu’il était impossible de créer un élément svg dynamiquement comme ceci :

var $('<svg />'); ?

Moi non. Après avoir cherché pendant pas mal de temps j’ai enfin réussi à faire un code qui génère un svg et ça fonctionne :

var mySvg = document.createElementNS("http://www.w3.org/2000/svg", "svg"),
    div_svg = $('#mondiv');

mySvg.setAttribute("version", "1.2");
mySvg.setAttribute("baseProfile", "tiny");
mySvg.setAttribute('viewBox', '0 0 100 100');
mySvg.setAttribute('preserveAspectRatio', 'xMinYMin');
div_svg[0].appendChild(mySvg); /* (!) [0] = élément DOM "pur" */
var c = document.createElementNS("http://www.w3.org/2000/svg", "polygon");
c.setAttribute('points', '0,45 25,1 75,1 99,45 75,90 25,90');
c.setAttribute('style', 'fill:blue;stroke:red;stroke-width:1');
$(mySvg).append(c);

Et voilà vous avez enfin un exemple qui fonctionne !

Django : créer un checkbox multiple choice avec bootstrap

Je me sers de cet habillage ici.

C’est, en gros, une « surcharge » de bootstrap avec quelques composants en plus.

Seulement j’aurais aimé avoir une sélection de plusieurs choix = cases à cocher qui soit « compatible » avec cet habillage.
Je n’aurais jamais cru que c’était aussi simple.
En fait Django a généralisé plein d’affichages HTML à tel point qu’il suffit de faire du pas à pas et de regarder ce qu’il fait pour comprendre.
Même le rendu par « item » de chaque « Renderer » est surchargeable. Donc voici le code qui prend… 10 lignes, et qui réhabille totalement le rendu des cases à cocher :

from django.forms import CheckboxSelectMultiple
from django.forms.widgets import ChoiceFieldRenderer, \
    CheckboxChoiceInput

class BootstrapChoiceFieldRenderer(ChoiceFieldRenderer):
    choice_input_class = CheckboxChoiceInput
    outer_html = '<div{id_attr}>{content}</div>'
    inner_html = '<div class="checkbox">'
                 '{choice_value}{sub_widgets}'
                 '</div>'

class CheckboxSelectMultipleBootstrap(CheckboxSelectMultiple):
    renderer = BootstrapChoiceFieldRenderer