Plugin pour composer des pages avec des blocks de différents types

Commit initial en sortie de la fabrique
dev/crayons
nicod_ 2 months ago
commit 1463768917

@ -0,0 +1,90 @@
<?php
/**
* Utilisation de l'action supprimer pour l'objet blocs_type
*
* @plugin Blocks
* @copyright 2023
* @author nicod_
* @licence GNU/GPL
* @package SPIP\Blocks\Action
*/
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
/**
* Action pour supprimer un·e blocs_type
*
* Vérifier l'autorisation avant d'appeler l'action.
*
* @param null|int $arg
* Identifiant à supprimer.
* En absence de id utilise l'argument de l'action sécurisée.
**/
function action_supprimer_blocs_type_dist($arg = null) {
$need_confirm = false;
if (is_null($arg)) {
$securiser_action = charger_fonction('securiser_action', 'inc');
$arg = $securiser_action();
$need_confirm = true;
}
$arg = intval($arg);
if ($need_confirm) {
$ok = confirmer_supprimer_blocs_type_avant_action(_T('blocs_type:confirmer_supprimer_blocs_type'), _T('item_oui') . '! ' . _T('blocs_type:supprimer_blocs_type'));
}
// cas suppression
if (autoriser('supprimer', 'blocs_type', $arg)) {
if ($arg) {
$objet = sql_fetsel('*', 'spip_blocs_types', 'id_blocs_type=' . sql_quote($arg));
$qui = (!empty($GLOBALS['visiteur_session']['id_auteur']) ? 'auteur #' . $GLOBALS['visiteur_session']['id_auteur'] : 'IP ' . $GLOBALS['ip']);
spip_log("SUPPRESSION blocs_type#$arg par $qui : " . json_encode($objet), "suppressions" . _LOG_INFO_IMPORTANTE);
sql_delete('spip_blocs_types', 'id_blocs_type=' . sql_quote($arg));
include_spip('action/editer_logo');
logo_supprimer('spip_blocs_types', $arg, 'on');
logo_supprimer('spip_blocs_types', $arg, 'off');
// invalider le cache
include_spip('inc/invalideur');
suivre_invalideur("id='blocs_type/$arg'");
} else {
spip_log("action_supprimer_blocs_type_dist $arg pas compris");
}
}
}
/**
* Confirmer avant suppression si on arrive par un bouton action
* @param string $titre
* @param string $titre_bouton
* @param string|null $url_action
* @return bool
*/
function confirmer_supprimer_blocs_type_avant_action($titre, $titre_bouton, $url_action = null) {
if (!$url_action) {
$url_action = self();
$action = _request('action');
$url_action = parametre_url($url_action, 'action', $action, '&');
} else {
$action = parametre_url($url_action, 'action');
}
$arg = parametre_url($url_action, 'arg');
$confirm = md5("$action:$arg:" . realpath(__FILE__));
if (_request('confirm_action') === $confirm) {
return true;
}
$url_confirm = parametre_url($url_action, "confirm_action", $confirm, '&');
include_spip("inc/filtres");
$bouton_action = bouton_action($titre_bouton, $url_confirm);
$corps = "<div style='text-align:center;'>$bouton_action</div>";
include_spip("inc/minipres");
echo minipres($titre, $corps);
exit;
}

@ -0,0 +1,111 @@
<?php
/**
* Déclarations relatives à la base de données
*
* @plugin Blocks
* @copyright 2023
* @author nicod_
* @licence GNU/GPL
* @package SPIP\Blocks\Pipelines
*/
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
/**
* Déclaration des alias de tables et filtres automatiques de champs
*
* @pipeline declarer_tables_interfaces
* @param array $interfaces
* Déclarations d'interface pour le compilateur
* @return array
* Déclarations d'interface pour le compilateur
*/
function blocks_declarer_tables_interfaces($interfaces) {
$interfaces['table_des_tables']['blocs'] = 'blocs';
$interfaces['table_des_tables']['blocs_types'] = 'blocs_types';
return $interfaces;
}
/**
* Déclaration des objets éditoriaux
*
* @pipeline declarer_tables_objets_sql
* @param array $tables
* Description des tables
* @return array
* Description complétée des tables
*/
function blocks_declarer_tables_objets_sql($tables) {
$tables['spip_blocs'] = [
'type' => 'bloc',
'principale' => 'oui',
'field' => [
'id_bloc' => 'bigint(21) NOT NULL',
'id_blocs_type' => 'bigint(21) NOT NULL DEFAULT 0',
'titre' => 'text',
'valeurs' => 'text NOT NULL DEFAULT ""',
'date' => 'datetime NOT NULL DEFAULT "0000-00-00 00:00:00"',
'statut' => 'varchar(20) DEFAULT "0" NOT NULL',
'maj' => 'timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP',
],
'key' => [
'PRIMARY KEY' => 'id_bloc',
'KEY id_blocs_type' => 'id_blocs_type',
'KEY statut' => 'statut',
],
'titre' => 'titre AS titre, "" AS lang',
'date' => 'date',
'champs_editables' => ['titre', 'id_blocs_type'],
'champs_versionnes' => ['titre', 'valeurs', 'id_blocs_type'],
'rechercher_champs' => ["titre" => 10],
'tables_jointures' => [],
'statut_textes_instituer' => [
'prepa' => 'texte_statut_en_cours_redaction',
'prop' => 'texte_statut_propose_evaluation',
'publie' => 'texte_statut_publie',
'refuse' => 'texte_statut_refuse',
'poubelle' => 'texte_statut_poubelle',
],
'statut' => [
[
'champ' => 'statut',
'publie' => 'publie',
'previsu' => 'publie,prop,prepa',
'post_date' => 'date',
'exception' => ['statut', 'tout'],
],
],
'texte_changer_statut' => 'bloc:texte_changer_statut_bloc',
];
$tables['spip_blocs_types'] = [
'type' => 'blocs_type',
'principale' => 'oui',
'table_objet_surnoms' => ['blocstype'], // table_objet('blocs_type') => 'blocs_types'
'field' => [
'id_blocs_type' => 'bigint(21) NOT NULL',
'titre' => 'text NOT NULL DEFAULT ""',
'id_blocs_type_parent' => 'bigint(21) NOT NULL DEFAULT 0',
'saisies' => 'text NOT NULL DEFAULT ""',
'maj' => 'timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP',
],
'key' => [
'PRIMARY KEY' => 'id_blocs_type',
],
'titre' => 'titre AS titre, "" AS lang',
#'date' => '',
'champs_editables' => ['titre', 'id_blocs_type_parent', 'saisies'],
'champs_versionnes' => ['titre', 'id_blocs_type_parent', 'saisies'],
'rechercher_champs' => ["titre" => 10],
'tables_jointures' => [],
];
return $tables;
}

@ -0,0 +1,56 @@
<?php
/**
* Fichier gérant l'installation et désinstallation du plugin Blocks
*
* @plugin Blocks
* @copyright 2023
* @author nicod_
* @licence GNU/GPL
* @package SPIP\Blocks\Installation
*/
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
/**
* Fonction d'installation et de mise à jour du plugin Blocks.
*
* @param string $nom_meta_base_version
* Nom de la meta informant de la version du schéma de données du plugin installé dans SPIP
* @param string $version_cible
* Version du schéma de données dans ce plugin (déclaré dans paquet.xml)
* @return void
**/
function blocks_upgrade($nom_meta_base_version, $version_cible) {
$maj = [];
$maj['create'] = [['maj_tables', ['spip_blocs', 'spip_blocs_types']]];
include_spip('base/upgrade');
maj_plugin($nom_meta_base_version, $version_cible, $maj);
}
/**
* Fonction de désinstallation du plugin Blocks.
*
* @param string $nom_meta_base_version
* Nom de la meta informant de la version du schéma de données du plugin installé dans SPIP
* @return void
**/
function blocks_vider_tables($nom_meta_base_version) {
sql_drop_table('spip_blocs');
sql_drop_table('spip_blocs_types');
# Nettoyer les liens courants (le génie optimiser_base_disparus se chargera de nettoyer toutes les tables de liens)
sql_delete('spip_documents_liens', sql_in('objet', ['bloc', 'blocs_type']));
sql_delete('spip_mots_liens', sql_in('objet', ['bloc', 'blocs_type']));
sql_delete('spip_auteurs_liens', sql_in('objet', ['bloc', 'blocs_type']));
# Nettoyer les versionnages et forums
sql_delete('spip_versions', sql_in('objet', ['bloc', 'blocs_type']));
sql_delete('spip_versions_fragments', sql_in('objet', ['bloc', 'blocs_type']));
sql_delete('spip_forum', sql_in('objet', ['bloc', 'blocs_type']));
effacer_meta($nom_meta_base_version);
}

