{# =================================================================== Start Page controls — used twice, with two different scopes: scope="user" what I see -> /api/user/preferences scope="global" what a new account sees by default -> PUT /api/settings (admin) Both render the same objects, so learning one teaches the other. The ids carry the scope so the settings page can show both at once, and static/start_page.js drives them from the same code path. Each scope is ONE card. Rows, cards-per-row and the filters are facets of a single decision ("what does this home page look like"), not three unrelated settings -- rendering them as three separate cards made the page read as six independent things and buried the fact that the whole lower half is just the same form again for a different audience. The row labels/hints are rendered here (through Flask-Babel) and read by the JS from window.__STARTPAGE_I18N -- the row list itself is built client-side from /api/home-feed/sources, because which sources exist depends on which modules are installed. =================================================================== #} {# NB: never put a Jinja comment INSIDE the dict expression below -- one inside a {{ ... }} expression is a syntax error that takes the whole page down (and Jinja comments do not nest, so this one cannot show you the token either). "column_n" carries the column number as %(n)s filled with a literal brace pair here, because Flask-Babel's newstyle gettext turns a bare "%s" into that same brace pair in the rendered catalogue string, and it is what static/start_page.js replaces at runtime. #} {% macro start_page_i18n() %} {% endmacro %} {# heading/intro are optional: the settings page passes them so the card carries its own title, the home page modal leaves them empty because the modal already has a title of its own. #} {% macro start_page_form(scope, show_new_home_toggle=False, heading='', intro='') %}