Added basic tag filters, removed tag filter section temporarily
Update app.py, content.json, and 9 more files...
This commit is contained in:
4
app.py
4
app.py
@@ -10,7 +10,7 @@ from werkzeug.exceptions import HTTPException
|
|||||||
|
|
||||||
from website.content import get_projects, get_tools, sanitize_input_tags, load_content_items, get_content, \
|
from website.content import get_projects, get_tools, sanitize_input_tags, load_content_items, get_content, \
|
||||||
get_applets, get_projects_languages, get_projects_by_languages, get_sorted_tools_by_tags, \
|
get_applets, get_projects_languages, get_projects_by_languages, get_sorted_tools_by_tags, \
|
||||||
get_sorted_projects_by_tags
|
get_sorted_projects_by_tags, get_tools_linked_tags, get_tools_unlinked_tags
|
||||||
from website.contributors import reload_contributors_data
|
from website.contributors import reload_contributors_data
|
||||||
from website.domains import ALLOWED_DOMAINS
|
from website.domains import ALLOWED_DOMAINS
|
||||||
from website.l10n.utils import get_user_lang, localize, reload_strings, l10n_url_abs, l10n_url_switch, DEFAULT_LANG
|
from website.l10n.utils import get_user_lang, localize, reload_strings, l10n_url_abs, l10n_url_switch, DEFAULT_LANG
|
||||||
@@ -125,6 +125,8 @@ def inject_processors():
|
|||||||
get_tools=get_tools,
|
get_tools=get_tools,
|
||||||
get_sorted_projects_by_tags=get_sorted_projects_by_tags,
|
get_sorted_projects_by_tags=get_sorted_projects_by_tags,
|
||||||
get_sorted_tools_by_tags=get_sorted_tools_by_tags,
|
get_sorted_tools_by_tags=get_sorted_tools_by_tags,
|
||||||
|
get_tools_unlinked_tags=get_tools_unlinked_tags,
|
||||||
|
get_tools_linked_tags=get_tools_linked_tags,
|
||||||
|
|
||||||
# Renderers
|
# Renderers
|
||||||
render_button=render_button,
|
render_button=render_button,
|
||||||
|
@@ -83,5 +83,7 @@
|
|||||||
"content.commons.lang.luxembourgish": "Luxembourgish",
|
"content.commons.lang.luxembourgish": "Luxembourgish",
|
||||||
"content.commons.lang.english.639-3": "English (eng)",
|
"content.commons.lang.english.639-3": "English (eng)",
|
||||||
"content.commons.lang.french.639-3": "French (fra)",
|
"content.commons.lang.french.639-3": "French (fra)",
|
||||||
"content.commons.lang.luxembourgish.639-3": "Luxembourgish (ltz)"
|
"content.commons.lang.luxembourgish.639-3": "Luxembourgish (ltz)",
|
||||||
|
|
||||||
|
"filters.summary": "Click to show/hide tag filters"
|
||||||
}
|
}
|
@@ -76,5 +76,7 @@
|
|||||||
"content.commons.lang.luxembourgish": "Luxembourgeois",
|
"content.commons.lang.luxembourgish": "Luxembourgeois",
|
||||||
"content.commons.lang.english.639-3": "Anglais (eng)",
|
"content.commons.lang.english.639-3": "Anglais (eng)",
|
||||||
"content.commons.lang.french.639-3": "Français (fra)",
|
"content.commons.lang.french.639-3": "Français (fra)",
|
||||||
"content.commons.lang.luxembourgish.639-3": "Luxembourgeois (ltz)"
|
"content.commons.lang.luxembourgish.639-3": "Luxembourgeois (ltz)",
|
||||||
|
|
||||||
|
"filters.summary": "Cliquez pour afficher/cacher les filtres"
|
||||||
}
|
}
|
@@ -28,4 +28,4 @@ tools:
|
|||||||
title_key: "meta.title"
|
title_key: "meta.title"
|
||||||
subtitle_key: "article.subtitle"
|
subtitle_key: "article.subtitle"
|
||||||
tags:
|
tags:
|
||||||
- "undefined"
|
- "graphics"
|
||||||
|
@@ -24,7 +24,7 @@ metadata:
|
|||||||
title_key: "meta.title"
|
title_key: "meta.title"
|
||||||
subtitle_key: "article.subtitle"
|
subtitle_key: "article.subtitle"
|
||||||
tags:
|
tags:
|
||||||
- "undefined"
|
- "graphics"
|
||||||
resources:
|
resources:
|
||||||
scripts:
|
scripts:
|
||||||
- "svg-to-png.mjs"
|
- "svg-to-png.mjs"
|
||||||
|
@@ -27,4 +27,5 @@ tools:
|
|||||||
title_key: "meta.title"
|
title_key: "meta.title"
|
||||||
subtitle_key: "article.subtitle"
|
subtitle_key: "article.subtitle"
|
||||||
tags:
|
tags:
|
||||||
- "undefined"
|
- "graphics"
|
||||||
|
- "analyser"
|
||||||
|
@@ -29,3 +29,11 @@ input[type=file].np-file-input-drop {
|
|||||||
margin-top: calc(1rem* 0.5);
|
margin-top: calc(1rem* 0.5);
|
||||||
margin-bottom: calc(1rem* 0.5);
|
margin-bottom: calc(1rem* 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hide-if-last:last-child {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hide-if-first:first-child {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
{% extends "base_www.jinja" %}
|
{% extends "base_www.jinja" %}
|
||||||
|
|
||||||
{% block main_content %}
|
{% block main_content %}
|
||||||
{% block content_filters %}{% endblock %}
|
<!--{% block content_filters %}{% endblock %}-->
|
||||||
<!--<hr class="subtle">-->
|
|
||||||
{% block content_listing %}{% endblock %}
|
{% block content_listing %}{% endblock %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
{% for project_data in get_sorted_projects_by_tags(requested_tags) %}
|
{% for project_data in get_sorted_projects_by_tags(requested_tags) %}
|
||||||
|
|
||||||
<hr class="subtle">
|
<hr class="subtle hide-if-first">
|
||||||
|
|
||||||
<!--<div class="p-s border r-m">-->
|
<!--<div class="p-s border r-m">-->
|
||||||
<div class="p-xs r-m">
|
<div class="p-xs r-m">
|
||||||
|
@@ -9,13 +9,34 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content_filters %}
|
{% block content_filters %}
|
||||||
[Tools filters here !]
|
<details class="border bkgd-dark r-m mb-s">
|
||||||
|
<summary class="p-xs t-noselect">{{ l10n("filters.summary", "content", user_lang) }}</summary>
|
||||||
|
<div class="p-xs bt bkgd-grey rb-m">
|
||||||
|
|
||||||
|
{% for linked_tag in get_tools_linked_tags(requested_tags) %}
|
||||||
|
<span class="mr-s t-size-10">
|
||||||
|
<a href="{{ l10n_url_abs('/tools/?tags=' + linked_tag, raw_lang) }}">#{{ linked_tag }}</a>
|
||||||
|
(+)
|
||||||
|
</span>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
<hr class="subtle hide-if-last hide-if-first">
|
||||||
|
|
||||||
|
{% for unlinked_tag in get_tools_unlinked_tags(requested_tags) %}
|
||||||
|
<span class="mr-s">
|
||||||
|
<a href="{{ l10n_url_abs('/tools/?tags=' + unlinked_tag, raw_lang) }}">#{{ unlinked_tag }}</a>
|
||||||
|
(+)
|
||||||
|
</span>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content_listing %}
|
{% block content_listing %}
|
||||||
|
|
||||||
{% for tool_data in get_sorted_tools_by_tags(requested_tags) %}
|
{% for tool_data in get_sorted_tools_by_tags(requested_tags) %}
|
||||||
<hr class="subtle">
|
<hr class="subtle hide-if-first">
|
||||||
|
|
||||||
<!--<div class="p-s border r-m">-->
|
<!--<div class="p-s border r-m">-->
|
||||||
<div class="p-xs r-m">
|
<div class="p-xs r-m">
|
||||||
|
@@ -54,6 +54,22 @@ def get_tools() -> LockedDict[str, ContentTool]:
|
|||||||
return __CONTENT.tools
|
return __CONTENT.tools
|
||||||
|
|
||||||
|
|
||||||
|
def get_tools_tags() -> list[str]:
|
||||||
|
tool: ContentTool
|
||||||
|
|
||||||
|
return sorted(
|
||||||
|
set(
|
||||||
|
[tag for tool in __CONTENT.tools.values() for tag in tool.metadata.general.tags]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
#returned_list: list[str] = list()
|
||||||
|
#for tool in __CONTENT.tools.values():
|
||||||
|
# tool: ContentTool
|
||||||
|
# returned_list = returned_list + tool.metadata.general.tags
|
||||||
|
#return list(set(returned_list))
|
||||||
|
|
||||||
|
|
||||||
def get_sorted_tools_by_tags(tags: Optional[list[str]]) -> list[ContentProject]:
|
def get_sorted_tools_by_tags(tags: Optional[list[str]]) -> list[ContentProject]:
|
||||||
if tags is None:
|
if tags is None:
|
||||||
return sorted(__CONTENT.tools.values(), key=lambda x: x.metadata.index.priority, reverse=True)
|
return sorted(__CONTENT.tools.values(), key=lambda x: x.metadata.index.priority, reverse=True)
|
||||||
@@ -67,6 +83,37 @@ def get_sorted_tools_by_tags(tags: Optional[list[str]]) -> list[ContentProject]:
|
|||||||
return sorted(returned_list, key=lambda x: x.metadata.index.priority, reverse=True)
|
return sorted(returned_list, key=lambda x: x.metadata.index.priority, reverse=True)
|
||||||
|
|
||||||
|
|
||||||
|
def get_tools_unlinked_tags(tags: Optional[list[str]]) -> list[str]:
|
||||||
|
"""Returns a list of tags which are not used with any tools that has one or more of the given tags."""
|
||||||
|
# TODO: cache the result !!!
|
||||||
|
|
||||||
|
all_tags = get_tools_tags()
|
||||||
|
linked_tags = get_tools_linked_tags(tags)
|
||||||
|
|
||||||
|
if tags is None:
|
||||||
|
return [tag for tag in all_tags if tag not in linked_tags]
|
||||||
|
else:
|
||||||
|
return [tag for tag in all_tags if (tag not in linked_tags and tag not in tags)]
|
||||||
|
|
||||||
|
|
||||||
|
def get_tools_linked_tags(tags: Optional[list[str]]) -> list[str]:
|
||||||
|
"""Returns a list of tags which are used in any tools that has one or more of the given tags."""
|
||||||
|
# TODO: cache the result !!!
|
||||||
|
|
||||||
|
returned_list = list()
|
||||||
|
|
||||||
|
if tags is not None:
|
||||||
|
relevant_tools = get_sorted_tools_by_tags(tags)
|
||||||
|
|
||||||
|
for relevant_tool in relevant_tools:
|
||||||
|
returned_list = returned_list + relevant_tool.metadata.general.tags
|
||||||
|
|
||||||
|
returned_list = set(returned_list)
|
||||||
|
returned_list = [tag for tag in returned_list if tag not in tags]
|
||||||
|
|
||||||
|
return returned_list
|
||||||
|
|
||||||
|
|
||||||
def sanitize_input_tags(input_tags: str) -> list[str]:
|
def sanitize_input_tags(input_tags: str) -> list[str]:
|
||||||
tags: list[str] = input_tags.split(";")
|
tags: list[str] = input_tags.split(";")
|
||||||
for tag in tags:
|
for tag in tags:
|
||||||
|
Reference in New Issue
Block a user