@ -0,0 +1,242 @@
<?php
/**
* Définit les autorisations du plugin Blocks
*
* @plugin Blocks
* @copyright 2023
* @author nicod_
* @licence GNU/GPL
* @package SPIP\Blocks\Autorisations
*/
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
/**
* Fonction d'appel pour le pipeline
* @pipeline autoriser
*/
function blocks_autoriser() {
}
// -----------------
// Objet blocs
/**
* Autorisation de voir un élément de menu (blocs)
*
* @param string $faire Action demandée
* @param string $type Type d'objet sur lequel appliquer l'action
* @param int $id Identifiant de l'objet
* @param array $qui Description de l'auteur demandant l'autorisation
* @param array $opt Options de cette autorisation
* @return bool true s'il a le droit, false sinon
**/
function autoriser_blocs_menu_dist($faire, $type, $id, $qui, $opt) {
return true;
}
/**
* Autorisation de voir (blocs)
*
* @param string $faire Action demandée
* @param string $type Type d'objet sur lequel appliquer l'action
* @param int $id Identifiant de l'objet
* @param array $qui Description de l'auteur demandant l'autorisation
* @param array $opt Options de cette autorisation
* @return bool true s'il a le droit, false sinon
**/
function autoriser_blocs_voir_dist($faire, $type, $id, $qui, $opt) {
return true;
}
/**
* Autorisation de voir (bloc)
*
* @param string $faire Action demandée
* @param string $type Type d'objet sur lequel appliquer l'action
* @param int $id Identifiant de l'objet
* @param array $qui Description de l'auteur demandant l'autorisation
* @param array $opt Options de cette autorisation
* @return bool true s'il a le droit, false sinon
**/
function autoriser_bloc_voir_dist($faire, $type, $id, $qui, $opt) {
return true;
}
/**
* Autorisation de créer (bloc)
*
* @param string $faire Action demandée
* @param string $type Type d'objet sur lequel appliquer l'action
* @param int $id Identifiant de l'objet
* @param array $qui Description de l'auteur demandant l'autorisation
* @param array $opt Options de cette autorisation
* @return bool true s'il a le droit, false sinon
**/
function autoriser_bloc_creer_dist($faire, $type, $id, $qui, $opt) {
return in_array($qui['statut'], ['0minirezo', '1comite']);
}
/**
* Autorisation de modifier (bloc)
*
* @param string $faire Action demandée
* @param string $type Type d'objet sur lequel appliquer l'action
* @param int $id Identifiant de l'objet
* @param array $qui Description de l'auteur demandant l'autorisation
* @param array $opt Options de cette autorisation
* @return bool true s'il a le droit, false sinon
**/
function autoriser_bloc_modifier_dist($faire, $type, $id, $qui, $opt) {
return in_array($qui['statut'], ['0minirezo', '1comite']);
}
/**
* Autorisation de supprimer (bloc)
*
* @param string $faire Action demandée
* @param string $type Type d'objet sur lequel appliquer l'action
* @param int $id Identifiant de l'objet
* @param array $qui Description de l'auteur demandant l'autorisation
* @param array $opt Options de cette autorisation
* @return bool true s'il a le droit, false sinon
**/
function autoriser_bloc_supprimer_dist($faire, $type, $id, $qui, $opt) {
return ($qui['statut'] == '0minirezo' and !$qui['restreint'])
or (blocks_autoriser_statuts('bloc', $id, $qui, $opt)
and $auteurs = blocks_auteurs_objet('bloc', $id) and in_array($qui['id_auteur'], $auteurs));
}
/**
* Autorisation de créer l'élément (bloc) dans un blocs_types
*
* @param string $faire Action demandée
* @param string $type Type d'objet sur lequel appliquer l'action
* @param int $id Identifiant de l'objet
* @param array $qui Description de l'auteur demandant l'autorisation
* @param array $opt Options de cette autorisation
* @return bool true s'il a le droit, false sinon
**/
function autoriser_blocstype_creerblocdans_dist($faire, $type, $id, $qui, $opt) {
return ($id and autoriser('voir', 'blocs_types', $id) and autoriser('creer', 'bloc'));
}
// -----------------
// Objet blocs_types
/**
* Autorisation de voir un élément de menu (blocstypes)
*
* @param string $faire Action demandée
* @param string $type Type d'objet sur lequel appliquer l'action
* @param int $id Identifiant de l'objet
* @param array $qui Description de l'auteur demandant l'autorisation
* @param array $opt Options de cette autorisation
* @return bool true s'il a le droit, false sinon
**/
function autoriser_blocstypes_menu_dist($faire, $type, $id, $qui, $opt) {
return true;
}
/**
* Autorisation de voir (blocstypes)
*
* @param string $faire Action demandée
* @param string $type Type d'objet sur lequel appliquer l'action
* @param int $id Identifiant de l'objet
* @param array $qui Description de l'auteur demandant l'autorisation
* @param array $opt Options de cette autorisation
* @return bool true s'il a le droit, false sinon
**/
function autoriser_blocstypes_voir_dist($faire, $type, $id, $qui, $opt) {
return true;
}
/**
* Autorisation de voir (blocstype)
*
* @param string $faire Action demandée
* @param string $type Type d'objet sur lequel appliquer l'action
* @param int $id Identifiant de l'objet
* @param array $qui Description de l'auteur demandant l'autorisation
* @param array $opt Options de cette autorisation
* @return bool true s'il a le droit, false sinon
**/
function autoriser_blocstype_voir_dist($faire, $type, $id, $qui, $opt) {
return true;
}
/**
* Autorisation de créer (blocstype)
*
* @param string $faire Action demandée
* @param string $type Type d'objet sur lequel appliquer l'action
* @param int $id Identifiant de l'objet
* @param array $qui Description de l'auteur demandant l'autorisation
* @param array $opt Options de cette autorisation
* @return bool true s'il a le droit, false sinon
**/
function autoriser_blocstype_creer_dist($faire, $type, $id, $qui, $opt) {
return autoriser('webmestre', '', '', $qui);
}
/**
* Autorisation de modifier (blocstype)
*
* @param string $faire Action demandée
* @param string $type Type d'objet sur lequel appliquer l'action
* @param int $id Identifiant de l'objet
* @param array $qui Description de l'auteur demandant l'autorisation
* @param array $opt Options de cette autorisation
* @return bool true s'il a le droit, false sinon
**/
function autoriser_blocstype_modifier_dist($faire, $type, $id, $qui, $opt) {
return autoriser('webmestre', '', '', $qui);
}
/**
* Autorisation de supprimer (blocstype)
*
* @param string $faire Action demandée
* @param string $type Type d'objet sur lequel appliquer l'action
* @param int $id Identifiant de l'objet
* @param array $qui Description de l'auteur demandant l'autorisation
* @param array $opt Options de cette autorisation
* @return bool true s'il a le droit, false sinon
**/
function autoriser_blocstype_supprimer_dist($faire, $type, $id, $qui, $opt) {
return autoriser('webmestre', '', '', $qui);
}
/**
* Lister les auteurs liés à un objet
*
* @param int $objet Type de l'objet
* @param int $id_objet Identifiant de l'objet
* @return array Liste des id_auteur trouvés
*/
function blocks_auteurs_objet($objet, $id_objet) {
$auteurs = sql_allfetsel('id_auteur', 'spip_auteurs_liens', ['objet = ' . sql_quote($objet), 'id_objet = ' . intval($id_objet)]);
if (is_array($auteurs)) {
return array_column($auteurs, 'id_auteur');
}
return [];
}
/**
* Tester si le statut de l'objet autorise des changements, en fonction du statut de l'auteur.
*
* @param string $objet Type d'objet
* @param int $id_objet Identifiant de l'objet
* @param array $qui Description de l'auteur demandant l'autorisation
* @param array $opt Options de l'autorisation
* @return bool true s'il a le droit, false sinon
**/
function blocks_autoriser_statuts($objet, $id_objet, $qui, $opt) {
$statut = sql_getfetsel('statut', table_objet_sql($objet), id_table_objet($objet) . ' = ' . intval($id_objet));
return (!isset($opt['statut']) or $opt['statut'] !== 'publie')
and in_array($qui['statut'], ['0minirezo', '1comite'])
and in_array($statut, ['prop', 'prepa', 'poubelle']);
}

