forked from ScoDoc/ScoDoc
Liens personnalisables (implements #386): au niveau global, avec paramètres.
This commit is contained in:
parent
b8767c7536
commit
bb1d4f559d
72
app/forms/main/config_personalized_links.py
Normal file
72
app/forms/main/config_personalized_links.py
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
"""
|
||||||
|
Formulaire configuration liens personalisés (menu "Liens")
|
||||||
|
"""
|
||||||
|
|
||||||
|
from flask import g, url_for
|
||||||
|
from flask_wtf import FlaskForm
|
||||||
|
from wtforms import FieldList, Form, validators
|
||||||
|
from wtforms.fields.simple import BooleanField, StringField, SubmitField
|
||||||
|
|
||||||
|
from app.models import ScoDocSiteConfig
|
||||||
|
|
||||||
|
|
||||||
|
class _PersonalizedLinksForm(FlaskForm):
|
||||||
|
"form. définition des liens personnalisés"
|
||||||
|
# construit dynamiquement ci-dessous
|
||||||
|
|
||||||
|
|
||||||
|
def PersonalizedLinksForm() -> _PersonalizedLinksForm:
|
||||||
|
"Création d'un formulaire pour éditer les liens"
|
||||||
|
|
||||||
|
# Formulaire dynamique, on créé une classe ad-hoc
|
||||||
|
class F(_PersonalizedLinksForm):
|
||||||
|
pass
|
||||||
|
|
||||||
|
F.links_by_id = dict(enumerate(ScoDocSiteConfig.get_perso_links()))
|
||||||
|
|
||||||
|
def _gen_link_form(idx):
|
||||||
|
setattr(
|
||||||
|
F,
|
||||||
|
f"link_{idx}",
|
||||||
|
StringField(
|
||||||
|
f"Titre",
|
||||||
|
validators=[
|
||||||
|
validators.Optional(),
|
||||||
|
validators.Length(min=1, max=80),
|
||||||
|
],
|
||||||
|
default="",
|
||||||
|
render_kw={"size": 6},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
setattr(
|
||||||
|
F,
|
||||||
|
f"link_url_{idx}",
|
||||||
|
StringField(
|
||||||
|
f"URL",
|
||||||
|
description="adresse, incluant le http.",
|
||||||
|
validators=[
|
||||||
|
validators.Optional(),
|
||||||
|
validators.URL(),
|
||||||
|
validators.Length(min=1, max=256),
|
||||||
|
],
|
||||||
|
default="",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
setattr(
|
||||||
|
F,
|
||||||
|
f"link_with_args_{idx}",
|
||||||
|
BooleanField(
|
||||||
|
f"ajouter arguments",
|
||||||
|
description="query string avec ids",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
# Initialise un champ de saisie par lien
|
||||||
|
for idx in F.links_by_id:
|
||||||
|
_gen_link_form(idx)
|
||||||
|
_gen_link_form("new")
|
||||||
|
|
||||||
|
F.submit = SubmitField("Valider")
|
||||||
|
F.cancel = SubmitField("Annuler", render_kw={"formnovalidate": True})
|
||||||
|
|
||||||
|
return F()
|
@ -3,9 +3,13 @@
|
|||||||
"""Model : site config WORK IN PROGRESS #WIP
|
"""Model : site config WORK IN PROGRESS #WIP
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import urllib.parse
|
||||||
|
|
||||||
from flask import flash
|
from flask import flash
|
||||||
from app import current_app, db, log
|
from app import current_app, db, log
|
||||||
from app.comp import bonus_spo
|
from app.comp import bonus_spo
|
||||||
|
from app.scodoc.sco_exceptions import ScoValueError
|
||||||
from app.scodoc import sco_utils as scu
|
from app.scodoc import sco_utils as scu
|
||||||
|
|
||||||
from datetime import time
|
from datetime import time
|
||||||
@ -342,3 +346,47 @@ class ScoDocSiteConfig(db.Model):
|
|||||||
log(f"set_month_debut_periode2({month})")
|
log(f"set_month_debut_periode2({month})")
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_perso_links(cls) -> list["PersonalizedLink"]:
|
||||||
|
"Return links"
|
||||||
|
data_links = cls.get("personalized_links")
|
||||||
|
if not data_links:
|
||||||
|
return []
|
||||||
|
try:
|
||||||
|
links_dict = json.loads(data_links)
|
||||||
|
except json.decoder.JSONDecodeError as exc:
|
||||||
|
# Corrupted data ? erase content
|
||||||
|
cls.set("personalized_links", "")
|
||||||
|
raise ScoValueError(
|
||||||
|
"Attention: liens personnalisés erronés: ils ont été effacés."
|
||||||
|
)
|
||||||
|
return [PersonalizedLink(**item) for item in links_dict]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def set_perso_links(cls, links: list["PersonalizedLink"] = None):
|
||||||
|
"Store all links"
|
||||||
|
if not links:
|
||||||
|
links = []
|
||||||
|
links_dict = [link.to_dict() for link in links]
|
||||||
|
data_links = json.dumps(links_dict)
|
||||||
|
cls.set("personalized_links", data_links)
|
||||||
|
|
||||||
|
|
||||||
|
class PersonalizedLink:
|
||||||
|
def __init__(self, title: str = "", url: str = "", with_args: bool = False):
|
||||||
|
self.title = str(title or "")
|
||||||
|
self.url = str(url or "")
|
||||||
|
self.with_args = bool(with_args)
|
||||||
|
|
||||||
|
def get_url(self, params: dict = {}) -> str:
|
||||||
|
if not self.with_args:
|
||||||
|
return self.url
|
||||||
|
query_string = urllib.parse.urlencode(params)
|
||||||
|
if "?" in self.url:
|
||||||
|
return self.url + "&" + query_string
|
||||||
|
return self.url + "?" + query_string
|
||||||
|
|
||||||
|
def to_dict(self) -> dict:
|
||||||
|
"as dict"
|
||||||
|
return {"title": self.title, "url": self.url, "with_args": self.with_args}
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
import html
|
import html
|
||||||
|
|
||||||
from flask import render_template
|
from flask import g, render_template
|
||||||
from flask import request
|
from flask import request
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
|
|
||||||
@ -148,6 +148,8 @@ def sco_header(
|
|||||||
"Main HTML page header for ScoDoc"
|
"Main HTML page header for ScoDoc"
|
||||||
from app.scodoc.sco_formsemestre_status import formsemestre_page_title
|
from app.scodoc.sco_formsemestre_status import formsemestre_page_title
|
||||||
|
|
||||||
|
if etudid is not None:
|
||||||
|
g.current_etudid = etudid
|
||||||
scodoc_flash_status_messages()
|
scodoc_flash_status_messages()
|
||||||
|
|
||||||
# Get head message from http request:
|
# Get head message from http request:
|
||||||
|
@ -29,7 +29,10 @@
|
|||||||
"""
|
"""
|
||||||
import flask
|
import flask
|
||||||
from flask import g, url_for, request
|
from flask import g, url_for, request
|
||||||
|
from flask_login import current_user
|
||||||
|
|
||||||
|
from app.models.config import ScoDocSiteConfig, PersonalizedLink
|
||||||
|
from app.models import FormSemestre
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
import app.scodoc.notesdb as ndb
|
import app.scodoc.notesdb as ndb
|
||||||
from app.scodoc.TrivialFormulator import TrivialFormulator
|
from app.scodoc.TrivialFormulator import TrivialFormulator
|
||||||
@ -58,6 +61,28 @@ def formsemestre_custommenu_get(formsemestre_id):
|
|||||||
return vals
|
return vals
|
||||||
|
|
||||||
|
|
||||||
|
def build_context_dict(formsemestre_id: int) -> dict:
|
||||||
|
"""returns a dict with "current" ids, to pass to external links"""
|
||||||
|
params = {
|
||||||
|
"dept": g.scodoc_dept,
|
||||||
|
"formsemestre_id": formsemestre_id,
|
||||||
|
"user_name": current_user.user_name,
|
||||||
|
}
|
||||||
|
cas_id = getattr(current_user, "cas_id", None)
|
||||||
|
if cas_id:
|
||||||
|
params["cas_id"] = cas_id
|
||||||
|
etudid = getattr(g, "current_etudid", None)
|
||||||
|
if etudid is not None:
|
||||||
|
params["etudid"] = etudid
|
||||||
|
evaluation_id = getattr(g, "current_evaluation_id", None)
|
||||||
|
if evaluation_id is not None:
|
||||||
|
params["evaluation_id"] = evaluation_id
|
||||||
|
moduleimpl_id = getattr(g, "current_moduleimpl_id", None)
|
||||||
|
if moduleimpl_id is not None:
|
||||||
|
params["moduleimpl_id"] = moduleimpl_id
|
||||||
|
return params
|
||||||
|
|
||||||
|
|
||||||
def formsemestre_custommenu_html(formsemestre_id):
|
def formsemestre_custommenu_html(formsemestre_id):
|
||||||
"HTML code for custom menu"
|
"HTML code for custom menu"
|
||||||
menu = []
|
menu = []
|
||||||
@ -66,6 +91,13 @@ def formsemestre_custommenu_html(formsemestre_id):
|
|||||||
ics_url = sco_edt_cal.formsemestre_get_ics_url(sem)
|
ics_url = sco_edt_cal.formsemestre_get_ics_url(sem)
|
||||||
if ics_url:
|
if ics_url:
|
||||||
menu.append({"title": "Emploi du temps (ics)", "url": ics_url})
|
menu.append({"title": "Emploi du temps (ics)", "url": ics_url})
|
||||||
|
# Liens globaux (config. générale)
|
||||||
|
params = build_context_dict(formsemestre_id)
|
||||||
|
for link in ScoDocSiteConfig.get_perso_links():
|
||||||
|
if link.title:
|
||||||
|
menu.append({"title": link.title, "url": link.get_url(params=params)})
|
||||||
|
|
||||||
|
# Liens propres à ce semestre
|
||||||
menu += formsemestre_custommenu_get(formsemestre_id)
|
menu += formsemestre_custommenu_get(formsemestre_id)
|
||||||
menu.append(
|
menu.append(
|
||||||
{
|
{
|
||||||
@ -79,9 +111,11 @@ def formsemestre_custommenu_html(formsemestre_id):
|
|||||||
|
|
||||||
def formsemestre_custommenu_edit(formsemestre_id):
|
def formsemestre_custommenu_edit(formsemestre_id):
|
||||||
"""Dialog to edit the custom menu"""
|
"""Dialog to edit the custom menu"""
|
||||||
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||||
dest_url = (
|
dest_url = url_for(
|
||||||
scu.NotesURL() + "/formsemestre_status?formsemestre_id=%s" % formsemestre_id
|
"notes.formsemestre_status",
|
||||||
|
scodoc_dept=g.scodoc_dept,
|
||||||
|
formsemestre_id=formsemestre_id,
|
||||||
)
|
)
|
||||||
H = [
|
H = [
|
||||||
html_sco_header.html_sem_header("Modification du menu du semestre "),
|
html_sco_header.html_sem_header("Modification du menu du semestre "),
|
||||||
|
@ -194,6 +194,7 @@ def moduleimpl_status(moduleimpl_id=None, partition_id=None):
|
|||||||
if not isinstance(moduleimpl_id, int):
|
if not isinstance(moduleimpl_id, int):
|
||||||
raise ScoInvalidIdType("moduleimpl_id must be an integer !")
|
raise ScoInvalidIdType("moduleimpl_id must be an integer !")
|
||||||
modimpl: ModuleImpl = ModuleImpl.query.get_or_404(moduleimpl_id)
|
modimpl: ModuleImpl = ModuleImpl.query.get_or_404(moduleimpl_id)
|
||||||
|
g.current_moduleimpl_id = modimpl.id
|
||||||
module: Module = modimpl.module
|
module: Module = modimpl.module
|
||||||
formsemestre_id = modimpl.formsemestre_id
|
formsemestre_id = modimpl.formsemestre_id
|
||||||
formsemestre: FormSemestre = modimpl.formsemestre
|
formsemestre: FormSemestre = modimpl.formsemestre
|
||||||
|
84
app/templates/config_personalized_links.j2
Normal file
84
app/templates/config_personalized_links.j2
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
{% extends "base.j2" %}
|
||||||
|
{% import 'bootstrap/wtf.html' as wtf %}
|
||||||
|
|
||||||
|
{% block styles %}
|
||||||
|
{{super()}}
|
||||||
|
<style>
|
||||||
|
div.lien_perso {
|
||||||
|
border-left: 3px solid blue;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
div.lien_perso>div:first-child {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 120%;
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.lien_perso .form-group, div.lien_perso .checkbox {
|
||||||
|
margin-left: 32px;
|
||||||
|
}
|
||||||
|
div.url > .form-group {
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
||||||
|
div.validation-buttons {
|
||||||
|
margin-top: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block app_content %}
|
||||||
|
<h1>{{title}}</h1>
|
||||||
|
|
||||||
|
<div class="help">
|
||||||
|
|
||||||
|
<p>Les liens définis ici seront affichés dans le menu <b>Liens</b> de tous
|
||||||
|
les semestres de tous les départements.</p>
|
||||||
|
|
||||||
|
<p>Si on coche "ajouter arguments", une query string est ajoutée par ScoDoc
|
||||||
|
à la fin du lien, pour passer des informations sur le contexte:</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><tt>dept</tt> : acronyme du département
|
||||||
|
<li><tt>formsemestre_id</tt> : id du formsemestre affiché
|
||||||
|
<li><tt>moduleimpl_id</tt> : id du moduleimpl affiché (si page module)
|
||||||
|
<li><tt>evaluation_id</tt> : id de l'évaluation affichée (si page d'évaluation)
|
||||||
|
<li><tt>etudid</tt> : id de l'étudiant (si un étudiant est sélectionné)
|
||||||
|
<li><tt>user_name</tt> : login scodoc de l'utilisateur
|
||||||
|
<li><tt>cas_id</tt> : login CAS de l'utilisateur
|
||||||
|
<ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-8">
|
||||||
|
|
||||||
|
<form class="form form-horizontal form-personalized-links" method="post" enctype="multipart/form-data" role="form">
|
||||||
|
{{ form.hidden_tag() }}
|
||||||
|
{{ wtf.form_errors(form, hiddens="only") }}
|
||||||
|
|
||||||
|
{% for idx, link in form.links_by_id.items() %}
|
||||||
|
<div class="lien_perso">
|
||||||
|
<div>Lien personnalisé {{idx}}</div>
|
||||||
|
{{ wtf.form_field( form["link_"+idx|string] ) }}
|
||||||
|
<div class="url">{{ wtf.form_field( form["link_url_"+idx|string] ) }}</div>
|
||||||
|
{{ wtf.form_field( form["link_with_args_"+idx|string] ) }}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
<div class="lien_perso">
|
||||||
|
<div>Nouveau lien personnalisé</div>
|
||||||
|
{{ wtf.form_field( form["link_new"] ) }}
|
||||||
|
<div class="url">{{ wtf.form_field( form["link_url_new"] ) }}</div>
|
||||||
|
{{ wtf.form_field( form["link_with_args_new"] ) }}
|
||||||
|
</div>
|
||||||
|
<div class="form-group validation-buttons">
|
||||||
|
{{ wtf.form_field(form.submit) }}
|
||||||
|
{{ wtf.form_field(form.cancel) }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -24,6 +24,20 @@
|
|||||||
<h1>Configuration générale</h1>
|
<h1>Configuration générale</h1>
|
||||||
<div class="sco_help greenboldtext">Les paramètres donnés ici s'appliquent à tout ScoDoc (tous les départements).</div>
|
<div class="sco_help greenboldtext">Les paramètres donnés ici s'appliquent à tout ScoDoc (tous les départements).</div>
|
||||||
|
|
||||||
|
<h2>ScoDoc</h2>
|
||||||
|
<form id="configuration_form_scodoc" class="sco-form" action="" method="post" enctype="multipart/form-data" novalidate>
|
||||||
|
{{ form_scodoc.hidden_tag() }}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-8">
|
||||||
|
{{ wtf.quick_form(form_scodoc) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="margin-top: 16px;">
|
||||||
|
<a class="stdlink" href="{{url_for('scodoc.config_personalized_links')}}">Éditer des liens personnalisés</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<h2>Calcul des "bonus" définis par l'établissement</h2>
|
<h2>Calcul des "bonus" définis par l'établissement</h2>
|
||||||
<form id="configuration_form" class="sco-form" action="" method="post" enctype="multipart/form-data" novalidate>
|
<form id="configuration_form" class="sco-form" action="" method="post" enctype="multipart/form-data" novalidate>
|
||||||
@ -74,15 +88,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<h2>ScoDoc</h2>
|
|
||||||
<form id="configuration_form_scodoc" class="sco-form" action="" method="post" enctype="multipart/form-data" novalidate>
|
|
||||||
{{ form_scodoc.hidden_tag() }}
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-8">
|
|
||||||
{{ wtf.quick_form(form_scodoc) }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
|
@ -61,16 +61,23 @@ from app.decorators import (
|
|||||||
scodoc,
|
scodoc,
|
||||||
)
|
)
|
||||||
from app.forms.main import config_logos, config_main
|
from app.forms.main import config_logos, config_main
|
||||||
from app.forms.main.create_dept import CreateDeptForm
|
from app.forms.main.config_assiduites import ConfigAssiduitesForm
|
||||||
from app.forms.main.config_apo import CodesDecisionsForm
|
from app.forms.main.config_apo import CodesDecisionsForm
|
||||||
from app.forms.main.config_cas import ConfigCASForm
|
from app.forms.main.config_cas import ConfigCASForm
|
||||||
from app.forms.main.config_assiduites import ConfigAssiduitesForm
|
from app.forms.main.config_personalized_links import PersonalizedLinksForm
|
||||||
|
from app.forms.main.create_dept import CreateDeptForm
|
||||||
from app import models
|
from app import models
|
||||||
from app.models import Departement, Identite
|
from app.models import (
|
||||||
|
Departement,
|
||||||
|
FormSemestre,
|
||||||
|
FormSemestreInscription,
|
||||||
|
Identite,
|
||||||
|
ScoDocSiteConfig,
|
||||||
|
UniteEns,
|
||||||
|
)
|
||||||
from app.models import departements
|
from app.models import departements
|
||||||
from app.models import FormSemestre, FormSemestreInscription
|
from app.models.config import PersonalizedLink
|
||||||
from app.models import ScoDocSiteConfig
|
|
||||||
from app.models import UniteEns
|
|
||||||
|
|
||||||
from app.scodoc import sco_find_etud
|
from app.scodoc import sco_find_etud
|
||||||
from app.scodoc import sco_logos
|
from app.scodoc import sco_logos
|
||||||
@ -260,6 +267,38 @@ def config_codes_decisions():
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/ScoDoc/config_personalized_links", methods=["GET", "POST"])
|
||||||
|
@admin_required
|
||||||
|
def config_personalized_links():
|
||||||
|
"""Form config liens perso"""
|
||||||
|
form = PersonalizedLinksForm()
|
||||||
|
if request.method == "POST" and form.cancel.data: # cancel button
|
||||||
|
return redirect(url_for("scodoc.index"))
|
||||||
|
if form.validate_on_submit():
|
||||||
|
links = []
|
||||||
|
for idx in list(form.links_by_id) + ["new"]:
|
||||||
|
title = form.data.get(f"link_{idx}")
|
||||||
|
url = form.data.get(f"link_url_{idx}")
|
||||||
|
with_args = form.data.get(f"link_with_args_{idx}")
|
||||||
|
if title and url:
|
||||||
|
links.append(
|
||||||
|
PersonalizedLink(title=title, url=url, with_args=with_args)
|
||||||
|
)
|
||||||
|
ScoDocSiteConfig.set_perso_links(links)
|
||||||
|
flash("Liens enregistrés")
|
||||||
|
return redirect(url_for("scodoc.configuration"))
|
||||||
|
|
||||||
|
for idx, link in form.links_by_id.items():
|
||||||
|
getattr(form, f"link_{idx}").data = link.title
|
||||||
|
getattr(form, f"link_url_{idx}").data = link.url
|
||||||
|
getattr(form, f"link_with_args_{idx}").data = link.with_args
|
||||||
|
return render_template(
|
||||||
|
"config_personalized_links.j2",
|
||||||
|
form=form,
|
||||||
|
title="Configuration des liens personnalisés",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/ScoDoc/table_etud_in_accessible_depts", methods=["POST"])
|
@bp.route("/ScoDoc/table_etud_in_accessible_depts", methods=["POST"])
|
||||||
@login_required
|
@login_required
|
||||||
def table_etud_in_accessible_depts():
|
def table_etud_in_accessible_depts():
|
||||||
|
@ -8,7 +8,7 @@ Utiliser comme:
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from app.models import ScoDocSiteConfig
|
from app.models.config import ScoDocSiteConfig, PersonalizedLink
|
||||||
from app.comp.bonus_spo import BonusIUTRennes1
|
from app.comp.bonus_spo import BonusIUTRennes1
|
||||||
from app.scodoc import sco_utils as scu
|
from app.scodoc import sco_utils as scu
|
||||||
|
|
||||||
@ -55,3 +55,14 @@ def test_scodoc_site_config(test_client):
|
|||||||
ScoDocSiteConfig.get_month_debut_annee_scolaire()
|
ScoDocSiteConfig.get_month_debut_annee_scolaire()
|
||||||
== scu.MONTH_DEBUT_ANNEE_SCOLAIRE
|
== scu.MONTH_DEBUT_ANNEE_SCOLAIRE
|
||||||
)
|
)
|
||||||
|
# Links:
|
||||||
|
assert ScoDocSiteConfig.get_perso_links() == []
|
||||||
|
ScoDocSiteConfig.set_perso_links(
|
||||||
|
[
|
||||||
|
PersonalizedLink(title="lien 1", url="http://foo.bar/bar", with_args=True),
|
||||||
|
PersonalizedLink(title="lien 1", url="http://foo.bar?x=1", with_args=True),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
links = ScoDocSiteConfig.get_perso_links()
|
||||||
|
assert links[0].get_url(params={"y": 2}) == "http://foo.bar/bar?y=2"
|
||||||
|
assert links[1].get_url(params={"y": 2}) == "http://foo.bar?x=1&y=2"
|
||||||
|
Loading…
Reference in New Issue
Block a user