Skip to content

Commit

Permalink
Editsection plugin: Relax path regex (fixing NoReverseMatch) (#1299)
Browse files Browse the repository at this point in the history
* Rework editsection plugin (fixes #1246)

The main problem of editsection is to find the correct location of the
section to edit in the source. Previously, that was done with custom,
regex-based parsing, but that fails when code blocks contain lines which
look like a header (for example, python comments).

This patch uses another approach to find the correct sections. It uses
extended versions of the BlockParsers responsible for creating headers,
which annotate those headers with the consumed source block. Since we
know now which input was responsible for generating the header, we can
easily locate it in the markdown source.

* try to make the linter happy...

* try harder to make the linter happy...

* try even harder to make the linter happy...

* add a test for nonunique headers

* reformat tests, too

* reorder imports

* Pass current revision to Editor.get_widget()/get_admin_widget()

Sometimes it is useful to have the current revision in the editor
widget instance, for example to create preview and upload links,
autocomplete, ...

<textarea name="content"
          data-upload-url='/wiki/my-page/_plugin/attachments/...'>

Previously, EditorBase had an instance attribute "instance", but that
doesn't make sense (there is only one global instance of Editor) and
wasn't ever filled anyway. This patch removes that, renames the
"instance" parameter in get_widget()/get_admin_widget() to "revision"
(to make clear what this parameter is) and fills it appropriately.

* add tests to improve coverage

* Relax editsection path regex

Problem:

The following, valid markdown will throw a NoReverseMatch exception:

 # Title1 {#some_id_with.dot}

This is due to editsection's url regex not allowing dots and other,
non-whitespace characters.

Solution:

Relax the url regex to allow any non-whitespace character, as HTML5
does.

* fix linting
  • Loading branch information
chrisv2 committed Jul 31, 2023
1 parent e563fbe commit 8db7f19
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/wiki/plugins/editsection/wiki_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class EditSectionPlugin(BasePlugin):
urlpatterns = {
"article": [
url(
r"^header/(?P<header>[\w-]+)/$",
r"^header/(?P<header>[\S]+)/$",
views.EditSection.as_view(),
name="editsection",
),
Expand Down
14 changes: 14 additions & 0 deletions tests/plugins/editsection/test_editsection.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,20 @@ def test_nonunique_headers(self):
expected = "## Date\r\n2023-01-02"
self.assertEqual(actual, expected)

def test_underscore_and_dot(self):
"""test whether we can handle non-slug characters like dots in header IDs"""
# Explanation: While autogenerated ids are slugified, Markdown allows to manually
# specify the ID using the {#custom_id_value} syntax. As HTML5 only requires ID
# values not to contain whitespace, we should be able to handle any valid HTML5 ID, too.
source = """# Title 1 {#some_id_with.dot}\n\n"""
urlpath = URLPath.create_urlpath(
URLPath.root(), "testedit", title="TestEdit", content=source
)
# rendering causes NoReverseMatch without the fix
actual = urlpath.article.render()
expected = '<h1 id="some_id_with.dot">Title 1<a class="article-edit-title-link" href="/testedit/_plugin/editsection/header/some_id_with.dot/">[edit]</a></h1>'
self.assertEqual(actual, expected)


class EditSectionEditBase(RequireRootArticleMixin, FuncBaseMixin):
pass
Expand Down

0 comments on commit 8db7f19

Please sign in to comment.