Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
.git
node_modules

democontent/
14 changes: 14 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,20 @@ to see sections that can be removed - in each case, the section is noted with a

Options are also available for using Postgres/MySQL, uWSGI/Gunicorn/Guvicorn, etc.

Loading with pre-built page on install
======================================

It is now possible to load the project with contents which shows how to use
``django-cms`` and ``djangocms-frontend`` to add pages.

Here is how to use the command:
1. To list the available files in the ``democontent`` folder.
Run ``docker compose run --rm web python manage.py democontent``

2. To add a page. Run ``docker compose run --rm web python manage.py democontent <FILE_PATH>``

3. To add a page by force. Run ``docker compose run --rm web python manage.py democontent <FILE_PATH> --force``

Updating requirements
=====================

Expand Down
Empty file added backend/management/__init__.py
Empty file.
Empty file.
107 changes: 107 additions & 0 deletions backend/management/commands/democontent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import os
import json

from django.conf import settings
from django.db import transaction
from django.contrib.auth import get_user_model
from django.core.management.base import BaseCommand

from cms.api import create_page
from cms.models.contentmodels import PageContent
from cms.constants import TEMPLATE_INHERITANCE_MAGIC

from djangocms_transfer.importer import import_plugins_to_page
from djangocms_transfer.datastructures import ArchivedPlaceholder, ArchivedPlugin


LANGUAGE = "en"
DEMOCONTENT = settings.BASE_DIR / "democontent"
User = get_user_model()


class Command(BaseCommand):
help = "Create Demo content."

def add_arguments(self, parser):
parser.add_argument(
"filepath", metavar="FILE_PATH", nargs="?", help="Input file to load from."
)
parser.add_argument(
"--force",
"-f",
action="store_true",
dest="force",
help="Force add page to the page tree."
)

def _page_create_details(self) -> dict:
user, created = User.objects.get_or_create(username="demo")
if created:
self.stdout.write("User with username, 'demo' created")

return {
"title": f"{self.title.title()}",
"template": TEMPLATE_INHERITANCE_MAGIC,
"created_by": user,
"in_navigation": True,
"language": LANGUAGE,
}

def loaddata(self, abs_filepath):
def parse_data(data):
if not data:
return data
if "plugins" in data:
return ArchivedPlaceholder(
slot=data["placeholder"],
plugins=data["plugins"],
)
if "plugin_type" in data:
return ArchivedPlugin(**data)
return data

with abs_filepath.open() as fixture:
try:
placeholders: list = json.loads(fixture.read(), object_hook=parse_data)

# create page and get pagecontent
page = create_page(**self._page_create_details())
page_content = page.get_admin_content(language=LANGUAGE)

# import plugin to page
import_plugins_to_page(
placeholders=placeholders,
pagecontent=page_content,
language=LANGUAGE,
)
except Exception as e:
e.args = (f"Problem installing fixture {fixture}: {e}",)
raise

def handle(self, *args, **options):
filepath = options["filepath"]
force = options["force"]

if not filepath:
for file in DEMOCONTENT.iterdir():
self.stdout.write("---> %s" % file.name)
return

file = os.path.basename(filepath)
self.title = file.split(".")[0]

# skip title check if force option is provided
if not force:
all_page_content = PageContent.admin_manager.all()
for page_content in all_page_content:
if page_content.title.lower() == self.title.lower():
self.stdout.write(
"Page with title('%s') already exists" % self.title
)
return

abs_filepath = DEMOCONTENT / file
with transaction.atomic():
self.loaddata(abs_filepath)

self.stdout.write("Page with title('%s') created" % self.title)
2 changes: 2 additions & 0 deletions backend/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
'filer',
'easy_thumbnails',

'djangocms_transfer',

# the default publishing implementation - optional, but used in most projects
'djangocms_versioning',

