Getting started
Elemental CMS is published under MPL-2.0 license and can be easily installed by issuing the following command:
pip install elemental-cms
Before we start #
We need a working MongoDB server to be able to explore the tool and all the available samples. We can use a standalone installation, or we can always create an account on MongoDB Atlas. The free tier will be more than enough to follow this guide.
Since the tool is written using Python before we start to build our application we will create a Python “project”
mkdir getting-started && \
cd getting-started
It is always recommended working with virtual environments so we can isolate problems and avoid installing undesired packages globally.
python -m venv .venv && \
source .venv/bin/activate
Now that we have our virtual environment up and activated we are ready to install elemental-cms CLI exclusively on our new isolated “project”. This will also install all the dependencies.
Command line interface (CLI) #
Now that the tool is installed we can use it by typing:
elemental-cms
This will display the tool help that will look something like this:
Usage: elemental-cms [OPTIONS] COMMAND [ARGS]...
Elemental CMS management CLI
Options:
--help Show this message and exit.
Commands:
global-deps
init
media
pages
snippets
static
version
Initializing elemental CMS workspace #
The CLI includes an "init" command which will create a basic structure on the working directory. But before we can issue the init command we need to create a settings file under the name local.cli.json on our settings folder.
mkdir settings && \
nano local.cli.json
Minimum local.cli.json file content to run the init command:
{
"cmsCoreContext": {
"DEBUG": true,
"ENV": "development",
"SECRET": "WyWITCbotmzy8pVDPY/6eg==",
"SITE_NAME": "Elemental CMS Getting Started",
"COMPANY": "Kudos Company",
"CANONICAL_URL": "https://www.elemental-kudos.com",
"LANGUAGES": [
"en",
"es"
],
"DEFAULT_LANGUAGE": "en",
"LANGUAGE_MODE": "multi",
"STATIC_FOLDER": "static",
"MEDIA_FOLDER": "media",
"STATIC_URL": "https://storage.googleapis.com/getting-started-static-bucket",
"MEDIA_URL": "https://storage.googleapis.com/getting-started-media-bucket",
"STATIC_BUCKET": "getting-started-static-bucket",
"MEDIA_BUCKET": "getting-started-media-bucket",
"GOOGLE_SERVICE_ACCOUNT_INFO": {
"type": "service_account"
},
"GLOBAL_DEPS_FOLDER": "workspace/global_deps",
"PAGES_FOLDER": "workspace/pages",
"SNIPPETS_FOLDER": "workspace/snippets"
},
"cmsDbContext": {
"id": "elemental-cms-db-friendly-name",
"connectionString": "mongodb://my-username:my-passwd@mongodb-hostname:27017/admin",
"databaseName": "elemental_getting_started"
}
}
The folder properties and database properties are vital to the init command to run, if any of this properties are missing or misconfigured the command will not work.
elemental-cms init -c settings/local.cli.json
If everything goes ok we must have the following folder structure:
└── getting-started
├── .elemental
├── media
├── settings
│ └── local.cli.json
├── static
├── templates
│ └── base.html
├── translations
└── workspace
├── global_deps
├── pages
└── snippets
Additionally our mongo server will have our CMS database
> show dbs
admin 0.000GB
config 0.000GB
elemental_getting_started 0.000GB
local 0.000GB
Creating our first page #
To create a new page we start by issuing the pages CLI command like this:
elemental-cms pages create -p home en
This will create the page content file and the page spec file under the workspace/pages/en directory.
Spec file
The spec file has the page metadata which can be then be pushed to the database in order to make the page available in the CMS.
The structure of the spec file can be seen below:
{
"_id": {
"$oid": "625b675f0c82e4f4d2107e8d"
},
"name": "home",
"language": "en",
"title": "home page",
"description": "",
"isHome": false,
"cssDeps": [],
"jsDeps": [],
"createdAt": {
"$date": 1650157407821
},
"lastModifiedAt": {
"$date": 1650157407821
}
}
As this is our first and only page we should set the isHome property to true.
Content file
The content file will have the HTML for the page. After the create command execution it will have a simple html like the following:
<div></div>
Pushing our new page #
In order to push a page we must use the pages push command which will send the metadata and content to the database and create a "draft" version of the page.
elemental-cms pages push -p home en
Publishing our page #
Until now the new page is stored on the "drafts" repository, in order to be accessible through the web application we must publish the page by running the following command:
elemental-cms pages publish -p home en
Flask application #
Until now, we have created a multi-language page and successfully published it, but we are missing our application entry point. Since this framework is based on Flask we must create a simple entry point as we will do it for any Flask application.
So we will create the main.py script file, and then we will add the minimum required script to launch a simple web application.
import json
import os
from elementalcms import Elemental, ElementalContext
from elementalcms.core import FlaskContext, MongoDbContext
from flask import Flask
www = Flask(__name__, template_folder='templates', static_folder='static')
CONFIG_FILEPATH = os.environ.get('CONFIG_FILEPATH', 'settings/local.www.json')
with open(CONFIG_FILEPATH) as config_file:
settings = json.load(config_file)
cms_core_context = FlaskContext(settings['cmsCoreContext'])
cms_db_context = MongoDbContext(settings['cmsDbContext'])
elemental_context = ElementalContext(cms_core_context, cms_db_context)
Elemental(www, elemental_context)
if __name__ == '__main__':
www.run(host='0.0.0.0', port=8000)
Running the application
In order to run the application we use python as with we will do it with any other application:
python main.py
cli & www settings
If we run the application right now we will get an error because the file settings/local.www.json does not exist. We can create this file by copying the local.cli.json version.
cp settings/local.cli.json settings/local.www.json
Then we edit the local.www.json file so its content looks like this:
{
"cmsCoreContext": {
"DEBUG": true,
"ENV": "development",
"SECRET": "WyWITCbotmzy8pVDPY/6eg==",
"SITE_NAME": "Elemental CMS Getting Started",
"COMPANY": "Kudos Company",
"CANONICAL_URL": "https://www.elemental-kudos.com",
"LANGUAGES": [
"en",
"es"
],
"DEFAULT_LANGUAGE": "en",
"LANGUAGE_MODE": "multi",
"STATIC_FOLDER": "static",
"MEDIA_FOLDER": "media",
"STATIC_URL": "/static",
"MEDIA_URL": "/media",
"GLOBAL_DEPS_FOLDER": "workspace/global_deps",
"PAGES_FOLDER": "workspace/pages",
"SNIPPETS_FOLDER": "workspace/snippets",
"DESIGN_MODE_ENABLED": true
},
"cmsDbContext": {
"id": "elemental-cms-db-friendly-name",
"connectionString": "mongodb://my-username:my-passwd@mongodb-hostname:27017/admin",
"databaseName": "elemental_getting_started"
}
}
As we can see the main differences are at the following cmsCoreContext properties:
Property |
local.www.json |
local.cli.json |
---|---|---|
STATIC_URL |
/static |
https://storage.googleapis.com/getting-started-static-bucket |
MEDIA_URL |
/media |
https://storage.googleapis.com/getting-started-media-bucket |
STATIC_BUCKET |
NOT REQUIRED NOR USED |
getting-started-static-bucket |
MEDIA_BUCKET |
NOT REQUIRED NOR USED |
getting-started-media-bucket |
GOOGLE_SERVICE_ACCOUNT_INFO |
NOT REQUIRED NOR USED |
Google Cloud Service account with granted access over GCS |
local.cli.json file is used by the CLI in order to be able to publish media and static files to GCS.
local.www.json file is used at our local development environment, it uses /media and /static urls to serve local files while we are in development mode. In development mode we will not use GCS, and because of that the debug file can miss related settings like, STATIC_BUCKET, MEDIA_BUCKET and GOOGLE_SERVICE_ACCOUNT_INFO. We can also activate the design mode by adding DESIGN_MODE_ENABLED property and setting it to true.