23
Structure de blog en PHP et Javascript avec Cockpit
Php, Javascript, Web
15 sept 2019

Cockpit est un très bon CMS (headless), mais qui possède malheureusement une documentation presque aussi faible que PyQGIS. Pour mémoire et aide, je publie ci-dessous un bout de code PHP qui permet de récupérer les données d'une collection Cockpit et les afficher sur une page. C'est très basique, mais même cela n'est pas la doc.

<?php
require_once("path/to/cockpit/bootstrap.php");


$page = 0;
$articlePerPage = 3;

$posts = cockpit('collections')->find('journal', [
   'limit' => $articlePerPage,
   'skip' => $articlePerPage*$page,
   'sort' => ["date"=>-1], //sorted by user defined "date" entry ; ["_created"=>-1] for last articles created first ; ["_o"=>1] for custom-order
   'filter' => ["tags"=>"myTag"]
]);

if (empty($posts)) {
    echo "Il n'y a pas de billets dans ce journal.".PHP_EOL;
} else {
    foreach ($posts as $post) {
      $title = $post["title"];
      $titleSlug = $post["title_slug"];
      $date = $post["date"];
      $tags = $post["tags"];
      $content = $post["content"];

      echo "
<article>
  <h3>".$title." (".$titleSlug.")</h3>
  <h4>".$date.". # Tags : ".implode(", ",$tags)."</h4>
".$content."
</article>
      ".PHP_EOL;
    }
}
?>

Et voici la même chose avec REST API et XMLHttpRequest en Javascript. La documentation propose d'utiliser fetch mais cette méthode n'est pas supportée par d'anciens navigateurs (Blackberry OS 10 par exemple). Il faut générer un jeton (token) adéquat depuis l'interface d'administration de Cockpit. Le jeton étant ici affiché en clair, pour des raisons évidentes de sécurité, il faut configurer un jeton en lecture seule et uniquement pour la collection recherchée. Voir la documentation Cockpit à ce sujet.

var container = document.getElementById("blog");
var ajaxReady = true; //avoids sending two requests at the same time

function nextPosts() {
  if(ajaxReady) {
    ajaxReady = false;

    // Request
    var request = new XMLHttpRequest();
    request.open('POST', 'path/to/cockpit/api/collections/get/name-of-your-collection?token=YOUR-READ-ONLY-TOKEN', true);
    request.onload = function() {
      var data = JSON.parse(this.response);
      if (request.status >= 200 && request.status < 400) {
        var posts = data["entries"];
        var totalPosts = data["total"];

        for (var i in posts) {
          var post = posts[i];

          // Post elements
          const article = document.createElement("article");

          const articleTitle = document.createElement("h3");
          articleTitle.textContent = post.title;

          const articleDateAndTags = document.createElement("h4");

          var subtitle = post.date + "# Tags : ";
          for (var j in post.tags) {
              var t = post.tags[j] + ",";
              subtitle += t;
          }
          articleDateAndTags.innerHTML = subtitle;

        // Assembly
        article.appendChild(articleTitle);
        article.appendChild(articleDateAndTags);
          article.innerHTML += post.content;

          // Append article to page
          container.appendChild(article);

          postPosition += 1;

          if(postPosition >= totalPosts) {
            console.log("Fin des articles");
          }
        }
        ajaxReady = true;

      } else { 
        console.log("Error");
      }
    }

    // Request's body
    var requestBody = JSON.stringify({
        limit: postsPerLoad,
        skip: postPosition,
        sort: {date:-1},
        filter: {tag:"myTag"}
    });

    // Send request
    request.setRequestHeader('Content-Type', 'application/json');
    request.send(requestBody);
  }
}

nextPosts();
22
PHP Simple HTML Dom compatible PHP 7.3
Php, Web
28 août 2019

