diff --git a/CLAUDE.md b/CLAUDE.md
index 802d45e..36dea23 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -24,3 +24,13 @@ Commit message here.
- Any fake corporate entities as co-authors
**Only attribute real humans** as co-authors when collaborating.
+
+## Database Migrations (Alembic)
+
+When adding new columns or modifying the database schema:
+
+1. **Backup SQLite first**: `cp data/remarkbox.sqlite data/remarkbox.sqlite.bak`
+2. **Add the column to the model** in `remarkbox/models/`
+3. **Generate migration**: `alembic -c development.ini revision --autogenerate -m "description"`
+4. **Clean up migration**: Remove extra autogenerated changes, keep only the new field
+5. **Run migration**: `alembic -c development.ini upgrade head`
diff --git a/development.ini b/development.ini
index 3da0494..975c8cb 100644
--- a/development.ini
+++ b/development.ini
@@ -2,8 +2,8 @@
# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
[alembic]
-script_location = remarkbox:scripts/alembic
-sqlalchemy.url = sqlite:///%(here)s/remarkbox.sqlite
+script_location = remarkbox/scripts/alembic
+sqlalchemy.url = sqlite:///%(here)s/data/remarkbox.sqlite
[app:main]
use = egg:remarkbox
diff --git a/remarkbox/models/namespace.py b/remarkbox/models/namespace.py
index 5c711d7..63fe580 100644
--- a/remarkbox/models/namespace.py
+++ b/remarkbox/models/namespace.py
@@ -86,6 +86,8 @@ class Namespace(RBase, Base):
owner_request_timestamp = Column(BigInteger, nullable=True)
# optional google analytics id for stand alone mode.
google_analytics_id = Column(Unicode(18), nullable=True)
+ # optional google site verification code for stand alone mode.
+ google_site_verification = Column(Unicode(128), nullable=True)
# allow anyone to edit the root node. (not implemented yet)
wiki = Column(Boolean, default=False)
# by default we show all nodes but a Namespace can change this behavior.
diff --git a/remarkbox/scripts/alembic/versions/d1213344ca99_add_google_site_verification_column_to_.py b/remarkbox/scripts/alembic/versions/d1213344ca99_add_google_site_verification_column_to_.py
new file mode 100644
index 0000000..de4cab4
--- /dev/null
+++ b/remarkbox/scripts/alembic/versions/d1213344ca99_add_google_site_verification_column_to_.py
@@ -0,0 +1,24 @@
+"""add google_site_verification column to namespace
+
+Revision ID: d1213344ca99
+Revises: 108519de76ac
+Create Date: 2026-01-11 09:06:53.272415
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = 'd1213344ca99'
+down_revision = '108519de76ac'
+branch_labels = None
+depends_on = None
+
+from alembic import op
+import sqlalchemy as sa
+
+
+def upgrade():
+ op.add_column('rb_namespace', sa.Column('google_site_verification', sa.Unicode(length=128), nullable=True))
+
+
+def downgrade():
+ op.drop_column('rb_namespace', 'google_site_verification')
diff --git a/remarkbox/templates/base.j2 b/remarkbox/templates/base.j2
index f0c7d78..5769f0c 100644
--- a/remarkbox/templates/base.j2
+++ b/remarkbox/templates/base.j2
@@ -9,6 +9,9 @@
+{% if request.path == '/' and request.namespace.google_site_verification %}
+
+{% endif %}
{% include 'snippets/stylesheet-includes.j2' %}
diff --git a/remarkbox/templates/namespace-settings.j2 b/remarkbox/templates/namespace-settings.j2
index c4e1234..2773df4 100644
--- a/remarkbox/templates/namespace-settings.j2
+++ b/remarkbox/templates/namespace-settings.j2
@@ -125,6 +125,12 @@ You can host your own CSS file and link it here.
+
+
+
+
+
+
{% set submit_button_classes = 'button-right green-button' %}
{% set submit_button_value = 'save changes' %}
{% include 'snippets/submit.j2' %}
diff --git a/remarkbox/views/authenticated/authenticated.py b/remarkbox/views/authenticated/authenticated.py
index 1685612..247f12f 100644
--- a/remarkbox/views/authenticated/authenticated.py
+++ b/remarkbox/views/authenticated/authenticated.py
@@ -58,6 +58,9 @@ def namespace_settings(request):
google_analytics_id = p.get(
"google-analytics-id", request.namespace.google_analytics_id
)
+ google_site_verification = p.get(
+ "google-site-verification", request.namespace.google_site_verification
+ )
hide_unless_approved_checkbox = p.get("hide-unless-approved-checkbox", "off")
allow_anonymous_checkbox = p.get("allow-anonymous-checkbox", "off")
@@ -137,6 +140,17 @@ def namespace_settings(request):
)
)
+ if google_site_verification != request.namespace.google_site_verification and (
+ google_site_verification or request.namespace.google_site_verification
+ ):
+ request.namespace.google_site_verification = google_site_verification
+ request.session.flash(
+ (
+ "Success, you changed the Google Site Verification code for stand alone mode.",
+ "success",
+ )
+ )
+
if hide_unless_approved != request.namespace.hide_unless_approved:
request.namespace.hide_unless_approved = hide_unless_approved
request.session.flash(