diff --git a/ecep_cms/.dockerignore b/ecep_cms/.dockerignore
new file mode 100644
index 00000000..a64885d2
--- /dev/null
+++ b/ecep_cms/.dockerignore
@@ -0,0 +1,4 @@
+.git
+.cache
+**/secrets.py
+**/settings_local.py
diff --git a/ecep_cms/Dockerfile b/ecep_cms/Dockerfile
new file mode 100644
index 00000000..c68513f4
--- /dev/null
+++ b/ecep_cms/Dockerfile
@@ -0,0 +1,7 @@
+# TACC/Core-CMS#v3.12.0-beta.3
+FROM taccwma/core-cms:aba079b
+
+WORKDIR /code
+
+COPY /src/taccsite_custom /code/taccsite_custom
+COPY /src/taccsite_cms /code/taccsite_cms
diff --git a/ecep_cms/Makefile b/ecep_cms/Makefile
new file mode 100644
index 00000000..04d475d0
--- /dev/null
+++ b/ecep_cms/Makefile
@@ -0,0 +1,39 @@
+DOCKERHUB_REPO := $(shell cat ./docker_repo.var)
+DOCKER_TAG ?= $(shell git rev-parse --short HEAD)
+DOCKER_IMAGE := $(DOCKERHUB_REPO):$(DOCKER_TAG)
+DOCKER_IMAGE_LATEST := $(DOCKERHUB_REPO):latest
+
+####
+# `DOCKER_IMAGE_BRANCH` tag is the git tag for the commit if it exists, else the branch on which the commit exists
+DOCKER_IMAGE_BRANCH := $(DOCKERHUB_REPO):$(shell git describe --exact-match --tags 2> /dev/null || git symbolic-ref --short HEAD)
+
+#.PHONY: build
+build:
+ docker-compose -f docker-compose.dev.yml build
+
+.PHONY: build-full
+build-full:
+ docker build -t $(DOCKER_IMAGE) --target production -f Dockerfile .
+ docker tag $(DOCKER_IMAGE) $(DOCKER_IMAGE_BRANCH) # Note: Currently broken for branches with slashes
+
+.PHONY: publish
+publish:
+ docker push $(DOCKER_IMAGE)
+ docker push $(DOCKER_IMAGE_BRANCH)
+
+.PHONY: publish-latest
+publish-latest:
+ docker tag $(DOCKER_IMAGE) $(DOCKER_IMAGE_LATEST)
+ docker push $(DOCKER_IMAGE_LATEST)
+
+.PHONY: start
+start:
+ docker-compose -f docker-compose.dev.yml up
+
+.PHONY: stop
+stop:
+ docker-compose -f docker-compose.dev.yml down
+
+.PHONY: stop-full
+stop-v:
+ docker-compose -f docker-compose.dev.yml down -v
diff --git a/ecep_cms/README.md b/ecep_cms/README.md
new file mode 100644
index 00000000..59a51232
--- /dev/null
+++ b/ecep_cms/README.md
@@ -0,0 +1,7 @@
+# Example
+
+An extension of the [Core CMS](https://github.com/TACC/Core-CMS) project
+
+## Basics
+
+See [Core-CMS-Custom](../README.md).
diff --git a/ecep_cms/docker-compose.dev.yml b/ecep_cms/docker-compose.dev.yml
new file mode 100644
index 00000000..8c16426e
--- /dev/null
+++ b/ecep_cms/docker-compose.dev.yml
@@ -0,0 +1,54 @@
+version: "3"
+services:
+ cms:
+ build: .
+ ports:
+ - 127.0.0.1:8000:8000
+ command: ["python3", "manage.py", "runserver", "0.0.0.0:8000"]
+ container_name: core_cms
+ hostname: core_cms
+ volumes:
+ - ./src/taccsite_custom:/code/taccsite_custom
+ - ./src/taccsite_cms/custom_app_settings.py:/code/taccsite_cms/custom_app_settings.py
+ - ./src/taccsite_cms/urls_custom.py:/code/taccsite_cms/urls_custom.py
+ - ./src/taccsite_cms/settings_custom.py:/code/taccsite_cms/settings_custom.py
+ - ./src/taccsite_cms/settings_local.py:/code/taccsite_cms/settings_local.py
+ - ./src/taccsite_cms/secrets.py:/code/taccsite_cms/secrets.py
+ networks:
+ - core_cms_net
+
+ postgres:
+ image: postgres:11.5
+ environment:
+ - POSTGRES_PASSWORD=taccforever
+ - POSTGRES_USER=postgresadmin
+ - POSTGRES_DB=taccsite
+ - PGDATA=/var/lib/postgresql/data/taccsite
+ volumes:
+ - core_cms_postgres_data:/var/lib/postgresql/data
+ hostname: core_cms_postgres
+ container_name: core_cms_postgres
+ networks:
+ - core_cms_net
+
+ elasticsearch:
+ image: docker.elastic.co/elasticsearch/elasticsearch:7.17.0
+ ulimits:
+ memlock: -1
+ environment:
+ - ES_HEAP_SIZE:1g
+ - discovery.type=single-node
+ volumes:
+ - core_cms_es_data:/usr/share/elasticsearch/data
+ container_name: core_cms_elasticsearch
+ ports:
+ - 127.0.0.1:9201:9200
+ networks:
+ - core_cms_net
+
+volumes:
+ core_cms_postgres_data:
+ core_cms_es_data:
+
+networks:
+ core_cms_net:
diff --git a/ecep_cms/src/taccsite_cms/custom_app_settings.py b/ecep_cms/src/taccsite_cms/custom_app_settings.py
new file mode 100644
index 00000000..084ea2dc
--- /dev/null
+++ b/ecep_cms/src/taccsite_cms/custom_app_settings.py
@@ -0,0 +1,25 @@
+CUSTOM_APPS = [
+
+ # ...
+
+ ########################
+ # NEWS / BLOG
+ ########################
+
+ # 'filer', # already in Core
+ # 'easy_thumbnails', # already in Core
+ 'parler',
+ 'taggit',
+ 'taggit_autosuggest',
+ # 'meta', # already in Core
+ 'sortedm2m',
+ 'djangocms_blog',
+
+ # REQ: 'taggit_autosuggest' requires the following is added to `urls_custom.py`
+ # custom_urls = [
+ # # Support `taggit_autosuggest` (from `djangocms-blog`)
+ # url(r'^taggit_autosuggest/', include('taggit_autosuggest.urls')),
+ # ]
+]
+CUSTOM_MIDDLEWARE = []
+STATICFILES_DIRS = ()
diff --git a/ecep_cms/src/taccsite_cms/settings_custom.py b/ecep_cms/src/taccsite_cms/settings_custom.py
new file mode 100644
index 00000000..79c12218
--- /dev/null
+++ b/ecep_cms/src/taccsite_cms/settings_custom.py
@@ -0,0 +1,127 @@
+# CUSTOM SETTINGS VALUES.
+# TACC WMA CMS SITE:
+# *.ECEP.TACC.UTEXAS.EDU
+
+# FAQ: Some _VARIABLES are duplicated from settings.py (but prefixed with "_")
+# because current infrastructure lacks ability to reference default values
+
+########################
+# DJANGO CMS SETTINGS
+########################
+
+CMS_TEMPLATES = (
+ ('standard.html', 'Standard'),
+ ('fullwidth.html', 'Full Width'),
+
+ ('guide.html', 'Guide'),
+ ('guides/getting_started.html', 'Guide: Getting Started'),
+ ('guides/data_transfer.html', 'Guide: Data Transfer'),
+ ('guides/data_transfer.globus.html', 'Guide: Globus Data Transfer'),
+ ('guides/portal_technology.html', 'Guide: Portal Technology Stack')
+)
+
+########################
+# TACC: BRANDING
+########################
+
+_NSF_BRANDING = [
+ "nsf",
+ "site_cms/img/nsf-white.png",
+ "branding-nsf",
+ "https://www.nsf.gov/",
+ "_blank",
+ "NSF Logo",
+ "anonymous",
+ "True"
+]
+
+_TACC_BRANDING = [
+ "tacc",
+ "site_cms/img/tacc-white.png",
+ "branding-tacc",
+ "https://www.tacc.utexas.edu/",
+ "_blank",
+ "TACC Logo",
+ "anonymous",
+ "True"
+]
+
+_UTEXAS_BRANDING = [
+ "utexas",
+ "site_cms/img/utaustin-white.png",
+ "branding-utaustin",
+ "https://www.utexas.edu/",
+ "_blank",
+ "University of Texas at Austin Logo",
+ "anonymous",
+ "True"
+]
+
+BRANDING = [_NSF_BRANDING, _TACC_BRANDING, _UTEXAS_BRANDING]
+
+########################
+# TACC: LOGOS
+########################
+
+LOGO = [
+ "ecep",
+ "ecep_cms/img/ecep-white-no_words.svg",
+ "",
+ "/",
+ "_self",
+ "ECEP Logo",
+ "anonymous",
+ "True"
+]
+
+FAVICON = {
+ "img_file_src": "ecep_cms/img/favicon.ico"
+}
+
+########################
+# TACC: PORTAL
+########################
+
+INCLUDES_CORE_PORTAL = True
+INCLUDES_PORTAL_NAV = True
+INCLUDES_SEARCH_BAR = True
+
+########################
+# TACC: NEWS/BLOG
+########################
+
+# TACC settings
+TACC_BLOG_SHOW_CATEGORIES = False
+TACC_BLOG_SHOW_TAGS = False
+
+########################
+# NEWS / BLOG
+########################
+
+# REQ: Assumes various "NEWS / BLOG" are installed via `custom_app_settings.py`
+
+# Paths for alternate templates that user can choose for blog-specific plugin
+# - Devs can customize core templates at `templates/djangocms_blog/`.
+# - Users can choose alt. templates from `templates/djangocms_blog/plugins/*`.
+# - Devs can customize alt. templates at `templates/djangocms_blog/plugins/*`.
+BLOG_PLUGIN_TEMPLATE_FOLDERS = (
+ ('plugins', 'Default'),
+ # ('plugins/alternate', 'Alternate'),
+)
+
+# Change default values for the auto-setup of one `BlogConfig`
+# SEE: https://github.com/nephila/djangocms-blog/issues/629
+BLOG_AUTO_SETUP = False # Set to False after setup (to minimize server overhead)
+BLOG_AUTO_HOME_TITLE ='Home'
+BLOG_AUTO_BLOG_TITLE = 'News'
+BLOG_AUTO_APP_TITLE = 'News'
+BLOG_AUTO_NAMESPACE = 'News'
+
+# Miscellaneous settings
+BLOG_ENABLE_COMMENTS = False
+
+########################
+# TACC: CORE STYLES
+########################
+
+TACC_CORE_STYLES_VERSION = 0
diff --git a/ecep_cms/src/taccsite_cms/templates/assets_custom.html b/ecep_cms/src/taccsite_cms/templates/assets_custom.html
new file mode 100644
index 00000000..32eebb1a
--- /dev/null
+++ b/ecep_cms/src/taccsite_cms/templates/assets_custom.html
@@ -0,0 +1,22 @@
+{# This template overwrites the original from TACC/Core-CMS #}
+{# NOTE: This should extend taccsite_cms via taccsite_custom, not overwrite #}
+{# FAQ: To extend, via app template inheritance, see TACC/Core-CMS#492 #}
+
+
+
+{# COPIED FROM CORE #}
+{# https://github.com/TACC/Core-CMS/blob/c8844e1/taccsite_cms/templates/assets_custom.html #}
+
+{% load static %}
+
+
+{% with settings.FAVICON as favicon %}
+
+{% endwith %}
+
+
+
+{# NEW CODE #}
+
+
+
diff --git a/ecep_cms/src/taccsite_cms/urls_custom.py b/ecep_cms/src/taccsite_cms/urls_custom.py
new file mode 100644
index 00000000..795aff92
--- /dev/null
+++ b/ecep_cms/src/taccsite_cms/urls_custom.py
@@ -0,0 +1,6 @@
+from django.conf.urls import include, url
+
+custom_urls = [
+ # Support `taggit_autosuggest` (from `djangocms-blog`)
+ url(r'^taggit_autosuggest/', include('taggit_autosuggest.urls')),
+]
diff --git a/ecep_cms/src/taccsite_custom/ecep_cms/__init__.py b/ecep_cms/src/taccsite_custom/ecep_cms/__init__.py
new file mode 100755
index 00000000..e69de29b
diff --git a/ecep_cms/src/taccsite_custom/ecep_cms/static/ecep_cms/css/site.css b/ecep_cms/src/taccsite_custom/ecep_cms/static/ecep_cms/css/site.css
new file mode 100644
index 00000000..0979eb8d
--- /dev/null
+++ b/ecep_cms/src/taccsite_custom/ecep_cms/static/ecep_cms/css/site.css
@@ -0,0 +1,67 @@
+/* Organize via ITCSS */
+/* SEE: https://confluence.tacc.utexas.edu/x/IAA9Cw */
+
+
+
+
+
+/* SETTINGS */
+
+/* https://github.com/TACC/Core-Styles/blob/v0.13.0/src/lib/_imports/settings/color.css */
+:root {
+ /* Accent */
+ --global-color-accent--xxx-light: #DAADFF;
+ --global-color-accent--x-light: #A12EFF;
+ --global-color-accent--light: #6E00C8;
+ --global-color-accent--normal: #4F008F;
+ --global-color-accent--dark: #2F0054;
+ --global-color-accent--x-dark: #1E0037;
+
+ --global-color-accent--alt: #DDC4F2;
+ --global-color-accent--weak: #5B00A440;
+
+ /* Link */
+ --global-color-link-on-light--normal: var(--global-color-accent--normal);
+ --global-color-link-on-dark--normal: var(--global-color-accent--xxx-light);
+}
+
+/* https://github.com/TACC/Core-Styles/blob/v0.13.0/src/lib/_imports/theme.default.css */
+:root {
+ --header-bkgd-color: #4F008F;
+ --header-minor-border-color: #DAADFF;
+ --header-search-brdr-color: #A12EFF;
+ --header-search-bkgd-color: #5f00ad;
+}
+
+
+
+
+
+/* COMPONENTS */
+
+/* https://github.com/TACC/Core-CMS/blob/main/taccsite_cms/static/site_cms/css/src/_imports/components/django.cms.blog.app.item.css */
+.blog-list article .byline,
+article.post-detail .byline {
+ display: none;
+}
+
+
+
+
+
+/* TRUMPS */
+
+/* SEE: TACC/Core-Styles/blob/main/source/_imports/trumps/s-header.css */
+.s-header .navbar-brand {
+ min-width: 76px;
+}
+
+
+
+
+
+/* UNORGANIZED */
+
+/* SEE: TACC/Core-Styles/blob/main/source/_imports/branding_logos.css */
+/* NOTE: This is ONLY allowed because branding was added to Footer via CMS */
+#header-branding { display: none; }
diff --git a/ecep_cms/src/taccsite_custom/ecep_cms/static/ecep_cms/img/ecep-purple-has_words.svg b/ecep_cms/src/taccsite_custom/ecep_cms/static/ecep_cms/img/ecep-purple-has_words.svg
new file mode 100644
index 00000000..76563d57
--- /dev/null
+++ b/ecep_cms/src/taccsite_custom/ecep_cms/static/ecep_cms/img/ecep-purple-has_words.svg
@@ -0,0 +1 @@
+
diff --git a/ecep_cms/src/taccsite_custom/ecep_cms/static/ecep_cms/img/ecep-purple-no_words-padded.jpeg b/ecep_cms/src/taccsite_custom/ecep_cms/static/ecep_cms/img/ecep-purple-no_words-padded.jpeg
new file mode 100644
index 00000000..d7dbc917
Binary files /dev/null and b/ecep_cms/src/taccsite_custom/ecep_cms/static/ecep_cms/img/ecep-purple-no_words-padded.jpeg differ
diff --git a/ecep_cms/src/taccsite_custom/ecep_cms/static/ecep_cms/img/ecep-purple-no_words.svg b/ecep_cms/src/taccsite_custom/ecep_cms/static/ecep_cms/img/ecep-purple-no_words.svg
new file mode 100644
index 00000000..73ca5f5f
--- /dev/null
+++ b/ecep_cms/src/taccsite_custom/ecep_cms/static/ecep_cms/img/ecep-purple-no_words.svg
@@ -0,0 +1 @@
+
diff --git a/ecep_cms/src/taccsite_custom/ecep_cms/static/ecep_cms/img/ecep-white-has_words.svg b/ecep_cms/src/taccsite_custom/ecep_cms/static/ecep_cms/img/ecep-white-has_words.svg
new file mode 100644
index 00000000..9c672b44
--- /dev/null
+++ b/ecep_cms/src/taccsite_custom/ecep_cms/static/ecep_cms/img/ecep-white-has_words.svg
@@ -0,0 +1 @@
+
diff --git a/ecep_cms/src/taccsite_custom/ecep_cms/static/ecep_cms/img/ecep-white-no_words.svg b/ecep_cms/src/taccsite_custom/ecep_cms/static/ecep_cms/img/ecep-white-no_words.svg
new file mode 100644
index 00000000..6b17140b
--- /dev/null
+++ b/ecep_cms/src/taccsite_custom/ecep_cms/static/ecep_cms/img/ecep-white-no_words.svg
@@ -0,0 +1 @@
+
diff --git a/ecep_cms/src/taccsite_custom/ecep_cms/static/ecep_cms/img/favicon.ico b/ecep_cms/src/taccsite_custom/ecep_cms/static/ecep_cms/img/favicon.ico
new file mode 100644
index 00000000..f0bc52b6
Binary files /dev/null and b/ecep_cms/src/taccsite_custom/ecep_cms/static/ecep_cms/img/favicon.ico differ
diff --git a/ecep_cms/src/taccsite_custom/ecep_cms/templates/snippets/page-members-css-old.html b/ecep_cms/src/taccsite_custom/ecep_cms/templates/snippets/page-members-css-old.html
new file mode 100644
index 00000000..913c6870
--- /dev/null
+++ b/ecep_cms/src/taccsite_custom/ecep_cms/templates/snippets/page-members-css-old.html
@@ -0,0 +1,70 @@
+
+
+
+
+
+{# The {{ html }} allows DjangoCMS Snippet to pass in more markup #}
+{{ html }}
diff --git a/ecep_cms/src/taccsite_custom/ecep_cms/templates/snippets/page-members-css.html b/ecep_cms/src/taccsite_custom/ecep_cms/templates/snippets/page-members-css.html
new file mode 100644
index 00000000..1ee3aec4
--- /dev/null
+++ b/ecep_cms/src/taccsite_custom/ecep_cms/templates/snippets/page-members-css.html
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+{# The {{ html }} allows DjangoCMS Snippet to pass in more markup #}
+{{ html }}
diff --git a/ecep_cms/src/taccsite_custom/ecep_cms/templates/snippets/page-members-js-old.html b/ecep_cms/src/taccsite_custom/ecep_cms/templates/snippets/page-members-js-old.html
new file mode 100644
index 00000000..0fac9ee6
--- /dev/null
+++ b/ecep_cms/src/taccsite_custom/ecep_cms/templates/snippets/page-members-js-old.html
@@ -0,0 +1,31 @@
+
+
+
+
+{# The {{ html }} allows DjangoCMS Snippet to pass in any JavaScript #}
+{{ html }}
diff --git a/ecep_cms/src/taccsite_custom/ecep_cms/templates/snippets/page-members-js.html b/ecep_cms/src/taccsite_custom/ecep_cms/templates/snippets/page-members-js.html
new file mode 100644
index 00000000..ad7d465f
--- /dev/null
+++ b/ecep_cms/src/taccsite_custom/ecep_cms/templates/snippets/page-members-js.html
@@ -0,0 +1,17 @@
+
+
+
+
+{# The {{ html }} allows DjangoCMS Snippet to pass in any JavaScript #}
+{{ html }}
diff --git a/ecep_cms/src/taccsite_custom/ecep_cms/templates/snippets/site-css.html b/ecep_cms/src/taccsite_custom/ecep_cms/templates/snippets/site-css.html
new file mode 100644
index 00000000..085c5985
--- /dev/null
+++ b/ecep_cms/src/taccsite_custom/ecep_cms/templates/snippets/site-css.html
@@ -0,0 +1,3 @@
+{% load static %}
+
+