Simple_html_dom est un très bon outil (je l'utilise par exemple pour cine-ics), mais il n'est plus mis à jour. Entre passant à PHP 7.3 on a donc quelque problèmes de compatibilité.

En suivant quelques indications trouvées ça et sur StackOverflow, j'ai modifié à minima la librairie pour la faire fonctionner sous PHP 7.3. Aucune garantie si ces modifications causent des problèmes par ailleurs.

Voici le fichier : simple_html_dom_php73.zip.

Pour information, c'est principalement le support pour les offset négatif de la fonction file_get_contents à partir de PHP 7.1 qui semble être la cause des problèmes. La librairie Simple_html_dom utilisait des offsets négatifs comme raccourci de code pour spécifiait des valeurs nulles.

21
La maîtrise d'ouvrage en RDA
Cinema, Architecture
17 juil 2019
Die Architekten, 1990, Peter Kahane (DEFA)
20
La visite de l'appartement type
Cinema, Architecture
18 déc 2018
Le Coup de sirocco, Alexandre Arcady (1979)
Sallah Shabbati, Ephraim Kishon (1964). NB : c'est le plus grand succès du cinéma israélien
19
Extraire un nombre décimal en Javascript
Javascript
30 nov 2018
function extractFloat(element) {
    element = element.toString();
    var match = element.match(/-?\s*\d+(\.\d+)?/); // captures the first 0 or -0 or -0.0 match

    if(match) {
    return match[0].replace(/\s+/g, ''); // removes whitespaces (if any)
    } else {
    return false;
  }
}

console.log(extractFloat("margin-top: - 66.67 px")); // -66.67
console.log(extractFloat("I ate 10 apples in the last 5 days")); // 10
console.log(extractFloat("2*a")); // 2
console.log(extractFloat(-5.0)); // -5
18
Fonction JS « est un nombre »
Javascript
29 nov 2018
function isNumber(n) {
    return !isNaN(parseFloat(n)) && isFinite(n);
}
17
Equivalent JS de la fonction Python int()
Javascript, Web
23 nov 2018
function int(n) {
    n = Math.round(n);

    if(!isNaN(n)){
        return n;
    } else { return 0; }
}

Si on est joueur, on peut (fin 2018) déjà utiliser les nouvelles fonctionnalités Javascript de l'élément Number pour tester si on a bien un entier, via Number.isInteger(n), voir cette doc. Attention, il n'y par exemple pas de support Internet Explorer, ni navigateur BlackBerry OS.

16
Utiliser HERE Maps comme fournisseur de tuiles avec Leaflet
Web, Javascript
10 sept 2018

Une bonne alternative aux fournisseurs habituels que sont Google Maps ou OpenStreetMaps est Here Maps (ex-Nokia, aujourd'hui détenu par les constructeurs automobile allemands, ). D'expérience c'est un peu plus lent que Google Maps mais on évite la publicité déguisée. Les cartes sont claires et le graphisme élégant.

var HereMaps = L.tileLayer(''https://{s}.aerial.maps.api.here.com/maptile/2.1/maptile/newest/terrain.day/{z}/{x}/{y}/256/png8?app_id=VgTVFr1a0ft1qGcLCVJ6&app_code=LJXqQ8ErW71UsRUK3R33Ow', {
    maxZoom: 20,
    subdomains:['1','2','3','4'],
    attribution: '&copy; HERE'
});

HereMaps.addTo(map);

Plus d'information sur la construction de la requète, voir la documentation de HERE.

Les codes (jeton) API app_code et app_id utilisés ici sont ceux de la carte de la page d'accueil de HERE. C'est très probablement interdit de l'utiliser pour vos projets et risque de changer dans le temps. A noter que HERE propose un service gratuit sous 250 000 transactions par an pour vous procurer vos propres codes.

Pour info, pour récupérer les codes API courants de la carte publique HERE, le plus simple est d'écouter les requêtes serveurs en naviguant sur la page. Faites Ctrl+Maj+I, onglet Réseau, déplacez vous sur la carte et regardez les adresses des tuiles qui chargent.

Mise à jour : adresse mise à jour au 29/11/20.

15
Commande Rhino équivalente au MatchProperties d'Autocad
Python, Rhino3D
24 août 2018
import rhinoscriptsyntax as rs

def acadMatch(source):
    rs.Command("_SelWindow")

    targets = rs.SelectedObjects()
    if targets:
        rs.MatchObjectAttributes(targets, source)
        rs.UnselectAllObjects()
        acadMatch(source)
    else:
        print "No target object found."

sources = rs.SelectedObjects()
if len(sources) > 0:
    source = sources[0]
else:
    source = rs.GetObject("Select source object")

if source:
    rs.UnselectAllObjects()
    acadMatch(source)
else:
    print "No source object found."

A ajouter dans un bouton (voir article. On peut même prendre l'icône d'Autocad pour faire encore plus vrai.

14
HTTPS, HSTS et redirection chez OVH
Web
14 août 2018

Pour forcer l'usage de SSL pour l'accès à votre site, c'est-à-dire forcer l'accès via « https:// » plutôt que « http:// », il convient d'ajouter les lignes suivantes à votre fichier .htaccess. Le code ci-dessous supprime aussi au passage le « www. » qui peut se glisser après « http:// ».

RewriteEngine on
RewriteCond %{SERVER_PORT} 80 [OR]
RewriteCond %{HTTP_HOST}  ^www\.website\.com$ [NC]
RewriteRule ^(.*) https://website.com/$1 [QSA,L,R=301]

Le code a pour effet de réécrire toutes les adresses en ajoutant un « s » à « http:// » pour forcer l'usage de ce protocole. On sait que cela a comme inconvénient de permettre initialement la connexion en HTTP (non sécurisée) pour lire le fichier .htaccess et seulement ensuite rediriger vers la page en HTTPS. Lors de cette première connexion non sécurisée une interception, puis éventuellement redirection vers un site maquillé, est possible. C'est le cas à chaque fois que l'on se connecte au site sans « https:// » dans l'adresse. Pour cette raison, HSTS (HTTP Strict Transport Security) a été inventé. Cette option enregistre sur le navigateur client et pour une durée donnée la préférence d'accès en HTTPS à tel site et opère la réécriture directement au niveau du navigateur client. On a ainsi besoin de se connecter qu'une seule fois de manière non sécurisée pour lire le fichier .htaccess. Cela limite les risques. HSTS se définit comme suit, dans le fichier .htaccess.

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

On peut même inscrire son site sur une liste blanche que les navigateurs ont en mémoire à l'installation et éviter absolument toute connexion non sécurisée.

Le risque, c'est que si le site en question n'a pas de certificat SSL, le perd, ou redirige vers un autre site sans certificat, le navigateur revoie un erreur. Et l'on ne pourra plus se connecter en HTTP au site car le navigateur a enregistré qu'il fallait toujours se connecter en HTTPS. Changer votre .htaccess n'aura pas d'effet, car l'information est stockée localement sur le navigateur de vos visiteurs. Cela, jusqu'à l'expiration du max-age (en secondes) défini dans le .htaccess comme ci-dessus. Le HSTS est donc assez dangereux si on y prend pas garde, surtout si vous le configurez pour une durée longue. Pour info, vous pouvez effacer la mémoire de votre navigateur concernant les préférence HSTS de tel site. Sur Firefox, voir Historique > clic droit sur le site Oublier ce site.

Si vous avez configuré des redirections avec votre hébergement OVH, elles ne pourront pas se faire en HTTPS à ma connaissance. Elles pourront cependant bien mener en bout de chaîne à une page en HTTPS. Par exemple, http://page.domaine.co peut rediriger vers https://domaine.com/pages/page mais l'accès à https://page.domaine.com vous renverra une erreur de certificat. En effet, le serveur de redirection d'OVH par lequel on transit est différent du serveur prévu dans le certificat délivré pour votre site. Pour renvoyer vers une page en HTTPS, il faut opter pour une redirection visible. Ainsi, si vous utilisez les redirections OVH, il ne faut pas utiliser HSTS.

Attention, des applications (CMS ou autre) que vous avez installé sur votre site, peuvent contenir des directives HSTS dans le .htaccess de leur sous-dossier mais qui s'appliquent à l'ensemble du domaine. C'est le cas de Own/Next-cloud ou FileRun par exemple. Il faudra alors éditer le fichier .htaccess en question et mettre un "#" devant la ligne configurant le HSTS pour le désactiver.