refactor: added custom routing for profiles
- installed a regex conveter to werkzeug to support regular expresions in routes - added a website route rule to match all profiles
This commit is contained in:
@@ -91,7 +91,7 @@ app_include_js = "/assets/community/js/community.js"
|
|||||||
# Hook on document methods and events
|
# Hook on document methods and events
|
||||||
|
|
||||||
doc_events = {
|
doc_events = {
|
||||||
"User": {
|
"User": {
|
||||||
"after_insert": "community.community.doctype.community_member.community_member.create_member_from_user"
|
"after_insert": "community.community.doctype.community_member.community_member.create_member_from_user"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -127,8 +127,29 @@ scheduler_events = {
|
|||||||
#
|
#
|
||||||
# auto_cancel_exempted_doctypes = ["Auto Repeat"]
|
# auto_cancel_exempted_doctypes = ["Auto Repeat"]
|
||||||
|
|
||||||
website_route_rules = [
|
from .routing import install_regex_converter
|
||||||
|
install_regex_converter()
|
||||||
|
|
||||||
|
# Add all simple route rules here
|
||||||
|
primary_rules = [
|
||||||
{"from_route": "/sketches/<sketch>", "to_route": "sketches/sketch"},
|
{"from_route": "/sketches/<sketch>", "to_route": "sketches/sketch"},
|
||||||
{"from_route": "/courses/<course>", "to_route": "courses/course"},
|
{"from_route": "/courses/<course>", "to_route": "courses/course"},
|
||||||
{"from_route": "/courses/<course>/<topic>", "to_route": "courses/topic"},
|
{"from_route": "/courses/<course>/<topic>", "to_route": "courses/topic"},
|
||||||
|
{"from_route": "/courses/<course>/<topic>", "to_route": "courses/topic"}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Any frappe default URL is blocked by profile-rules, add it here to unblock it
|
||||||
|
whitelist = [
|
||||||
|
"/login",
|
||||||
|
"/update-password",
|
||||||
|
"/update-profile",
|
||||||
|
"/third-party-apps"
|
||||||
|
]
|
||||||
|
whitelist_rules = [{"from_route": p, "to_route": p[1:]} for p in whitelist]
|
||||||
|
|
||||||
|
# regex rule to match all profiles
|
||||||
|
profile_rules = [
|
||||||
|
{"from_route": "/<regex('[a-z0-9-]{5,}'):username>", "to_route": "profiles/profile"},
|
||||||
|
]
|
||||||
|
|
||||||
|
website_route_rules = primary_rules + whitelist_rules + profile_rules
|
||||||
|
|||||||
25
community/routing.py
Normal file
25
community/routing.py
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
"""Utilities for making custom routing.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from werkzeug.routing import BaseConverter, Map
|
||||||
|
from werkzeug.datastructures import ImmutableDict
|
||||||
|
|
||||||
|
class RegexConverter(BaseConverter):
|
||||||
|
"""werkzeug converter that supports custom regular expression.
|
||||||
|
|
||||||
|
The `install_regex_converter` function must be called before using
|
||||||
|
regex converter in rules.
|
||||||
|
"""
|
||||||
|
def __init__(self, map, regex):
|
||||||
|
super().__init__(map)
|
||||||
|
self.regex = regex
|
||||||
|
|
||||||
|
def install_regex_converter():
|
||||||
|
"""Installs the RegexConvetor to the default converters supported by werkzeug.
|
||||||
|
|
||||||
|
This allows specifing rules using regex. For example:
|
||||||
|
|
||||||
|
/profiles/<regex("[a-z0-9]{5,}"):username>
|
||||||
|
"""
|
||||||
|
default_converters = dict(Map.default_converters, regex=RegexConverter)
|
||||||
|
Map.default_converters = ImmutableDict(default_converters)
|
||||||
25
community/www/profiles/profile.html
Normal file
25
community/www/profiles/profile.html
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{% extends "templates/web.html" %}
|
||||||
|
{% block page_content %}
|
||||||
|
<div class="py-20 row">
|
||||||
|
{% if user.photo %}
|
||||||
|
<div class="col-sm-2 border border-dark">
|
||||||
|
<img src="{{ user.photo }}" alt="{{ user.full_name }}">
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="col-sm-2">
|
||||||
|
<div class="standard-image" style="font-size: 30px;">{{ user.abbr }}</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<div class="col">
|
||||||
|
<h1>{{ user.full_name }}</h1>
|
||||||
|
{% if user.short_intro %}
|
||||||
|
<p class="lead"> {{ user.short_intro }} </p>
|
||||||
|
{% endif %}
|
||||||
|
{% if user.bio %}
|
||||||
|
<p class="markdown-style"> {{ frappe.utils.md_to_html(user.bio) }} </p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
<!-- this is a sample default web page template -->
|
||||||
18
community/www/profiles/profile.py
Normal file
18
community/www/profiles/profile.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import frappe
|
||||||
|
|
||||||
|
def get_context(context):
|
||||||
|
context.no_cache = 1
|
||||||
|
|
||||||
|
username = frappe.form_dict.get('username')
|
||||||
|
user = username and get_user(username)
|
||||||
|
if not user:
|
||||||
|
context.template = "www/404.html"
|
||||||
|
|
||||||
|
user.abbr = "".join([s[0] for s in user.full_name.split()])
|
||||||
|
context.user = user
|
||||||
|
|
||||||
|
def get_user(username):
|
||||||
|
try:
|
||||||
|
return frappe.get_doc("Community Member", username)
|
||||||
|
except frappe.DoesNotExistError:
|
||||||
|
return
|
||||||
Reference in New Issue
Block a user