@ -0,0 +1,14 @@
<?php
/**
* Fonctions utiles au plugin Blocks
*
* @plugin Blocks
* @copyright 2023
* @author nicod_
* @licence GNU/GPL
* @package SPIP\Blocks\Fonctions
*/
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}

@ -0,0 +1,14 @@
<?php
/**
* Options au chargement du plugin Blocks
*
* @plugin Blocks
* @copyright 2023
* @author nicod_
* @licence GNU/GPL
* @package SPIP\Blocks\Options
*/
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}

@ -0,0 +1,108 @@
<?php
/**
* Utilisations de pipelines par Blocks
*
* @plugin Blocks
* @copyright 2023
* @author nicod_
* @licence GNU/GPL
* @package SPIP\Blocks\Pipelines
*/
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
/**
* Ajouter les objets sur les vues des parents directs
*
* @pipeline affiche_enfants
* @param array $flux Données du pipeline
* @return array Données du pipeline
**/
function blocks_affiche_enfants($flux) {
if (
$e = trouver_objet_exec($flux['args']['exec'])
and $e['edition'] === false
) {
$id_objet = $flux['args']['id_objet'];
if ($e['type'] === 'blocs_type') {
$flux['data'] .= recuperer_fond(
'prive/objets/liste/blocs',
[
'titre' => _T('bloc:titre_blocs'),
'id_blocs_type' => $id_objet,
]
);
if (autoriser('creerblocdans', 'blocs_types', $id_objet)) {
include_spip('inc/presentation');
$flux['data'] .= icone_verticale(
_T('bloc:icone_creer_bloc'),
generer_url_ecrire('bloc_edit', "id_blocs_type=$id_objet"),
'bloc-24.png',
'new',
'right'
) . "<br class='nettoyeur' />";
}
}
}
return $flux;
}
/**
* Afficher le nombre d'éléments dans les parents
*
* @pipeline boite_infos
* @param array $flux Données du pipeline
* @return array Données du pipeline
**/
function blocks_boite_infos($flux) {
if (isset($flux['args']['type']) and isset($flux['args']['id']) and $id = intval($flux['args']['id'])) {
$texte = '';
if ($flux['args']['type'] == 'blocs_type' and $nb = sql_countsel('spip_blocs', ["statut='publie'", 'id_blocs_type=' . $id])) {
$texte .= '<div>' . singulier_ou_pluriel($nb, 'bloc:info_1_bloc', 'bloc:info_nb_blocs') . "</div>\n";
}
if ($texte and $p = strpos($flux['data'], '<!--nb_elements-->')) {
$flux['data'] = substr_replace($flux['data'], $texte, $p, 0);
}
}
return $flux;
}
/**
* Compter les enfants d'un objet
*
* @pipeline objets_compte_enfants
* @param array $flux Données du pipeline
* @return array Données du pipeline
**/
function blocks_objet_compte_enfants($flux) {
if ($flux['args']['objet'] == 'blocs_type' and $id_blocs_type = intval($flux['args']['id_objet'])) {
// juste les publiés ?
if (array_key_exists('statut', $flux['args']) and ($flux['args']['statut'] == 'publie')) {
$flux['data']['blocs'] = sql_countsel('spip_blocs', 'id_blocs_type= ' . intval($id_blocs_type) . " AND (statut = 'publie')");
} else {
$flux['data']['blocs'] = sql_countsel('spip_blocs', 'id_blocs_type= ' . intval($id_blocs_type) . " AND (statut <> 'poubelle')");
}
}
return $flux;
}
/**
* Optimiser la base de données
*
* Supprime les objets à la poubelle.
*
* @pipeline optimiser_base_disparus
* @param array $flux Données du pipeline
* @return array Données du pipeline
*/
function blocks_optimiser_base_disparus($flux) {
sql_delete('spip_blocs', "statut='poubelle' AND maj < " . $flux['args']['date']);
return $flux;
}

