Skip to content

Commit

Permalink
fix index entries in usage reports (#5)
Browse files Browse the repository at this point in the history
* squash commits. fix version to 5, add signals / hooks

* make index entries visible to usage reports

* update tests

* improve error handling

* stop unpublished and draft pages from being indexed
  • Loading branch information
Ross-Clark authored Jul 23, 2024
1 parent ca46eef commit 1850b7c
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 13 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python: [3.7, 3.8, 3.9]
python: [3.8, 3.9]

steps:
- uses: actions/checkout@v2
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,8 @@ wagtail_streamfield_index.egg-info
media/
Pipfile
Pipfile.lock
venv/
.venv/
build/
__pycache__
.vscode/
6 changes: 3 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
with open("README.md", "r") as fh:
long_description = fh.read()

INSTALL_REQUIRES = ["django>=3.2", "Wagtail>=4.0"]
INSTALL_REQUIRES = ["django>=3.2", "Wagtail>=5.0.0", " wagtail < 6.0"]

TESTING_REQUIRES = ["pytest==5.2.1", "pytest-django==3.5.1", "pytest-pythonpath==0.7.3"]
TESTING_REQUIRES = ["pytest==6.2.5", "pytest-django==3.5.1", "pytest-pythonpath==0.7.3", "factory-boy>=3.2"]

LINTING_REQUIRES = ["black==20.8b1", "flake8==3.7.8", "flake8-black==0.1.1", "isort==5.7.0"]

setup(
name="wagtail-streamfield-index",
version="0.0.4",
version="1.0.0",
description="Indexing for Wagtail streamfields",
author="Mike Monteith",
author_email="<[email protected]>",
Expand Down
13 changes: 7 additions & 6 deletions streamfieldindex/indexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,20 @@ def index_page(page):
# Clear the index for this specific page
IndexEntry.objects.filter(page__id=page.id).delete()

for field in page._meta.fields:
if not isinstance(field, StreamField):
# We are only interested in streamfields. Skip over non-streamfield fields
continue
if page.live: # we dont want to index any draft/unpublished pages
for field in page._meta.fields:
if not isinstance(field, StreamField):
# We are only interested in streamfields. Skip over non-streamfield fields
continue

index_field(field, page)
index_field(field, page)


def index_field(field, page):

field_name = field.name
streamvalue = getattr(page, field_name)
for (block, path) in flatten_streamfield(streamvalue):
for block, path in flatten_streamfield(streamvalue):
field_name = field_name
block_name = path[-1]

Expand Down
8 changes: 6 additions & 2 deletions streamfieldindex/models.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from django.db import models
from django.urls import reverse
from wagtail.blocks import ListBlock, StreamBlock, StructBlock


Expand All @@ -21,6 +22,9 @@ class IndexEntry(models.Model):

page = models.ForeignKey("wagtailcore.Page", on_delete=models.CASCADE)

def get_edit_url(self):
return reverse("wagtailadmin_pages:edit", args=[self.page.id])

def get_bound_block(self):
field_value = getattr(self.page.specific, self.field_name)
path = self.block_path.split("/")
Expand All @@ -43,15 +47,15 @@ def get_sub_block(bound_block, path_list):
next_block = bound_block.value[index]
return get_sub_block(next_block, path_list)
else:
raise Exception(f"We don't know how to iterate over block type {type(bound_block.block)}")
raise ValueError(f"We don't know how to iterate over block type {type(bound_block.block)}")

first_index = path.pop(0) # The first index must always be a number, since it is a streamfield
path.pop(0) # We can throw away the next path as it is just the block_type which we don't need
block = field_value[int(first_index)]
return get_sub_block(block, path)

def __str__(self):
return f"<IndexEntry {self.page.title}::{self.field_name}::{self.block_path}>"
return f"Streamfield index: {self.page.title} {self.field_name} {self.block_path}" # noqa E231

class Meta:
verbose_name_plural = "Index Entries"
32 changes: 31 additions & 1 deletion streamfieldindex/wagtail_hooks.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from django.urls import reverse
from wagtail import hooks
from wagtail.signals import page_published
from wagtail.admin.admin_url_finder import ModelAdminURLFinder, register_admin_url_finder
from wagtail.signals import page_published, page_unpublished, post_page_move

from .indexer import index_page
from .models import IndexEntry


@hooks.register("after_create_page")
Expand All @@ -14,8 +17,35 @@ def index_after_edit_page(request, page):
index_page(page)


@hooks.register("after_copy_page")
def index_after_copy_page(request, page):
index_page(page)


def post_publish(sender, instance, **kwargs):
index_page(instance)


def index_post_page_move(sender, instance, **kwargs):
index_page(instance)


def index_post_unpublished(sender, instance, **kwargs):
index_page(instance)


class IndexEntryAdminURLFinder(ModelAdminURLFinder):
"""
Custom URL finder for IndexEntry model
https://github.com/gasman/wagtail/blob/9174db40746514b6fa6d792b25507571381c9255/wagtail/admin/admin_url_finder.py#L28
"""

def construct_edit_url(self, instance):
return reverse("wagtailadmin_pages:edit", args=[instance.page.id])


register_admin_url_finder(IndexEntry, IndexEntryAdminURLFinder)

page_published.connect(post_publish)
page_unpublished.connect(index_post_unpublished)
post_page_move.connect(index_post_page_move)
21 changes: 21 additions & 0 deletions tests/test_wagtail_hooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import pytest
from django.urls import reverse
from wagtail.test.utils.wagtail_factories import PageFactory
from wagtail.tests.utils import WagtailTestUtils

import streamfieldindex
from streamfieldindex.wagtail_hooks import IndexEntryAdminURLFinder


@pytest.mark.django_db
class TestIndexEntryAdminURLFinder(WagtailTestUtils):
def test_construct_edit_url(self):
finder = IndexEntryAdminURLFinder()
instance = streamfieldindex.models.IndexEntry(
page=PageFactory(),
block_type="text",
block_value="Hello, world!",
block_path="content",
)
expected_url = reverse("wagtailadmin_pages:edit", args=[instance.page.id])
assert finder.construct_edit_url(instance) == expected_url

0 comments on commit 1850b7c

Please sign in to comment.