diff --git a/src/kitconcept/seo/configure.zcml b/src/kitconcept/seo/configure.zcml
index 4ae4ef3..843a045 100644
--- a/src/kitconcept/seo/configure.zcml
+++ b/src/kitconcept/seo/configure.zcml
@@ -16,4 +16,6 @@
+
+
diff --git a/src/kitconcept/seo/subscribers.py b/src/kitconcept/seo/subscribers.py
new file mode 100644
index 0000000..9f2452c
--- /dev/null
+++ b/src/kitconcept/seo/subscribers.py
@@ -0,0 +1,16 @@
+from kitconcept.seo.behaviors.seo import ISeo
+from plone.dexterity.interfaces import IDexterityContent
+from zope.component import adapter
+from ZPublisher.interfaces import IPubAfterTraversal
+from ZPublisher.pubevents import PubAfterTraversal
+
+
+@adapter(IPubAfterTraversal)
+def add_x_robots_noindex_header(event: PubAfterTraversal):
+ """Add X-Robots-Tag to prevent indexing items with seo_noindex."""
+ request = event.request
+ for obj in request["PARENTS"]:
+ if IDexterityContent.providedBy(obj):
+ if ISeo.providedBy(obj) and obj.seo_noindex:
+ request.response.setHeader("X-Robots-Tag", "noindex")
+ break
diff --git a/tests/conftest.py b/tests/conftest.py
index 63cbe85..1a31697 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -24,6 +24,6 @@
@pytest.fixture
def manager_plone_client(functional):
portal = functional["portal"]
- api_session = RelativeSession(f"{portal.absolute_url()}/++api++")
+ api_session = RelativeSession(f"{portal.absolute_url()}")
api_session.auth = (SITE_OWNER_NAME, SITE_OWNER_PASSWORD)
return api_session
diff --git a/tests/test_behavior.py b/tests/test_behavior.py
index 20d052c..abd93a8 100644
--- a/tests/test_behavior.py
+++ b/tests/test_behavior.py
@@ -1,11 +1,11 @@
def test_seo_behavior_fields(manager_plone_client):
# Enable behavior for pages
manager_plone_client.patch(
- "/@controlpanels/dexterity-types/Document", json={"kitconcept.seo": True}
+ "++api++/@controlpanels/dexterity-types/Document", json={"kitconcept.seo": True}
)
# Check schema
- schema = manager_plone_client.get("/@types/Document").json()
+ schema = manager_plone_client.get("++api++/@types/Document").json()
assert schema["fieldsets"][-1] == {
"behavior": "plone",
"description": "",
@@ -21,3 +21,27 @@ def test_seo_behavior_fields(manager_plone_client):
"id": "seo",
"title": "SEO",
}
+
+
+def test_noindex_sets_response_header(manager_plone_client):
+ # Enable behavior for pages
+ manager_plone_client.patch(
+ "++api++/@controlpanels/dexterity-types/Document", json={"kitconcept.seo": True}
+ )
+
+ # Add page
+ resp = manager_plone_client.post(
+ "++api++/",
+ json={"@type": "Document", "title": "Test page", "seo_noindex": True},
+ )
+ assert resp.status_code == 201
+
+ # Confirm the page is served with X-Robots-Tag header
+ resp = manager_plone_client.get("/test-page")
+ assert resp.status_code == 200
+ assert resp.headers["X-Robots-Tag"] == "noindex"
+
+ # Confirm views of the page are served with X-Robots-Tag header
+ resp = manager_plone_client.get("/test-page/@@view")
+ assert resp.status_code == 200
+ assert resp.headers["X-Robots-Tag"] == "noindex"