forked from ScoDoc/DocScoDoc
216 lines
6.1 KiB
Markdown
216 lines
6.1 KiB
Markdown
# Conventions de codage pour ScoDoc
|
|
|
|
Le projet étant très ancien, le code est passé par différentes conventions et
|
|
frameworks. Le style de python et celui du *frontend* web ont considérablement
|
|
évolués ces dernières décennies.
|
|
|
|
Pour les nouveaux codes, respecter les principes suivants:
|
|
|
|
- ScoDoc est avant tout une application serveur écrite en Python, qui offre des
|
|
services via une interface Web, une API, et accessoirement la ligne de
|
|
commande unix.
|
|
|
|
- Les pages Web générées doivent l'être en Python côté serveur. On peut utiliser
|
|
du JS pour les pages dynamiques complexes (eg éditeur de partition) mais
|
|
éviter d'utiliser du JS pour générer des éléments statiques: l'abus de JS
|
|
conduit à dupliquer du code (qui existe en général dans le serveur) et
|
|
augmente les coûts de maintenance.
|
|
|
|
## Conventions de codage
|
|
|
|
### Formatage du code
|
|
|
|
- l'usage de **[black](https://black.readthedocs.io/en/stable/)** est obligatoire
|
|
- l'usage de pylint et mypy est fortement recommandé
|
|
- Pour le code JS, indentation avec 2 espaces (sous VS Code, utiliser *Prettier*).
|
|
|
|
### Conventions standard Python
|
|
|
|
On se tient à la PEP8, c'est à dire en résumé:
|
|
`UneClasse`, `une_fonction`, `_une_fonction_privee`, `une_variable`, `UNE_CONSTANTE_GLOBALE`.
|
|
|
|
Les noms de fichiers sont en minuscules sans accents ni espaces, `comme_ceci.py`.
|
|
|
|
### Annotations de type (typehints)
|
|
|
|
On annote les paramètres et résultats des fonctions.
|
|
|
|
```py
|
|
def _upload_justificatif_files(
|
|
just: Justificatif, form: AjoutJustificatifEtudForm
|
|
) -> bool:
|
|
...
|
|
```
|
|
|
|
## Pages et templates
|
|
|
|
Les vues utilisent un template *Jinja2*, fichier avec extension j2.
|
|
|
|
On s'astreint, sauf cas particulier, à un nommage identique de la route, la vue et du template.
|
|
|
|
```py
|
|
@bp.route("/un_exemple")
|
|
def un_exemple(...):
|
|
...
|
|
return render_template(".../un_exemple.j2")
|
|
```
|
|
|
|
Le template aura typiquement avec la structure suivante:
|
|
|
|
```jinja
|
|
{% extends "sco_page.j2" %}
|
|
|
|
{% block app_content %}
|
|
<h1>Titre</h1>
|
|
{% endblock app_content %}
|
|
```
|
|
|
|
Pour les pages dans un semestre (avec barre menu etc.), on utilisera `<h2>` au
|
|
lieu de `<h1>`.
|
|
|
|
### Templates habituels
|
|
|
|
Les templates suivants sont les plus utilisés pour les pages:
|
|
|
|
- `base.j2` pages hors département (accueil, configuration, ...)
|
|
|
|
- `sco_page.j2` page standard dans un formsemestre: avec sidebar et barre de
|
|
menu du semestre. Le contenu de la variable `content` est placé comme HTML
|
|
brut (*safe*) dans la partie contenu. Passer `sco=ScoData(formsemestre=formsemestre)`
|
|
en argument au template.
|
|
|
|
- `sco_page_dept.j2` page dans un département (avec sidebar) mais sans formsemestre (pas de
|
|
barre de menu)
|
|
|
|
### Constantes définies dans les templates ScoDoc
|
|
|
|
Le `context_processor` `inject_sco_utils()` ajoute des objets pour accès à tous
|
|
les templates ScoDoc:
|
|
|
|
- `scu` : le module `sco_utils.py` (diverses fonctions utilitaires et variables
|
|
de config.)
|
|
- `sco` : des données sur le contexte, notamment les préférences, le
|
|
formsemestre et l'étudiant courants (resp. `sco.formsemestre` et `sco.etud`)
|
|
|
|
### Appel d'un template page
|
|
|
|
Pour mémoire, l'appel d'un template dans une vue se fait ainsi:
|
|
|
|
```py
|
|
render_template( "votre_template.j2",
|
|
title="Changer de référentiel de compétences",
|
|
autre_variable=...
|
|
)
|
|
```
|
|
|
|
### Passage des anciennes pages ScoDoc 7 aux templates Jinja
|
|
|
|
Les anciennes pages étaient générées en python selon la structure:
|
|
|
|
```py
|
|
html_sco_header.sco_header(
|
|
cssstyles=["css/....css"],
|
|
javascripts=[
|
|
"js/....js",
|
|
],
|
|
page_title="titre de la page",
|
|
)
|
|
... contenu ...
|
|
html_sco_header.sco_footer()
|
|
```
|
|
|
|
La migration la plus simple consiste à utilise `sco_page.j2`:
|
|
```py
|
|
render_template(
|
|
"sco_page.j2",
|
|
content=contenu,
|
|
title="titre de la page",
|
|
cssstyles=["..."],
|
|
javascripts=["..."],
|
|
)
|
|
```
|
|
|
|
Mais si on souhaite générer le contenu dans un template, cela prendra la forme:
|
|
|
|
```jinja-html
|
|
{% extends "sco_page.j2" %}
|
|
|
|
{% block title %}
|
|
...titre...
|
|
{% endblock title %}
|
|
|
|
{% block styles %}
|
|
{{ super() }}
|
|
<link rel="stylesheet" href="{{scu.STATIC_DIR}}/css/un_style_scodoc.css">
|
|
<style>
|
|
... styles locaux ...
|
|
</style>
|
|
{% endblock styles %}
|
|
|
|
{% block app_content %}
|
|
<div class="pageContent">
|
|
<h2>titre page</h2>
|
|
... contenu ...
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block scripts %}
|
|
{{ super() }}
|
|
<script src="{{scu.STATIC_DIR}}/js/un_script_scodoc.js"></script>
|
|
<script>
|
|
... script js local ...
|
|
</script>
|
|
{% endblock %}
|
|
```
|
|
|
|
|
|
### Classes css
|
|
|
|
`scodoc.css` (et à partir de 9.7, `scodoc97.css`) définissent quelques classes à usage général:
|
|
|
|
- `div.scobox`: boite (bords arrondis, fond uni) regroupant des éléments.
|
|
|
|
- `div.scobox-title` le titre de la boite
|
|
- `div.scobox-buttons` boutons en bas de boite.
|
|
|
|
- `p.help`, `div.help`: explications, aide.
|
|
- ...
|
|
|
|
## Accès à la base de donnée
|
|
|
|
Sauf exception (requêtes exotiques, problèmes de performance) à discuter, les
|
|
accès à la base se font à travers l'ORM *SQLAlchemy*. Les modèles sont définis
|
|
dans `app/models`, sauf les comptes utilisateurs qui sont dans
|
|
`/app/auth/models.py`.
|
|
|
|
Au moment de la définition de nouveaux modèles, éviter si possible les champs
|
|
*nullables*, penser à créer là où ce sera utile des index.
|
|
|
|
## Tableaux
|
|
|
|
ScoDoc génère beaucoup de tableaux, sauf exception destinés à l'affichage Web et à l'export xlsx.
|
|
|
|
On utilise la super-classe `Table` de `app/tables/table_builder.py`.
|
|
|
|
Le rendu HTML utilise *DataTables*.
|
|
|
|
## Dates et heures
|
|
|
|
ScoDoc, contrairement à de nombreuses applications, est centré sur les
|
|
*étudiants* et les enseignements, qui sont censés opérer dans le fuseau horaire
|
|
du serveur. Cela signifie que, quelle que soit l'emplacement de l'utilisateur,
|
|
les heures affichées et saisies par ScoDoc seront données dans le fuseau horaire
|
|
du serveur.
|
|
|
|
L'API publie et reçoit des heures au format ISO avec fuseau horaire (*timezone*) et n'est pas
|
|
concernée par cette remarque.
|
|
|
|
|
|
!!! note "Voir aussi"
|
|
|
|
- [Introduction au développement ScoDoc](DevInternals.md)
|
|
- [Guide développeurs](GuideDeveloppeurs.md)
|
|
- [API ScoDoc 9](ScoDoc9API.md)
|
|
- [Modélisation du BUT](ModelisationParcoursBUT.md)
|
|
- [Contacts](Contact.md)
|