Expand Down
1 change: 1 addition & 0 deletions democontent/gridrowpercolumn.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"placeholder": "Content", "plugins": [{"pk": 62, "creation_date": "2025-07-15T13:31:14.722Z", "position": 1, "plugin_type": "GridRowPlugin", "parent_id": null, "data": {"ui_item": "GridRow", "tag_type": "div", "config": {"vertical_alignment": "", "horizontal_alignment": "", "gutters": "", "attributes": {}, "row_cols_xs": 3, "row_cols_sm": 7, "row_cols_md": null, "row_cols_lg": null, "row_cols_xl": null, "row_cols_xxl": null, "plugin_title": {"show": false, "title": ""}, "responsive_visibility": null, "margin_x": "", "margin_y": "", "margin_devices": null, "padding_x": "", "padding_y": "", "padding_devices": null}}}, {"pk": 65, "creation_date": "2025-07-17T21:19:38.749Z", "position": 2, "plugin_type": "GridContainerPlugin", "parent_id": null, "data": {"ui_item": "GridContainer", "tag_type": "div", "config": {"size_x": "", "size_y": "", "padding_x": "", "padding_y": "", "padding_devices": null, "margin_x": "", "margin_y": "", "margin_devices": ["xs"], "responsive_visibility": [], "background_context": "", "background_opacity": "", "background_shadow": "", "plugin_title": {"show": false, "title": ""}, "container_type": "container", "attributes": {}}}}]}]
1 change: 1 addition & 0 deletions democontent/help.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"placeholder": "Content", "plugins": [{"pk": 70, "creation_date": "2025-03-13T17:13:26.875Z", "position": 1, "plugin_type": "GridContainerPlugin", "parent_id": null, "data": {"ui_item": "GridContainer", "tag_type": "div", "config": {"container_type": "container", "attributes": {}, "plugin_title": {"show": false, "title": ""}, "background_context": "", "background_opacity": "100", "background_shadow": "", "responsive_visibility": null, "margin_x": "", "margin_y": "", "margin_devices": null, "padding_x": "", "padding_y": "", "padding_devices": null, "size_x": "vw-100", "size_y": "50"}}}, {"pk": 71, "creation_date": "2025-03-13T17:15:04.988Z", "position": 2, "plugin_type": "GridRowPlugin", "parent_id": 70, "data": {"ui_item": "GridRow", "tag_type": "div", "config": {"vertical_alignment": "", "horizontal_alignment": "", "gutters": "", "attributes": {}, "row_cols_xs": null, "row_cols_sm": null, "row_cols_md": null, "row_cols_lg": null, "row_cols_xl": null, "row_cols_xxl": null, "plugin_title": {"show": false, "title": ""}, "responsive_visibility": null, "margin_x": "mx-1", "margin_y": "my-1", "margin_devices": null, "padding_x": "px-1", "padding_y": "py-1", "padding_devices": null}}}, {"pk": 72, "creation_date": "2025-03-13T17:16:12.137Z", "position": 3, "plugin_type": "GridColumnPlugin", "parent_id": 71, "data": {"ui_item": "GridColumn", "tag_type": "div", "config": {"column_alignment": null, "xs_col": null, "xs_order": null, "xs_offset": null, "xs_ml": null, "xs_mr": null, "sm_col": null, "sm_order": null, "sm_offset": null, "sm_ml": null, "sm_mr": null, "md_col": null, "md_order": null, "md_offset": null, "md_ml": null, "md_mr": null, "lg_col": null, "lg_order": null, "lg_offset": null, "lg_ml": null, "lg_mr": null, "xl_col": null, "xl_order": null, "xl_offset": null, "xl_ml": null, "xl_mr": null, "xxl_col": null, "xxl_order": null, "xxl_offset": null, "xxl_ml": null, "xxl_mr": null}}}, {"pk": 73, "creation_date": "2025-03-13T17:17:31.056Z", "position": 4, "plugin_type": "CardPlugin", "parent_id": 72, "data": {"ui_item": "Card", "tag_type": "div", "config": {"card_alignment": "center", "card_outline": "secondary", "card_text_color": "primary", "card_full_height": false, "attributes": {}, "background_context": "light", "background_opacity": "50", "background_shadow": "", "responsive_visibility": null, "margin_x": "", "margin_y": "", "margin_devices": null}}}, {"pk": 74, "creation_date": "2025-03-13T17:17:31.065Z", "position": 5, "plugin_type": "CardInnerPlugin", "parent_id": 73, "data": {"ui_item": "CardInner", "tag_type": "div", "config": {"inner_type": "card-body"}}}, {"pk": 75, "creation_date": "2025-03-13T17:20:28.371Z", "position": 6, "plugin_type": "TextPlugin", "parent_id": 74, "data": {"body": "<p><strong>Expensive</strong></p>"}}, {"pk": 76, "creation_date": "2025-03-13T17:16:12.141Z", "position": 7, "plugin_type": "GridColumnPlugin", "parent_id": 71, "data": {"ui_item": "GridColumn", "tag_type": "div", "config": {"column_alignment": null, "xs_col": null, "xs_order": null, "xs_offset": null, "xs_ml": null, "xs_mr": null, "sm_col": null, "sm_order": null, "sm_offset": null, "sm_ml": null, "sm_mr": null, "md_col": null, "md_order": null, "md_offset": null, "md_ml": null, "md_mr": null, "lg_col": null, "lg_order": null, "lg_offset": null, "lg_ml": null, "lg_mr": null, "xl_col": null, "xl_order": null, "xl_offset": null, "xl_ml": null, "xl_mr": null, "xxl_col": null, "xxl_order": null, "xxl_offset": null, "xxl_ml": null, "xxl_mr": null}}}, {"pk": 77, "creation_date": "2025-03-13T17:17:31.056Z", "position": 8, "plugin_type": "CardPlugin", "parent_id": 76, "data": {"ui_item": "Card", "tag_type": "div", "config": {"card_alignment": "", "card_outline": "secondary", "card_text_color": "primary", "card_full_height": false, "attributes": {}, "background_context": "light", "background_opacity": "50", "background_shadow": "", "responsive_visibility": null, "margin_x": "", "margin_y": "", "margin_devices": null}}}, {"pk": 78, "creation_date": "2025-03-13T17:17:31.065Z", "position": 9, "plugin_type": "CardInnerPlugin", "parent_id": 77, "data": {"ui_item": "CardInner", "tag_type": "div", "config": {"inner_type": "card-body"}}}, {"pk": 79, "creation_date": "2025-03-13T17:20:28.371Z", "position": 10, "plugin_type": "TextPlugin", "parent_id": 78, "data": {"body": "<p><strong>Medium</strong></p>\n\n<p><cms-plugin alt=\"Link - Home page \" title=\"Link - Home page\" id=\"80\"></cms-plugin></p>\n\n<p>\u00a0</p>"}}, {"pk": 80, "creation_date": "2025-03-14T22:18:23.726Z", "position": 11, "plugin_type": "LinkPlugin", "parent_id": 79, "data": {"template": "default", "name": "Home page", "link": {"internal_link": "cms.page:1", "anchor": "#adebayo"}, "target": "_blank", "attributes": {}}}, {"pk": 81, "creation_date": "2025-03-13T17:15:43.388Z", "position": 12, "plugin_type": "GridColumnPlugin", "parent_id": 71, "data": {"ui_item": "GridColumn", "tag_type": "div", "config": {"column_alignment": null, "xs_col": null, "xs_order": null, "xs_offset": null, "xs_ml": null, "xs_mr": null, "sm_col": null, "sm_order": null, "sm_offset": null, "sm_ml": null, "sm_mr": null, "md_col": null, "md_order": null, "md_offset": null, "md_ml": null, "md_mr": null, "lg_col": null, "lg_order": null, "lg_offset": null, "lg_ml": null, "lg_mr": null, "xl_col": null, "xl_order": null, "xl_offset": null, "xl_ml": null, "xl_mr": null, "xxl_col": null, "xxl_order": null, "xxl_offset": null, "xxl_ml": null, "xxl_mr": null}}}, {"pk": 82, "creation_date": "2025-03-13T17:17:31.056Z", "position": 13, "plugin_type": "CardPlugin", "parent_id": 81, "data": {"ui_item": "Card", "tag_type": "div", "config": {"card_alignment": "", "card_outline": "secondary", "card_text_color": "primary", "card_full_height": false, "attributes": {}, "background_context": "light", "background_opacity": "50", "background_shadow": "", "responsive_visibility": null, "margin_x": "", "margin_y": "", "margin_devices": null}}}, {"pk": 83, "creation_date": "2025-03-13T17:17:31.065Z", "position": 14, "plugin_type": "CardInnerPlugin", "parent_id": 82, "data": {"ui_item": "CardInner", "tag_type": "div", "config": {"inner_type": "card-body"}}}, {"pk": 84, "creation_date": "2025-03-13T17:20:28.371Z", "position": 15, "plugin_type": "TextPlugin", "parent_id": 83, "data": {"body": "<p><strong>Free</strong></p>"}}]}]
2 changes: 2 additions & 0 deletions requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ djangocms-admin-style>=3.2.2
# the next-gen text editor
djangocms-text

# required to populate demo content
djangocms-transfer>=2.0.0

# optional django CMS frontend
djangocms-frontend
Expand Down
3 changes: 3 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ django-cms==5.0.1
# djangocms-attributes-field
# djangocms-frontend
# djangocms-link
# djangocms-transfer
# djangocms-versioning
django-entangled==0.6.2
# via djangocms-frontend
Expand Down Expand Up @@ -91,6 +92,8 @@ djangocms-link==5.0.1
# via djangocms-frontend
djangocms-text==0.9.1
# via -r requirements.in
djangocms-transfer==2.0.0
# via -r requirements.in
djangocms-versioning==2.3.2
# via -r requirements.in
easy-thumbnails[svg]==2.10
Expand Down