Skip to content

Commit

Permalink
Localization / doc fixes (#650)
Browse files Browse the repository at this point in the history
* localization / doc fixes:
- add missing header.html
- docs: support 'i18n' extra, mention in docs
- use 'default_locale' for html lang tag
- access control docs: fix documentation for adding user with acl command

* localization: add compile_catalog after extract as well to simplify updates for identity (en) locale

* ui: 
- include locale in home page collection listing
- keep locale on error page home link

* autoescape:
- ensure jinja2 templates are autoescaped to prevent xss issues (thanks @sebastian-nagel for suggested fix)
- ensure banner inserts are not double-escaped
- update tests for template autoescaping

* update CHANGES.rst

* bump version to 2.6.0b1
  • Loading branch information
ikreymer authored Jun 15, 2021
1 parent 9587954 commit f7bd84c
Show file tree
Hide file tree
Showing 15 changed files with 57 additions and 12 deletions.
14 changes: 14 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
pywb 2.6.0b1 changelist
~~~~~~~~~~~~~~~~~~~~~~~

Additional documentation / localization fixes `#650 <https://github.com/webrecorder/pywb/pull/650>`_

* Ensure home page and error page keeps locale, language switching is working.

* Add autoescaping to Jinja2 to avoid XSS issues (suggested by @sebastian-nagel)

* Add support for 'pywb[i18n]' extra to install localization dependencies

Documentation typo fixes (by @ldko, `#649 <https://github.com/webrecorder/pywb/pull/649>`_)


pywb 2.6.0b0 changelist
~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
3 changes: 0 additions & 3 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,3 @@ enable_memento: true
# Replay content in an iframe
framed_replay: true

locales:
- en
- es
2 changes: 1 addition & 1 deletion docs/manual/access-control.rst
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ The URL supplied can be a URL or a SURT prefix. If a SURT is supplied, it is use

A specific user for user-based rules can also be specified, for example to add ``allow_ignore_embargo`` for user ``staff`` only, run::

wb-manager acl add <collection> http://httpbin.org/anything/something allow_ignore_embargo staff
wb-manager acl add <collection> http://httpbin.org/anything/something allow_ignore_embargo -u staff


By default, access control rules apply to a prefix of a given URL or SURT.
Expand Down
5 changes: 5 additions & 0 deletions docs/manual/localization.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@ pywb can extract all text from templates and generate CSV files for translation

(pywb uses the `Babel library <http://babel.pocoo.org/en/latest/>`_ which extends the `standard Python i18n system <https://docs.python.org/3/library/gettext.html>`_)

To ensure all localization related dependencies are installed, first run::

pip install pywb[i18n]

Locales to use are configured in the ``config.yaml``.

The command-line ``wb-manager`` utility provides a way to manage locales for translation, including generating extracted text, and to update translated text.


Adding a Locale and Extracting Text
===================================

Expand Down
2 changes: 2 additions & 0 deletions pywb/manager/locmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ def extract_loc(self, locale, no_csv):
csv = os.path.join(base, 'messages.csv')
po2csv([po, csv])

self.compile_catalog()

def update_loc(self, locale, no_csv):
for loc in locale:
if not no_csv:
Expand Down
4 changes: 3 additions & 1 deletion pywb/rewrite/templateview.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from six.moves.urllib.parse import urlsplit, quote

from jinja2 import Environment, TemplateNotFound, contextfunction
from jinja2 import Environment, TemplateNotFound, contextfunction, select_autoescape
from jinja2 import FileSystemLoader, PackageLoader, ChoiceLoader

from babel.support import Translations
Expand Down Expand Up @@ -77,10 +77,12 @@ def __init__(self, paths=None,

if overlay:
jinja_env = overlay.jinja_env.overlay(loader=loader,
autoescape=select_autoescape(),
trim_blocks=True,
extensions=extensions)
else:
jinja_env = RelEnvironment(loader=loader,
autoescape=select_autoescape(),
trim_blocks=True,
extensions=extensions)

Expand Down
2 changes: 1 addition & 1 deletion pywb/templates/base.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="{{ env.pywb_lang | default('en') }}">
<html lang="{{ env.pywb_lang | default(default_locale) }}">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8;charset=utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
Expand Down
2 changes: 1 addition & 1 deletion pywb/templates/error.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ <h2 class="display-2">Pywb Error</h2>
{% elif err_status == 404 and err_details == 'coll_not_found' %}
<p>{% trans %}Collection not found: <b>{{ err_msg }}{% endtrans %}</b></p>

<p><a href="/">{{ _('See list of valid collections') }}</a></p>
<p><a href="/{{ env.pywb_lang | default('') }}">{{ _('See list of valid collections') }}</a></p>

{% elif err_status == 404 and err_details == 'static_file_not_found' %}
<p>{% trans %}Static file not found: <b>{{ err_msg }}{% endtrans %}</b></p>
Expand Down
4 changes: 4 additions & 0 deletions pywb/templates/frame_insert.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,12 @@
</style>
<script src='{{ static_prefix }}/wb_frame.js'> </script>

{% autoescape false %}

{{ banner_html }}

{% endautoescape %}

</head>
<body style="margin: 0px; padding: 0px;">

Expand Down
4 changes: 4 additions & 0 deletions pywb/templates/head_insert.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{% autoescape false %}

<!-- WB Insert -->
<script>
{% set urlsplit = cdx.url | urlsplit %}
Expand Down Expand Up @@ -61,5 +63,7 @@

{{ banner_html }}

{% endautoescape %}

<!-- End WB Insert -->

13 changes: 13 additions & 0 deletions pywb/templates/header.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<header>
{% if locales|length > 1 %}
<div class="language-select">
{{ _('Language:') }}
<ul role="listbox" aria-activedescendant="{{ env.pywb_lang | default(default_locale) }}" aria-labelledby="{{ _('Language select') }}">
{% for locale in locales %}
<li role="option" id="{{ locale }}"><a href="{{ switch_locale(locale) }}">{{ locale }}</a></li>
{% endfor %}
</ul>
</div>
{% endif %}
</header>

2 changes: 1 addition & 1 deletion pywb/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ <h2 class="display-2">{{ _('Pywb Wayback Machine') }}</h2>
<ul>
{% for route in routes %}
<li>
<a href="{{ env['pywb.app_prefix'] + '/' + route }}">{{ '/' + route }}</a>
<a href="{{ env['pywb.app_prefix'] + ('/' + env.pywb_lang if env.pywb_lang else '') + '/' + route }}">{{ '/' + route }}</a>
{% if all_metadata and all_metadata[route] %}
({{ all_metadata[route].title }})
{% endif %}
Expand Down
2 changes: 1 addition & 1 deletion pywb/version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = '2.6.0b0'
__version__ = '2.6.0b1'

if __name__ == '__main__':
print(__version__)
3 changes: 3 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ def get_package_data():
glob.glob('sample_archive/text_content/*')),
],
install_requires=load_requirements('requirements.txt'),
extras_require={
"i18n": ["translate_toolkit"],
},
tests_require=[
'pytest',
'WebTest',
Expand Down
7 changes: 4 additions & 3 deletions tests/test_auto_colls.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,15 +313,16 @@ def test_more_custom_templates(self):
assert resp.status_int == 200
assert resp.content_type == 'text/html'
assert 'overriden search page: ' in resp.text
print(resp.text)
assert '"some":"value"' in resp.text, resp.text
#assert '"some":"value"' in resp.text, resp.text
assert '{&#34;some&#34;:&#34;value&#34;}' in resp.text, resp.text

def test_replay_banner_metadata(self, fmod):
""" Test adding metadata in replay banner (both framed and non-frame)
"""
resp = self.get('/test/20140103030321{0}/http://example.com/?example=1', fmod)
assert '<div>Custom Banner Here!</div>' in resp.text
assert '"some":"value"' in resp.text
#assert '"some":"value"' in resp.text
assert '{&#34;some&#34;:&#34;value&#34;}' in resp.text, resp.text

def test_more_custom_templates_replay(self, fmod):
resp = self.get('/test/20140103030321{0}/http://example.com/?example=1', fmod)
Expand Down

0 comments on commit f7bd84c

Please sign in to comment.