@ -0,0 +1,16 @@
<div class="formulaire_spip formulaire_configurer formulaire_#FORM">
<h3 class="titrem"><:blocks:cfg_titre_parametrages:/></h3>
[<p class="reponse_formulaire reponse_formulaire_ok">(#ENV*{message_ok})</p>]
[<p class="reponse_formulaire reponse_formulaire_erreur">(#ENV*{message_erreur})</p>]
<form method="post" action="#ENV{action}">
<div>
#ACTION_FORMULAIRE
<input type="hidden" name="_meta_casier" value="blocks" />
<p class="boutons"><span class="image_loading">&nbsp;</span><input type="submit" class="submit" value="<:bouton_enregistrer|attribut_html:/>" /></p>
</div>
</form>
</div>

@ -0,0 +1,19 @@
<div class='formulaire_spip formulaire_editer formulaire_#FORM formulaire_#FORM-#ENV{id_bloc,nouveau}'>
[<p class="reponse_formulaire reponse_formulaire_ok">(#ENV**{message_ok})</p>]
[<p class="reponse_formulaire reponse_formulaire_erreur">(#ENV*{message_erreur})</p>]
[(#ENV{editable})
<form method="post" action="#ENV{action}"><div>
#ACTION_FORMULAIRE
<input type="hidden" name="id_bloc" value="#ENV{id_bloc}" />
<div class="editer-groupe">
#GENERER_SAISIES{#ENV*{_saisies}}
</div>
[(#REM) ajouter les saisies supplementaires : extra et autre, a cet endroit ]
<!--extra-->
<p class="boutons"><input type="submit" class="submit" value="<:bouton_enregistrer|attribut_html:/>" /></p>
</div></form>
]
</div>

@ -0,0 +1,179 @@
<?php
/**
* Gestion du formulaire de d'édition de bloc
*
* @plugin Blocks
* @copyright 2023
* @author nicod_
* @licence GNU/GPL
* @package SPIP\Blocks\Formulaires
*/
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
include_spip('inc/actions');
include_spip('inc/editer');
/**
* Déclaration des saisies de bloc
*
* @param int|string $id_bloc
* Identifiant du bloc. 'new' pour un nouveau bloc.
* @param int $id_blocs_type
* Identifiant de l'objet parent (si connu)
* @param string $retour
* URL de redirection après le traitement
* @param int $lier_trad
* Identifiant éventuel d'un bloc source d'une traduction
* @param string $config_fonc
* Nom de la fonction ajoutant des configurations particulières au formulaire
* @param array $row
* Valeurs de la ligne SQL du bloc, si connu
* @param string $hidden
* Contenu HTML ajouté en même temps que les champs cachés du formulaire.
* @return string
* Hash du formulaire
*/
function formulaires_editer_bloc_saisies_dist($id_bloc = 'new', $id_blocs_type = 0, $retour = '', $lier_trad = 0, $config_fonc = '', $row = [], $hidden = '') {
$saisies = [
[
'saisie' => 'input',
'options' => [
'nom' => 'titre',
'obligatoire' => 'oui',
'label' => _T('bloc:champ_titre_label'),
],
],
[
'saisie' => 'blocs_types',
'options' => [
'nom' => 'id_blocs_type',
'obligatoire' => 'oui',
'label' => _T('blocs_type:titre_blocs_type'),
],
],
];
return $saisies;
}
/**
* Identifier le formulaire en faisant abstraction des paramètres qui ne représentent pas l'objet edité
*
* @param int|string $id_bloc
* Identifiant du bloc. 'new' pour un nouveau bloc.
* @param int $id_blocs_type
* Identifiant de l'objet parent (si connu)
* @param string $retour
* URL de redirection après le traitement
* @param int $lier_trad
* Identifiant éventuel d'un bloc source d'une traduction
* @param string $config_fonc
* Nom de la fonction ajoutant des configurations particulières au formulaire
* @param array $row
* Valeurs de la ligne SQL du bloc, si connu
* @param string $hidden
* Contenu HTML ajouté en même temps que les champs cachés du formulaire.
* @return string
* Hash du formulaire
*/
function formulaires_editer_bloc_identifier_dist($id_bloc = 'new', $id_blocs_type = 0, $retour = '', $lier_trad = 0, $config_fonc = '', $row = [], $hidden = '') {
return serialize([intval($id_bloc)]);
}
/**
* Chargement du formulaire d'édition de bloc
*
* Déclarer les champs postés et y intégrer les valeurs par défaut
*
* @param int|string $id_bloc
* Identifiant du bloc. 'new' pour un nouveau bloc.
* @param int $id_blocs_type
* Identifiant de l'objet parent (si connu)
* @param string $retour
* URL de redirection après le traitement
* @param int $lier_trad
* Identifiant éventuel d'un bloc source d'une traduction
* @param string $config_fonc
* Nom de la fonction ajoutant des configurations particulières au formulaire
* @param array $row
* Valeurs de la ligne SQL du bloc, si connu
* @param string $hidden
* Contenu HTML ajouté en même temps que les champs cachés du formulaire.
* @return array
* Environnement du formulaire
* @uses formulaires_editer_objet_charger()
*
*/
function formulaires_editer_bloc_charger_dist($id_bloc = 'new', $id_blocs_type = 0, $retour = '', $lier_trad = 0, $config_fonc = '', $row = [], $hidden = '') {
$valeurs = formulaires_editer_objet_charger('bloc', $id_bloc, $id_blocs_type, $lier_trad, $retour, $config_fonc, $row, $hidden);
if (!$valeurs['id_blocs_type']) {
$valeurs['id_blocs_type'] = $id_blocs_type;
}
$valeurs['saisies'] = call_user_func_array('formulaires_editer_bloc_saisies_dist', func_get_args());
return $valeurs;
}
/**
* Vérifications du formulaire d'édition de bloc
*
* Vérifier les champs postés et signaler d'éventuelles erreurs
*
* @param int|string $id_bloc
* Identifiant du bloc. 'new' pour un nouveau bloc.
* @param int $id_blocs_type
* Identifiant de l'objet parent (si connu)
* @param string $retour
* URL de redirection après le traitement
* @param int $lier_trad
* Identifiant éventuel d'un bloc source d'une traduction
* @param string $config_fonc
* Nom de la fonction ajoutant des configurations particulières au formulaire
* @param array $row
* Valeurs de la ligne SQL du bloc, si connu
* @param string $hidden
* Contenu HTML ajouté en même temps que les champs cachés du formulaire.
* @return array
* Tableau des erreurs
* @uses formulaires_editer_objet_verifier()
*
*/
function formulaires_editer_bloc_verifier_dist($id_bloc = 'new', $id_blocs_type = 0, $retour = '', $lier_trad = 0, $config_fonc = '', $row = [], $hidden = '') {
$erreurs = formulaires_editer_objet_verifier('bloc', $id_bloc, ['titre', 'id_blocs_type']);
return $erreurs;
}
/**
* Traitement du formulaire d'édition de bloc
*
* Traiter les champs postés
*
* @param int|string $id_bloc
* Identifiant du bloc. 'new' pour un nouveau bloc.
* @param int $id_blocs_type
* Identifiant de l'objet parent (si connu)
* @param string $retour
* URL de redirection après le traitement
* @param int $lier_trad
* Identifiant éventuel d'un bloc source d'une traduction
* @param string $config_fonc
* Nom de la fonction ajoutant des configurations particulières au formulaire
* @param array $row
* Valeurs de la ligne SQL du bloc, si connu
* @param string $hidden
* Contenu HTML ajouté en même temps que les champs cachés du formulaire.
* @return array
* Retours des traitements
* @uses formulaires_editer_objet_traiter()
*
*/
function formulaires_editer_bloc_traiter_dist($id_bloc = 'new', $id_blocs_type = 0, $retour = '', $lier_trad = 0, $config_fonc = '', $row = [], $hidden = '') {
$retours = formulaires_editer_objet_traiter('bloc', $id_bloc, $id_blocs_type, $lier_trad, $retour, $config_fonc, $row, $hidden);
return $retours;
}

@ -0,0 +1,19 @@
<div class='formulaire_spip formulaire_editer formulaire_#FORM formulaire_#FORM-#ENV{id_blocs_type,nouveau}'>
[<p class="reponse_formulaire reponse_formulaire_ok">(#ENV**{message_ok})</p>]
[<p class="reponse_formulaire reponse_formulaire_erreur">(#ENV*{message_erreur})</p>]
[(#ENV{editable})
<form method="post" action="#ENV{action}"><div>
#ACTION_FORMULAIRE
<input type="hidden" name="id_blocs_type" value="#ENV{id_blocs_type}" />
<div class="editer-groupe">
#GENERER_SAISIES{#ENV*{_saisies}}
</div>
[(#REM) ajouter les saisies supplementaires : extra et autre, a cet endroit ]
<!--extra-->
<p class="boutons"><input type="submit" class="submit" value="<:bouton_enregistrer|attribut_html:/>" /></p>
</div></form>
]
</div>

@ -0,0 +1,168 @@
<?php
/**
* Gestion du formulaire de d'édition de blocs_type
*
* @plugin Blocks
* @copyright 2023
* @author nicod_
* @licence GNU/GPL
* @package SPIP\Blocks\Formulaires
*/
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
include_spip('inc/actions');
include_spip('inc/editer');
/**
* Déclaration des saisies de blocs_type
*
* @param int|string $id_blocs_type
* Identifiant du blocs_type. 'new' pour un nouveau blocs_type.
* @param string $retour
* URL de redirection après le traitement
* @param int $lier_trad
* Identifiant éventuel d'un blocs_type source d'une traduction
* @param string $config_fonc
* Nom de la fonction ajoutant des configurations particulières au formulaire
* @param array $row
* Valeurs de la ligne SQL du blocs_type, si connu
* @param string $hidden
* Contenu HTML ajouté en même temps que les champs cachés du formulaire.
* @return string
* Hash du formulaire
*/
function formulaires_editer_blocs_type_saisies_dist($id_blocs_type = 'new', $retour = '', $lier_trad = 0, $config_fonc = '', $row = [], $hidden = '') {
$saisies = [
[
'saisie' => 'input',
'options' => [
'nom' => 'titre',
'obligatoire' => 'oui',
'label' => _T('blocs_type:champ_titre_label'),
],
],
[
'saisie' => 'blocs_types',
'options' => [
'nom' => 'id_blocs_type_parent',
'label' => _T('blocs_type:champ_id_blocs_type_parent_label'),
],
],
];
return $saisies;
}
/**
* Identifier le formulaire en faisant abstraction des paramètres qui ne représentent pas l'objet edité
*
* @param int|string $id_blocs_type
* Identifiant du blocs_type. 'new' pour un nouveau blocs_type.
* @param string $retour
* URL de redirection après le traitement
* @param int $lier_trad
* Identifiant éventuel d'un blocs_type source d'une traduction
* @param string $config_fonc
* Nom de la fonction ajoutant des configurations particulières au formulaire
* @param array $row
* Valeurs de la ligne SQL du blocs_type, si connu
* @param string $hidden
* Contenu HTML ajouté en même temps que les champs cachés du formulaire.
* @return string
* Hash du formulaire
*/
function formulaires_editer_blocs_type_identifier_dist($id_blocs_type = 'new', $retour = '', $lier_trad = 0, $config_fonc = '', $row = [], $hidden = '') {
return serialize([intval($id_blocs_type)]);
}
/**
* Chargement du formulaire d'édition de blocs_type
*
* Déclarer les champs postés et y intégrer les valeurs par défaut
*
* @param int|string $id_blocs_type
* Identifiant du blocs_type. 'new' pour un nouveau blocs_type.
* @param string $retour
* URL de redirection après le traitement
* @param int $lier_trad
* Identifiant éventuel d'un blocs_type source d'une traduction
* @param string $config_fonc
* Nom de la fonction ajoutant des configurations particulières au formulaire
* @param array $row
* Valeurs de la ligne SQL du blocs_type, si connu
* @param string $hidden
* Contenu HTML ajouté en même temps que les champs cachés du formulaire.
* @return array
* Environnement du formulaire
* @uses formulaires_editer_objet_charger()
*
*/
function formulaires_editer_blocs_type_charger_dist($id_blocs_type = 'new', $retour = '', $lier_trad = 0, $config_fonc = '', $row = [], $hidden = '') {
$valeurs = formulaires_editer_objet_charger('blocs_type', $id_blocs_type, '', $lier_trad, $retour, $config_fonc, $row, $hidden);
$valeurs['saisies'] = call_user_func_array('formulaires_editer_blocs_type_saisies_dist', func_get_args());
return $valeurs;
}
/**
* Vérifications du formulaire d'édition de blocs_type
*
* Vérifier les champs postés et signaler d'éventuelles erreurs
*
* @param int|string $id_blocs_type
* Identifiant du blocs_type. 'new' pour un nouveau blocs_type.
* @param string $retour
* URL de redirection après le traitement
* @param int $lier_trad
* Identifiant éventuel d'un blocs_type source d'une traduction
* @param string $config_fonc
* Nom de la fonction ajoutant des configurations particulières au formulaire
* @param array $row
* Valeurs de la ligne SQL du blocs_type, si connu
* @param string $hidden
* Contenu HTML ajouté en même temps que les champs cachés du formulaire.
* @return array
* Tableau des erreurs
* @uses formulaires_editer_objet_verifier()
*
*/
function formulaires_editer_blocs_type_verifier_dist($id_blocs_type = 'new', $retour = '', $lier_trad = 0, $config_fonc = '', $row = [], $hidden = '') {
$erreurs = formulaires_editer_objet_verifier('blocs_type', $id_blocs_type, ['titre']);
return $erreurs;
}
/**
* Traitement du formulaire d'édition de blocs_type
*
* Traiter les champs postés
*
* @param int|string $id_blocs_type
* Identifiant du blocs_type. 'new' pour un nouveau blocs_type.
* @param string $retour
* URL de redirection après le traitement
* @param int $lier_trad
* Identifiant éventuel d'un blocs_type source d'une traduction
* @param string $config_fonc
* Nom de la fonction ajoutant des configurations particulières au formulaire
* @param array $row
* Valeurs de la ligne SQL du blocs_type, si connu
* @param string $hidden
* Contenu HTML ajouté en même temps que les champs cachés du formulaire.
* @return array
* Retours des traitements
* @uses formulaires_editer_objet_traiter()
*
*/
function formulaires_editer_blocs_type_traiter_dist($id_blocs_type = 'new', $retour = '', $lier_trad = 0, $config_fonc = '', $row = [], $hidden = '') {
$retours = formulaires_editer_objet_traiter('blocs_type', $id_blocs_type, '', $lier_trad, $retour, $config_fonc, $row, $hidden);
return $retours;
}

@ -0,0 +1,45 @@
<?php
// This is a SPIP language file -- Ceci est un fichier langue de SPIP
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
$GLOBALS[$GLOBALS['idx_lang']] = [
// A
'ajouter_lien_bloc' => 'Ajouter ce bloc',
// C
'champ_titre_label' => 'Titre',
'champ_valeurs_label' => 'Valeurs',
'confirmer_supprimer_bloc' => 'Confirmez-vous la suppression de cet bloc ?',
// I
'icone_creer_bloc' => 'Créer un bloc',
'icone_modifier_bloc' => 'Modifier ce bloc',
'info_1_bloc' => 'Un bloc',
'info_aucun_bloc' => 'Aucun bloc',
'info_blocs_auteur' => 'Les blocs de cet auteur',
'info_nb_blocs' => '@nb@ blocs',
// R
'retirer_lien_bloc' => 'Retirer ce bloc',
'retirer_tous_liens_blocs' => 'Retirer tous les blocs',
// S
'supprimer_bloc' => 'Supprimer cet bloc',
// T
'texte_ajouter_bloc' => 'Ajouter un bloc',
'texte_changer_statut_bloc' => 'Ce bloc est :',
'texte_creer_associer_bloc' => 'Créer et associer un bloc',
'texte_definir_comme_traduction_bloc' => 'Ce bloc est une traduction du bloc numéro :',
'titre_bloc' => 'Bloc',
'titre_blocs' => 'Blocs',
'titre_blocs_rubrique' => 'Blocs de la rubrique',
'titre_langue_bloc' => 'Langue de ce bloc',
'titre_logo_bloc' => 'Logo de ce bloc',
'titre_objets_lies_bloc' => 'Liés à ce bloc',
'titre_page_blocs' => 'Les blocs',
];

@ -0,0 +1,18 @@
<?php
// This is a SPIP language file -- Ceci est un fichier langue de SPIP
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
$GLOBALS[$GLOBALS['idx_lang']] = [
// B
'blocks_titre' => 'Blocks',
// C
'cfg_titre_parametrages' => 'Paramétrages',
// T
'titre_page_configurer_blocks' => 'Configurer Blocks',
];

@ -0,0 +1,46 @@
<?php
// This is a SPIP language file -- Ceci est un fichier langue de SPIP
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
$GLOBALS[$GLOBALS['idx_lang']] = [
// A
'ajouter_lien_blocs_type' => 'Ajouter ce type de bloc',
// C
'champ_id_blocs_type_parent_label' => 'Type de bloc parent',
'champ_saisies_label' => 'Saisies',
'champ_titre_label' => 'Titre',
'confirmer_supprimer_blocs_type' => 'Confirmez-vous la suppression de cet type de bloc ?',
// I
'icone_creer_blocs_type' => 'Créer un type de bloc',
'icone_modifier_blocs_type' => 'Modifier ce type de bloc',
'info_1_blocs_type' => 'Un type de bloc',
'info_aucun_blocs_type' => 'Aucun type de bloc',
'info_blocs_types_auteur' => 'Les types de blocs de cet auteur',
'info_nb_blocs_types' => '@nb@ types de blocs',
// R
'retirer_lien_blocs_type' => 'Retirer ce type de bloc',
'retirer_tous_liens_blocs_types' => 'Retirer tous les types de blocs',
// S
'supprimer_blocs_type' => 'Supprimer cet type de bloc',
// T
'texte_ajouter_blocs_type' => 'Ajouter un type de bloc',
'texte_changer_statut_blocs_type' => 'Ce type de bloc est :',
'texte_creer_associer_blocs_type' => 'Créer et associer un type de bloc',
'texte_definir_comme_traduction_blocs_type' => 'Ce type de bloc est une traduction du type de bloc numéro :',
'titre_blocs_type' => 'Type de bloc',
'titre_blocs_types' => 'Types de blocs',
'titre_blocs_types_rubrique' => 'Types de blocs de la rubrique',
'titre_langue_blocs_type' => 'Langue de ce type de bloc',
'titre_logo_blocs_type' => 'Logo de ce type de bloc',
'titre_objets_lies_blocs_type' => 'Liés à ce type de bloc',
'titre_page_blocs_types' => 'Les types de blocs',
];

@ -0,0 +1,14 @@
<?php
// This is a SPIP language file -- Ceci est un fichier langue de SPIP
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
$GLOBALS[$GLOBALS['idx_lang']] = [
// B
'blocks_description' => '',
'blocks_nom' => 'Blocks',
'blocks_slogan' => 'Composer des pages avec des blocs',
];

@ -0,0 +1,32 @@
<paquet
prefix="blocks"
version="1.0.0"
etat="dev"
compatibilite="[4.2.0;4.2.*]"
logo="prive/themes/spip/images/blocks-xx.svg"
documentation=""
schema="1.0.0"
>
<nom>Blocks</nom>
<!-- Composer des pages avec des blocs -->
<auteur lien='https://contrib.spip.net/nicod_'>nicod_</auteur>
<licence>GNU/GPL</licence>
<necessite nom="saisies" compatibilite="[3.50.1;]"/>
<pipeline nom="autoriser" inclure="blocks_autorisations.php"/>
<pipeline nom="declarer_tables_objets_sql" inclure="base/blocks.php"/>
<pipeline nom="declarer_tables_interfaces" inclure="base/blocks.php"/>
<pipeline nom="affiche_enfants" inclure="blocks_pipelines.php"/>
<pipeline nom="boite_infos" inclure="blocks_pipelines.php"/>
<pipeline nom="objet_compte_enfants" inclure="blocks_pipelines.php"/>
<pipeline nom="optimiser_base_disparus" inclure="blocks_pipelines.php"/>
<menu nom="blocs" titre="bloc:titre_blocs" parent="menu_edition" icone="images/bloc-16.png" action="blocs"/>
<menu nom="blocs_types" titre="blocs_type:titre_blocs_types" parent="menu_edition" icone="images/blocs_type-16.png"
action="blocs_types"/>
</paquet>

@ -0,0 +1,12 @@
<BOUCLE_bloc(BLOCS){id_bloc}{statut?}>
[<div class="champ contenu_titre[ (#TITRE*|strlen|?{'',vide})]">
<div class="label"><:bloc:champ_titre_label:/> : </div>
<span dir="#LANG_DIR" class="#EDIT{titre} titre">(#TITRE)</span>
</div>]
[<div class="champ contenu_valeurs[ (#VALEURS*|strlen|?{'',vide})]">
<div class="label"><:bloc:champ_valeurs_label:/> : </div>
<span dir="#LANG_DIR" class="#EDIT{valeurs} valeurs">(#VALEURS)</span>
</div>]
</BOUCLE_bloc>

@ -0,0 +1,17 @@
<BOUCLE_blocs_type(BLOCS_TYPES){id_blocs_type}>
[<div class="champ contenu_titre[ (#TITRE*|strlen|?{'',vide})]">
<div class="label"><:blocs_type:champ_titre_label:/> : </div>
<span dir="#LANG_DIR" class="#EDIT{titre} titre">(#TITRE)</span>
</div>]
[<div class="champ contenu_id_blocs_type_parent[ (#ID_BLOCS_TYPE_PARENT*|strlen|?{'',vide})]">
<div class="label"><:blocs_type:champ_id_blocs_type_parent_label:/> : </div>
<span dir="#LANG_DIR" class="#EDIT{id_blocs_type_parent} id_blocs_type_parent">(#ID_BLOCS_TYPE_PARENT)</span>
</div>]
[<div class="champ contenu_saisies[ (#SAISIES*|strlen|?{'',vide})]">
<div class="label"><:blocs_type:champ_saisies_label:/> : </div>
<span dir="#LANG_DIR" class="#EDIT{saisies} saisies">(#SAISIES)</span>
</div>]
</BOUCLE_blocs_type>

@ -0,0 +1,30 @@
<BOUCLE_bloc(BLOCS){id_bloc=#ENV{id}}{statut?}>
<div class="infos">
[(#SET{texte_objet,<:bloc:titre_bloc:/>})]
<div class="numero"><:titre_cadre_numero_objet{objet=#GET{texte_objet}}:/><p>#ID_BLOC</p></div>
[(#FORMULAIRE_INSTITUER_OBJET{bloc,#ID_BLOC})]
<div class='nb_elements'><!--nb_elements--></div>
[(#REM)
Bouton voir en ligne
]
<BOUCLE_publie(BLOCS){id_bloc}>
[(#VAL{redirect}
|generer_url_action{type=bloc&id=#ID_BLOC}
|parametre_url{var_mode,calcul}
|icone_horizontale{<:icone_voir_en_ligne:>,racine})]
</BOUCLE_publie>
[(#AUTORISER{previsualiser,bloc,#ID_BLOC,'',#ARRAY{statut,#STATUT}})
[(#VAL{redirect}
|generer_url_action{type=bloc&id=#ID_BLOC}
|parametre_url{var_mode,preview}
|icone_horizontale{<:previsualiser:>,preview})]
]
<//B_publie>
</div>
</BOUCLE_bloc>

@ -0,0 +1,22 @@
<BOUCLE_blocs_type(BLOCS_TYPES){id_blocs_type=#ENV{id}}>
<div class="infos">
[(#SET{texte_objet,<:blocs_type:titre_blocs_type:/>})]
<div class="numero"><:titre_cadre_numero_objet{objet=#GET{texte_objet}}:/><p>#ID_BLOCS_TYPE</p></div>
<div class='nb_elements'><!--nb_elements--></div>
[(#VAL{redirect}
|generer_url_action{type=blocs_type&id=#ID_BLOCS_TYPE}
|parametre_url{var_mode,calcul}
|icone_horizontale{<:icone_voir_en_ligne:>,racine})]
[(#AUTORISER{supprimer, blocs_type, #ID_BLOCS_TYPE}|oui)
<hr />
[(#BOUTON_ACTION{
[(#CHEMIN_IMAGE{blocs_type-del-24.png}|balise_img{<:blocs_type:supprimer_blocs_type:/>}|concat{' ',#VAL{<:blocs_type:supprimer_blocs_type:/>}|wrap{<b>}}|trim)],
#URL_ACTION_AUTEUR{supprimer_blocs_type, #ID_BLOCS_TYPE, #URL_ECRIRE{blocs_types}},
icone s24 horizontale danger blocs_type-del-24, <:blocs_type:confirmer_supprimer_blocs_type:/>})]
]
</div>
</BOUCLE_blocs_type>

@ -0,0 +1,39 @@
[(#SET{defaut_tri,#ARRAY{
titre,1,
date,-1,
id_bloc,1,
points,-1
}})]<B_liste_blocs>
#ANCRE_PAGINATION
<div class="liste-objets blocs">
<table class="spip liste">
[<caption><strong class="caption">(#ENV*{titre,#GRAND_TOTAL|singulier_ou_pluriel{bloc:info_1_bloc,bloc:info_nb_blocs}})</strong></caption>]
<thead>
<tr class="first_row">
<th class="picto" scope="col"></th>
<th class="statut" scope="col">[(#TRI{statut,<span title="<:lien_trier_statut|attribut_html:/>">#</span>,ajax})]</th>
<th class="titre" scope="col">[(#TRI{titre,<:bloc:champ_titre_label:/>,ajax})]</th>
<th class="date" scope="col">[(#TRI{date,<:date:/>,ajax})]</th>
<th class="id" scope="col">[(#TRI{id_bloc,<:info_numero_abbreviation:/>,ajax})]</th>
</tr>
</thead>
<tbody>
<BOUCLE_liste_blocs(BLOCS){id_blocs_type?}{id_mot?}{id_auteur?}{where?}{statut?}{recherche?}{tri #ENV{par,num titre},#GET{defaut_tri}}{par titre}{pagination #ENV{nb,10}}>
<tr class="[(#COMPTEUR_BOUCLE|alterner{row_odd,row_even})]">
<td class="picto">[(#CHEMIN_IMAGE{bloc-16.png}|balise_img)]</td>
<td class="statut">[(#STATUT|puce_statut{bloc,#ID_BLOC})]</td>
<td class="titre principale">[(#LOGO_BLOC|image_reduire{20,26})]<a href="[(#ID_BLOC|generer_url_entite{bloc})]" title="<:info_numero_abbreviation|attribut_html:/> #ID_BLOC">[(#RANG). ]#TITRE</a></td>
<td class="date secondaire">[(#DATE|affdate_jourcourt)]</td>
<td class="id">[(#AUTORISER{modifier,bloc,#ID_BLOC}|?{
<a href="[(#URL_ECRIRE{bloc_edit,id_bloc=#ID_BLOC})]">#ID_BLOC</a>,
#ID_BLOC
})]</td>
</tr>
</BOUCLE_liste_blocs>
</tbody>
</table>
[<nav role="navigation" class="pagination">(#PAGINATION{prive})</nav>]
</div>
</B_liste_blocs>[
<div class="liste-objets blocs caption-wrap"><strong class="caption">(#ENV*{sinon,''})</strong></div>
]<//B_liste_blocs>

@ -0,0 +1,34 @@
[(#SET{defaut_tri,#ARRAY{
titre,1,
id_blocs_type,1,
points,-1
}})]<B_liste_blocs_types>
#ANCRE_PAGINATION
<div class="liste-objets blocs_types">
<table class="spip liste">
[<caption><strong class="caption">(#ENV*{titre,#GRAND_TOTAL|singulier_ou_pluriel{blocs_type:info_1_blocs_type,blocs_type:info_nb_blocs_types}})</strong></caption>]
<thead>
<tr class="first_row">
<th class="picto" scope="col"></th>
<th class="titre" scope="col">[(#TRI{titre,<:blocs_type:champ_titre_label:/>,ajax})]</th>
<th class="id" scope="col">[(#TRI{id_blocs_type,<:info_numero_abbreviation:/>,ajax})]</th>
</tr>
</thead>
<tbody>
<BOUCLE_liste_blocs_types(BLOCS_TYPES){id_blocs_type_parent?}{id_mot?}{id_auteur?}{where?}{recherche?}{tri #ENV{par,num titre},#GET{defaut_tri}}{par titre}{pagination #ENV{nb,10}}>
<tr class="[(#COMPTEUR_BOUCLE|alterner{row_odd,row_even})]">
<td class="picto">[(#CHEMIN_IMAGE{blocs_type-16.png}|balise_img)]</td>
<td class="titre principale">[(#LOGO_BLOCS_TYPE|image_reduire{20,26})]<a href="[(#ID_BLOCS_TYPE|generer_url_entite{blocs_type})]" title="<:info_numero_abbreviation|attribut_html:/> #ID_BLOCS_TYPE">[(#RANG). ]#TITRE</a></td>
<td class="id">[(#AUTORISER{modifier,blocs_type,#ID_BLOCS_TYPE}|?{
<a href="[(#URL_ECRIRE{blocs_type_edit,id_blocs_type=#ID_BLOCS_TYPE})]">#ID_BLOCS_TYPE</a>,
#ID_BLOCS_TYPE
})]</td>
</tr>
</BOUCLE_liste_blocs_types>
</tbody>
</table>
[<nav role="navigation" class="pagination">(#PAGINATION{prive})</nav>]
</div>
</B_liste_blocs_types>[
<div class="liste-objets blocs_types caption-wrap"><strong class="caption">(#ENV*{sinon,''})</strong></div>
]<//B_liste_blocs_types>

@ -0,0 +1,56 @@
[(#AUTORISER{voir,bloc,#ID_BLOC}|sinon_interdire_acces)]
[(#SET{url_voir,#VAL{bloc}|objet_info{url_voir}})]
[(#SET{url_edit,#VAL{bloc}|objet_info{url_edit}})]
<BOUCLE_bloc(BLOCS){id_bloc}{statut==.*}{si #ENV{exec}|=={#GET{url_voir}}}>
[(#BOITE_OUVRIR{[
[(#AUTORISER{modifier,bloc,#ID_BLOC})
[(#ID_BLOC|afficher_qui_edite{bloc}|non)
[(#URL_ECRIRE{#GET{url_edit},id_bloc=#ID_BLOC}|icone_verticale{<:bloc:icone_modifier_bloc:/>,bloc,edit,right ajax preload})]
]
[(#ID_BLOC|afficher_qui_edite{bloc}|oui)
[(#URL_ECRIRE{#GET{url_edit},id_bloc=#ID_BLOC}|icone_verticale{#ID_BLOC|afficher_qui_edite{bloc},warning-24,'',right edition_deja ajax preload})]
]
]
<h1>[(#RANG). ](#TITRE|sinon{<:info_sans_titre:/>})[(#CHEMIN_IMAGE{bloc-24.png}|balise_img{bloc,cadre-icone})]</h1>
],simple fiche_objet})]
<div class="ajax">
#FORMULAIRE_DATER{bloc,#ID_BLOC}
</div>
<!--affiche_milieu-->
<div id="wysiwyg">
<INCLURE{fond=prive/objets/contenu/bloc,id=#ID_BLOC,id_bloc=#ID_BLOC,virtuel=oui,ajax=wysiwyg,wysiwyg=1}>
</div>
<div class="nettoyeur"></div>
[(#AUTORISER{modifier,bloc,#ID_BLOC})
[(#ID_BLOC|afficher_qui_edite{bloc}|non)
[(#URL_ECRIRE{#GET{url_edit},id_bloc=#ID_BLOC}|icone_verticale{<:bloc:icone_modifier_bloc:/>,bloc,edit,right ajax preload})]
]
[(#ID_BLOC|afficher_qui_edite{bloc}|oui)
[(#URL_ECRIRE{#GET{url_edit},id_bloc=#ID_BLOC}|icone_verticale{#ID_BLOC|afficher_qui_edite{bloc},warning-24,'',right edition_deja ajax preload})]
]
]
#PIPELINE{afficher_complement_objet,#ARRAY{args,#ARRAY{type,bloc,id,#ID_BLOC},data,'<div class="nettoyeur"></div>'}}
#BOITE_FERMER
#SET{enfants,''}
[(#VAL{prive/objets/contenu/bloc-enfants}|trouver_fond|oui)
[(#SET{enfants,[(#INCLURE{fond=prive/objets/contenu/bloc-enfants,id_bloc,env})]})]
]
[(#PIPELINE{affiche_enfants,[(#ARRAY{args,#ARRAY{exec,bloc,id_bloc,#ID_BLOC,objet,bloc,id_objet,#ID_BLOC},data,#GET{enfants}})]})]
[(#CONST{_AJAX}|oui)
<script type="text/javascript">/*<!\\[CDATA\\[*/reloadExecPage('#ENV{exec}','#navigation,#chemin,#extra');/*\\]\\]>*/</script>
]
</BOUCLE_bloc>
[(#ENV**{exec}|=={#GET{url_edit}}|?{#INCLURE{fond=prive/squelettes/contenu/#GET{url_edit},redirect='',env,retourajax=oui},#REM|sinon_interdire_acces})]
<//B_bloc>

@ -0,0 +1,36 @@
[(#ID_BLOC|oui)
[(#AUTORISER{modifier,bloc,#ID_BLOC}|sinon_interdire_acces)]
[(#SET{id_parent,#INFO_ID_BLOCS_TYPE{bloc,#ID_BLOC}})]
]
[(#ID_BLOC|non)
#SET{id_parent,#ENV{id_blocs_type,#ENV{id_parent}}}
[(#GET{id_parent}|non|ou{[(#AUTORISER{creerblocdans, blocs_type, #GET{id_parent}})]}|sinon_interdire_acces)]
]
#SET{redirect,#ENV{redirect}|sinon{#ID_BLOC|?{#ID_BLOC|generer_url_entite{bloc},#GET{id_parent}|?{#GET{id_parent}|generer_url_entite{blocs_type},#URL_ECRIRE{blocs_types}}}}}
<div class="cadre-formulaire-editer">
<div class="entete-formulaire">
[(#ID_BLOC|oui)
[(#GET{redirect}|icone_verticale{<:icone_retour:/>,bloc,'',left retour[(#ENV{retourajax,''}|oui)ajax preload]})]
]
[
[(#ID_BLOC|?{<:bloc:icone_modifier_bloc:/>,<:bloc:icone_creer_bloc:/>})]
<h1>(#ENV*{titre,#INFO_TITRE{bloc,#ID_BLOC}|sinon{<:info_sans_titre:/>}})</h1>
]
</div>
#SET{redirect,#ENV{redirect,#ID_BLOC|generer_url_entite{bloc}}}
[(#ENV{retourajax,''}|oui)
#SET{redirect,'javascript:if (window.jQuery) jQuery(".entete-formulaire .retour a").followLink();'}
<div class="ajax">
]
[(#FORMULAIRE_EDITER_BLOC{#ENV{id_bloc,oui}, #GET{id_parent}, #GET{redirect}})]
[(#ENV{retourajax,''}|oui)
</div>
<script type="text/javascript">/*<!\[CDATA\[*/reloadExecPage('#ENV{exec}');/*\]\]>*/</script>
]
</div>

@ -0,0 +1,11 @@
[(#AUTORISER{voir,_blocs}|sinon_interdire_acces)]
<h1 class="grostitre"><:bloc:titre_page_blocs:/></h1>
#FORMULAIRE_RECHERCHE_ECRIRE{#SELF,ajax}
<div class="nettoyeur"></div>
<INCLURE{fond=prive/objets/liste/blocs, env, ajax, sinon=<:bloc:info_aucun_bloc:/>}>
[(#AUTORISER{creer,bloc})
[(#URL_ECRIRE{bloc_edit,new=oui}|icone_verticale{<:bloc:icone_creer_bloc:/>,bloc,new,right})]
]

@ -0,0 +1,56 @@
[(#AUTORISER{voir,blocs_type,#ID_BLOCS_TYPE}|sinon_interdire_acces)]
[(#SET{url_voir,#VAL{blocs_type}|objet_info{url_voir}})]
[(#SET{url_edit,#VAL{blocs_type}|objet_info{url_edit}})]
<BOUCLE_blocs_type(BLOCS_TYPES){id_blocs_type}{si #ENV{exec}|=={#GET{url_voir}}}>
[(#BOITE_OUVRIR{[
[(#AUTORISER{modifier,blocs_type,#ID_BLOCS_TYPE})
[(#ID_BLOCS_TYPE|afficher_qui_edite{blocs_type}|non)
[(#URL_ECRIRE{#GET{url_edit},id_blocs_type=#ID_BLOCS_TYPE}|icone_verticale{<:blocs_type:icone_modifier_blocs_type:/>,blocs_type,edit,right ajax preload})]
]
[(#ID_BLOCS_TYPE|afficher_qui_edite{blocs_type}|oui)
[(#URL_ECRIRE{#GET{url_edit},id_blocs_type=#ID_BLOCS_TYPE}|icone_verticale{#ID_BLOCS_TYPE|afficher_qui_edite{blocs_type},warning-24,'',right edition_deja ajax preload})]
]
]
<h1>[(#RANG). ](#TITRE|sinon{<:info_sans_titre:/>})[(#CHEMIN_IMAGE{blocs_type-24.png}|balise_img{blocs_type,cadre-icone})]</h1>
],simple fiche_objet})]
<div class="ajax">
#FORMULAIRE_DATER{blocs_type,#ID_BLOCS_TYPE}
</div>
<!--affiche_milieu-->
<div id="wysiwyg">
<INCLURE{fond=prive/objets/contenu/blocs_type,id=#ID_BLOCS_TYPE,id_blocs_type=#ID_BLOCS_TYPE,virtuel=oui,ajax=wysiwyg,wysiwyg=1}>
</div>
<div class="nettoyeur"></div>
[(#AUTORISER{modifier,blocs_type,#ID_BLOCS_TYPE})
[(#ID_BLOCS_TYPE|afficher_qui_edite{blocs_type}|non)
[(#URL_ECRIRE{#GET{url_edit},id_blocs_type=#ID_BLOCS_TYPE}|icone_verticale{<:blocs_type:icone_modifier_blocs_type:/>,blocs_type,edit,right ajax preload})]
]
[(#ID_BLOCS_TYPE|afficher_qui_edite{blocs_type}|oui)
[(#URL_ECRIRE{#GET{url_edit},id_blocs_type=#ID_BLOCS_TYPE}|icone_verticale{#ID_BLOCS_TYPE|afficher_qui_edite{blocs_type},warning-24,'',right edition_deja ajax preload})]
]
]
#PIPELINE{afficher_complement_objet,#ARRAY{args,#ARRAY{type,blocs_type,id,#ID_BLOCS_TYPE},data,'<div class="nettoyeur"></div>'}}
#BOITE_FERMER
#SET{enfants,''}
[(#VAL{prive/objets/contenu/blocs_type-enfants}|trouver_fond|oui)
[(#SET{enfants,[(#INCLURE{fond=prive/objets/contenu/blocs_type-enfants,id_blocs_type,env})]})]
]
[(#PIPELINE{affiche_enfants,[(#ARRAY{args,#ARRAY{exec,blocs_type,id_blocs_type,#ID_BLOCS_TYPE,objet,blocs_type,id_objet,#ID_BLOCS_TYPE},data,#GET{enfants}})]})]
[(#CONST{_AJAX}|oui)
<script type="text/javascript">/*<!\\[CDATA\\[*/reloadExecPage('#ENV{exec}','#navigation,#chemin,#extra');/*\\]\\]>*/</script>
]
</BOUCLE_blocs_type>
[(#ENV**{exec}|=={#GET{url_edit}}|?{#INCLURE{fond=prive/squelettes/contenu/#GET{url_edit},redirect='',env,retourajax=oui},#REM|sinon_interdire_acces})]
<//B_blocs_type>

@ -0,0 +1,11 @@
[(#AUTORISER{voir,_blocs_types}|sinon_interdire_acces)]
<h1 class="grostitre"><:blocs_type:titre_page_blocs_types:/></h1>
#FORMULAIRE_RECHERCHE_ECRIRE{#SELF,ajax}
<div class="nettoyeur"></div>
<INCLURE{fond=prive/objets/liste/blocs_types, env, ajax, sinon=<:blocs_type:info_aucun_blocs_type:/>}>
[(#AUTORISER{creer,blocs_type})
[(#URL_ECRIRE{blocs_type_edit,new=oui}|icone_verticale{<:blocs_type:icone_creer_blocs_type:/>,blocs_type,new,right})]
]

@ -0,0 +1,7 @@
[(#AUTORISER{configurer,_blocks}|sinon_interdire_acces)]
<h1 class="grostitre"><:blocks:titre_page_configurer_blocks:/></h1>
<div class="ajax">
#FORMULAIRE_CONFIGURER_BLOCKS
</div>

@ -0,0 +1,10 @@
<!-- hierarchie -->
<a href="#URL_ECRIRE{blocs}"><:bloc:titre_blocs:/></a>
<BOUCLE_hierarchie(BLOCS){id_bloc}{statut?}>
&gt; [(#URL_ECRIRE{blocs_type,id_blocs_type=#ID_BLOCS_TYPE}|lien_ou_expose{#INFO_TITRE{blocs_types,#ID_BLOCS_TYPE},''})]
&gt; <strong class="on">#TITRE</strong>
</BOUCLE_hierarchie>
[(#ENV{id_blocs_type}|oui)
&gt; [(#URL_ECRIRE{blocs_type,id_blocs_type=#ID_BLOCS_TYPE}|lien_ou_expose{#INFO_TITRE{blocs_types,#ID_BLOCS_TYPE},''})]
]&gt; <strong class="on"><:ecrire:info_sans_titre:/></strong>
<//B_hierarchie>

@ -0,0 +1 @@
<INCLURE{fond=prive/squelettes/hierarchie/bloc,env} />

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 48 48">
<path fill="none" stroke="#2196f3" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"
d="M6 30h12v12H6V30ZM30 6h12v12H30V6Zm0 12h12v12H30V18Zm-12 0h12v12H18V18ZM6 18h12v12H6V18Z"/>
</svg>

After

Width:  |  Height:  |  Size: 290 B

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 48 48">
<path fill="none" stroke="#2196f3" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"
d="M6 30h12v12H6V30ZM30 6h12v12H30V6Zm0 12h12v12H30V18Zm-12 0h12v12H18V18ZM6 18h12v12H6V18Z"/>
</svg>

After

Width:  |  Height:  |  Size: 290 B

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48">
<path fill="none" stroke="#2196f3" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"
d="M6 30h12v12H6V30ZM30 6h12v12H30V6Zm0 12h12v12H30V18Zm-12 0h12v12H18V18ZM6 18h12v12H6V18Z"/>
</svg>

After

Width:  |  Height:  |  Size: 290 B

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 48 48">
<path fill="none" stroke="#2196f3" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"
d="M6 30h12v12H6V30ZM30 6h12v12H30V6Zm0 12h12v12H30V18Zm-12 0h12v12H18V18ZM6 18h12v12H6V18Z"/>
</svg>

After

Width:  |  Height:  |  Size: 290 B

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 48 48">
<path fill="none" stroke="#2196f3" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"
d="M6 30h12v12H6V30ZM30 6h12v12H30V6Zm0 12h12v12H30V18Zm-12 0h12v12H18V18ZM6 18h12v12H6V18Z"/>
</svg>

After

Width:  |  Height:  |  Size: 290 B

@ -0,0 +1,20 @@
<BOUCLE_test_multiple(CONDITION){si #ENV{multiple}|=={on}|oui}>
[(#SET{valeur,[(#ENV*{valeur}|is_array|?{[(#ENV*{valeur})],[(#ENV*{valeur}|explode{','})]})]})]
<B_blocs_types_selectionnes>
<ul>
<BOUCLE_blocs_types_selectionnes(BLOCS_TYPES){id_blocs_type IN #GET*{valeur}}
{par num titre, titre}{tout}>
<li class="choix">#TITRE (#ID