Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 37 additions & 1 deletion .github/workflows/test_startcmsproject.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,42 @@ concurrency:
cancel-in-progress: true

jobs:
validate-install-rules:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.13'
- name: Validate djangocms_install_rules.json against its schema
run: |
python -m pip install jsonschema
python << 'EOF'
import json
import os
import sys
import jsonschema

with open("djangocms_install_rules.json") as f:
doc = json.load(f)

schema_file = os.path.basename(doc.get("$schema", ""))
if not schema_file:
sys.exit("djangocms_install_rules.json has no $schema reference")
if not os.path.exists(schema_file):
sys.exit(f"Referenced schema {schema_file} not found in repository")

with open(schema_file) as f:
schema = json.load(f)

jsonschema.Draft7Validator.check_schema(schema)
errors = list(jsonschema.Draft7Validator(schema).iter_errors(doc))
for error in errors:
print(f"ERROR at {list(error.absolute_path)}: {error.message}")
sys.exit(1 if errors else 0)
EOF

create-project:
runs-on: ${{ matrix.os }}
strategy:
Expand All @@ -33,4 +69,4 @@ jobs:
source ./.venv/bin/activate
python -m pip install --upgrade pip
python -m pip install Django~=${{ matrix.django-version }} django-cms
djangocms mysite --noinput --template https://github.com/${{ github.repository }}/archive/${{ github.head_ref || github.ref_name }}.zip
djangocms mysite --noinput --name requirements.in --template https://github.com/${{ github.repository }}/archive/${{ github.head_ref || github.ref_name }}.zip
71 changes: 71 additions & 0 deletions djangocms_install_rules.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"$schema": "https://raw.githubusercontent.com/django-cms/cms-template/main/djangocms_install_rules.schema.v1.json",
"comment": "Rules used by `djangocms .` to add django CMS to an existing project. Fetched from the cms-template repository (branch matching the installed django CMS major.minor), with this file as the bundled fallback. Each `when` condition may contain a `flag` (truthy command option) and/or a `mode` (list of matching --mode values). For installed_apps and middleware a rule may also carry a `before` or `after` anchor (an existing entry) for positional insertion; otherwise items are appended.",
"installed_apps": [
{"items": ["djangocms_simple_admin_style"], "before": "django.contrib.admin"},
{
"items": [
"django.contrib.sites",
"cms",
"menus",
"treebeard",
"sekizai",
"filer",
"easy_thumbnails",
"djangocms_frontend",
"djangocms_text",
"djangocms_link"
]
},
{"items": ["djangocms_versioning"], "when": {"flag": "versioning"}},
{"items": ["djangocms_moderation"], "when": {"flag": "moderation"}},
{"items": ["djangocms_alias"], "when": {"flag": "alias"}},
{"items": ["djangocms_stories", "taggit", "taggit_autosuggest"], "when": {"flag": "stories"}},
{"items": ["rest_framework", "djangocms_rest"], "when": {"mode": ["headless", "hybrid"]}}
],
"middleware": [
{
"items": ["django.middleware.locale.LocaleMiddleware"],
"after": "django.contrib.sessions.middleware.SessionMiddleware"
},
{
"items": [
"cms.middleware.user.CurrentUserMiddleware",
"cms.middleware.page.CurrentPageMiddleware",
"cms.middleware.toolbar.ToolbarMiddleware",
"cms.middleware.language.LanguageCookieMiddleware"
]
}
],
"context_processors": [
{
"items": [
"django.template.context_processors.i18n",
"sekizai.context_processors.sekizai",
"cms.context_processors.cms_settings"
]
}
],
"settings": [
{"name": "SITE_ID", "snippet": "SITE_ID = 1"},
{"name": "X_FRAME_OPTIONS", "snippet": "X_FRAME_OPTIONS = \"SAMEORIGIN\""},
{"name": "CMS_CONFIRM_VERSION4", "snippet": "CMS_CONFIRM_VERSION4 = True"},
{"name": "LANGUAGES", "snippet": "LANGUAGES = [\n (\"{language_code}\", \"{language_name}\"),\n]"},
{"name": "CMS_TEMPLATES", "snippet": "CMS_TEMPLATES = [\n (\"cms-base.html\", \"Default\"),\n]", "when": {"mode": ["traditional", "hybrid"]}},
{"name": "CMS_PLACEHOLDERS", "snippet": "CMS_PLACEHOLDERS = [\n (\"cms-base.html\", (\"content\",), \"Content\"),\n]", "when": {"mode": ["headless"]}}
],
"urls": [
{"pattern": "path(\"api/\", include(\"djangocms_rest.urls\"))", "when": {"mode": ["headless", "hybrid"]}},
{"pattern": "path(\"taggit_autosuggest/\", include(\"taggit_autosuggest.urls\"))", "when": {"flag": "stories"}},
{"pattern": "path(\"\", include(\"cms.urls\"))", "when": {"mode": ["traditional", "hybrid"]}}
],
"packages": {
"filer": "django-filer"
},
"template_dir": {
"path": "templates",
"base_template": "cms-base.html",
"base_template_content": "{% extends \"bootstrap5/base.html\" %}{# Replace this with your CMS base template1 #}\n",
"when": {"mode": ["traditional", "hybrid"]}
}
}
196 changes: 196 additions & 0 deletions djangocms_install_rules.schema.v1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://raw.githubusercontent.com/django-cms/cms-template/main/djangocms_install_rules.schema.v1.json",
"title": "django CMS install rules",
"description": "Rules used by `djangocms .` to add django CMS to an existing Django project. Fetched from the cms-template repository (branch matching the installed django CMS major.minor), with the bundled file as fallback.",
"type": "object",
"additionalProperties": false,
"properties": {
"$schema": {
"type": "string"
},
"comment": {
"type": "string",
"description": "Free-form documentation; ignored by the installer."
},
"installed_apps": {
"type": "array",
"description": "Apps to add to INSTALLED_APPS. Items are appended unless a before/after anchor is given.",
"items": {
"$ref": "#/definitions/anchoredRule"
}
},
"middleware": {
"type": "array",
"description": "Middleware to add to MIDDLEWARE. Items are appended unless a before/after anchor is given.",
"items": {
"$ref": "#/definitions/anchoredRule"
}
},
"context_processors": {
"type": "array",
"description": "Context processors to append to the template OPTIONS.",
"items": {
"$ref": "#/definitions/itemsRule"
}
},
"settings": {
"type": "array",
"description": "Settings snippets to append to settings.py if the named setting is not already defined.",
"items": {
"$ref": "#/definitions/settingRule"
}
},
"urls": {
"type": "array",
"description": "URL patterns to add to the project urlpatterns.",
"items": {
"$ref": "#/definitions/urlRule"
}
},
"packages": {
"type": "object",
"description": "Maps an installed app or module name to its pip requirement, where the two differ.",
"additionalProperties": {
"type": "string"
}
},
"template_dir": {
"type": "object",
"description": "Template directory to create, with an optional base template to seed it.",
"additionalProperties": false,
"required": ["path"],
"properties": {
"path": {
"type": "string",
"description": "Directory (relative to the project root) to create and register in TEMPLATES['DIRS']."
},
"base_template": {
"type": "string",
"description": "Filename of the base template to create inside the template directory."
},
"base_template_content": {
"type": "string",
"description": "Initial content of the base template."
},
"when": {
"$ref": "#/definitions/when"
},
"comment": {
"type": "string"
}
}
}
},
"definitions": {
"when": {
"type": "object",
"description": "Condition for applying a rule. All given criteria must match.",
"additionalProperties": false,
"minProperties": 1,
"properties": {
"flag": {
"type": "string",
"description": "Name of a command option that must be truthy (e.g. \"versioning\" for --versioning)."
},
"mode": {
"type": "array",
"description": "The rule applies if the --mode value is one of these.",
"minItems": 1,
"items": {
"enum": ["traditional", "headless", "hybrid"]
}
}
}
},
"itemsRule": {
"type": "object",
"additionalProperties": false,
"required": ["items"],
"properties": {
"items": {
"type": "array",
"minItems": 1,
"items": {
"type": "string"
}
},
"when": {
"$ref": "#/definitions/when"
},
"comment": {
"type": "string"
}
}
},
"anchoredRule": {
"type": "object",
"additionalProperties": false,
"required": ["items"],
"not": {
"required": ["before", "after"]
},
"properties": {
"items": {
"type": "array",
"minItems": 1,
"items": {
"type": "string"
}
},
"before": {
"type": "string",
"description": "Existing entry before which the items are inserted."
},
"after": {
"type": "string",
"description": "Existing entry after which the items are inserted."
},
"when": {
"$ref": "#/definitions/when"
},
"comment": {
"type": "string"
}
}
},
"settingRule": {
"type": "object",
"additionalProperties": false,
"required": ["name", "snippet"],
"properties": {
"name": {
"type": "string",
"description": "Setting name; the snippet is only added if this setting is not already defined."
},
"snippet": {
"type": "string",
"description": "Python code appended to settings.py. May contain {language_code}/{language_name} placeholders."
},
"when": {
"$ref": "#/definitions/when"
},
"comment": {
"type": "string"
}
}
},
"urlRule": {
"type": "object",
"additionalProperties": false,
"required": ["pattern"],
"properties": {
"pattern": {
"type": "string",
"description": "Python expression for the URL pattern, e.g. path(\"\", include(\"cms.urls\"))."
},
"when": {
"$ref": "#/definitions/when"
},
"comment": {
"type": "string"
}
}
}
}
}
27 changes: 21 additions & 6 deletions project_name/settings.py-tpl
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,22 @@ INSTALLED_APPS = [
'menus',

'djangocms_text',
'djangocms_link',
'djangocms_alias',
'djangocms_versioning',

'djangocms_link',{% if alias %}
'djangocms_alias',{% endif %}{% if versioning %}
'djangocms_versioning',{% endif %}{% if moderation %}
'djangocms_moderation',{% endif %}
{% if stories %}
'djangocms_stories',
'taggit',
'taggit-autosuggest',
'parler',
{% endif %}
{% if mode == "headless" or mode == "hybrid" %}
'djangocms_rest',
'rest_framework',
{% endif %}
'sekizai',
'treebeard',
'parler',

'filer',
'easy_thumbnails',
Expand Down Expand Up @@ -198,12 +207,18 @@ CMS_CONFIRM_VERSION4 = True

SITE_ID = 1

# A base template is part of this setup
{% if mode == "headless" %}# A setting to define which placeholders are used

CMS_PLACEHOLDERS = (
("base.html", ("content", "Content"))
)
{% else %}# A base template is part of this setup
# https://docs.django-cms.org/en/{% if cms_docs_version %}release-{{ cms_docs_version }}.x{% else %}latest{% endif %}/reference/configuration.html#cms-templates

CMS_TEMPLATES = (
("base.html", _("Standard")),
)
{% endif %}

# Enable permissions
# https://docs.django-cms.org/en/{% if cms_docs_version %}release-{{ cms_docs_version }}.x{% else %}latest{% endif %}/topics/permissions.html
Expand Down
6 changes: 4 additions & 2 deletions project_name/urls.py-tpl
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ from django.views.i18n import JavaScriptCatalog
urlpatterns = i18n_patterns(
path('jsi18n/', JavaScriptCatalog.as_view(), name='javascript-catalog'),
path('admin/', admin.site.urls),
path('filer/', include('filer.urls')),
path('', include('cms.urls')),
path('filer/', include('filer.urls')),{% if stories %}
path('taggit_autosuggest', include('taggit_autosuggest.urls')){% endif %}{% if mode == "hybrid" or mode == "headless" %}
path('api', include("djangocms_rest.urls"))),{% endif %}{% if mode == "hybrid" or mode == "traditional" %}
path('', include('cms.urls')),{% endif %}
)


Expand Down
12 changes: 7 additions & 5 deletions requirements.in
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
djangocms-versioning
djangocms-alias
djangocms-frontend>=2.0.0a1
djangocms-frontend>=2.0.0
django-filer
djangocms-text
django-fsm<3
djangocms-simple-admin-style
django-treebeard!=5.0.3
django-parler{% if versioning %}djangocms-versioning
{% endif %}{% if alias %}djangocms-alias
{% endif %}{% if moderation %}djangocms-moderation
{% endif %}{% if mode == "headless" or mode == "hybrid" %}djangocms-rest
{% endif %}{% if stories %}djangocms-stories
{% endif %}
Loading