diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e682981978a35cee92a2eb747dff37783139f6c2
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,14 @@
+devel:    
+  stage: deploy
+  script:
+    - echo "pipeline started"
+    - cp -r ckanext-theme_hft/* /usr/lib/ckan/default/src/ckanext-theme_hft/
+    - . /usr/lib/ckan/default/bin/activate
+    - cd /usr/lib/ckan/default/src/ckanext-theme_hft
+    - python setup.py develop
+    - deactivate
+    - supervisorctl restart all
+  tags: 
+    - testing
+  only:
+    - testing
diff --git a/README.md b/README.md
index 4639189da5df221a76eeb60af5376444bce56213..4fdcff5122bfdee1dfb580233446fe92dc39afaa 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,33 @@
-# ckan theme
+# Customized Theme of CKAN Data Catalog of HFT Stuttgart
+The extension and files for the customization are structured as follows in the **`ckan`** source code's parent directory:
+- ckanext-theme_hft
+  - ckanext
+    - theme_hft
+      - assets
+        - theme.css
+        - webassets.yml
+      - public
+        - (pictures).jpg/png
+      - templates
+        - home
+          - index.html
+          - snippets
+            - promoted.html
+        - base.html
+        - header.html
+        - footer.html
+      - plugin.py
+  - setup.py
 
-The theme for the Data Catalog of HFT Stuttgart
\ No newline at end of file
+### Steps to implement the customized theme
+1. Run the following command to create a new extension and place its directory in the **`ckan`** source code's parent directory:
+   > ckan generate extension
+   - New extension name: _`ckanext-theme_hft`_
+   - theme name: _`theme_hft`_
+1. Put the files in this repo to the their respective directories.
+1. Go to **`ckanext-theme_hft`** directory and run the following command:
+   > python setup.py develop
+1. Add the new plugin to the ckan.plugins setting in `/etc/ckan/default/ckan.ini` file:
+   > ckan.plugins = stats text_view recline_view theme_hft
+1. Start CKAN
+   > ckan -c /etc/ckan/default/ckan.ini run
diff --git a/ckanext-theme_hft/ckanext/theme_hft/assets/theme.css b/ckanext-theme_hft/ckanext/theme_hft/assets/theme.css
new file mode 100644
index 0000000000000000000000000000000000000000..f85eb37f35ef3ebb817e8c5740fe03fb81ea8adb
--- /dev/null
+++ b/ckanext-theme_hft/ckanext/theme_hft/assets/theme.css
@@ -0,0 +1,54 @@
+/* ========================================================================
+   The main masthead bar that contains the site logo, nav links, and search
+   ======================================================================== */
+
+.masthead {
+  background-color: #ffffff;
+  color: black;
+}
+.masthead .nav > li > a {
+  color: black;
+  text-shadow: none;
+}
+/* The "navigation pills" in the masthead (the links to Datasets,
+   Organizations, etc) when the user's pointer hovers over them. */
+.masthead .navigation .nav-pills li a:hover {
+  background-color: #C14531;
+  color: black;
+}
+/* The "active" navigation pill (for example, when you're on the /dataset page
+   the "Datasets" link is active). */
+.masthead .navigation .nav-pills li.active a {
+  background-color: #C14531;
+}
+/* The "box shadow" effect that appears around the search box when it
+   has the keyboard cursor's focus. */
+.masthead input[type="text"]:focus {
+  -webkit-box-shadow: inset 0px 0px 2px 0px rgba(0, 0, 0, 0.7);
+  box-shadow: inset 0px 0px 2px 0px rgba(0, 0, 0, 0.7);
+}
+
+@media (min-width: 768px) {
+  .hero {
+    background: url("/header.jpg");
+  }
+}
+
+/* ====================================
+   The footer at the bottom of the site
+   ==================================== */
+
+.site-footer,
+body {
+  background-color: #ffffff;
+}
+/* The text in the footer. */
+.site-footer,
+.site-footer label,
+.site-footer small {
+  color: rgba(128, 128, 128, 1);
+}
+/* The link texts in the footer. */
+.site-footer a {
+  color: rgba(128, 128, 128, 1);
+}
diff --git a/ckanext-theme_hft/ckanext/theme_hft/assets/webassets.yml b/ckanext-theme_hft/ckanext/theme_hft/assets/webassets.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c52403a9c948fa02b8d1655ea7c550684c3e820d
--- /dev/null
+++ b/ckanext-theme_hft/ckanext/theme_hft/assets/webassets.yml
@@ -0,0 +1,4 @@
+theme:
+  filters: cssrewrite
+  output: assets/%(version)s_theme.css
+  contents: theme.css
diff --git a/ckanext-theme_hft/ckanext/theme_hft/plugin.py b/ckanext-theme_hft/ckanext/theme_hft/plugin.py
new file mode 100644
index 0000000000000000000000000000000000000000..db33b6fbe2c6b786e6f8b3f7c4b0583080cce0bb
--- /dev/null
+++ b/ckanext-theme_hft/ckanext/theme_hft/plugin.py
@@ -0,0 +1,14 @@
+import ckan.plugins as plugins
+import ckan.plugins.toolkit as toolkit
+
+
+class ThemeHftPlugin(plugins.SingletonPlugin):
+    plugins.implements(plugins.IConfigurer)
+
+    # IConfigurer
+
+    def update_config(self, config):
+        toolkit.add_template_directory(config, 'templates')
+        toolkit.add_public_directory(config, 'public')
+        toolkit.add_resource('assets', 'theme_hft')
+
diff --git a/ckanext-theme_hft/ckanext/theme_hft/public/header.jpg b/ckanext-theme_hft/ckanext/theme_hft/public/header.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..b880b3fa9652d3de68a15988cce3063ea176eb63
Binary files /dev/null and b/ckanext-theme_hft/ckanext/theme_hft/public/header.jpg differ
diff --git a/ckanext-theme_hft/ckanext/theme_hft/public/logo.png b/ckanext-theme_hft/ckanext/theme_hft/public/logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..d43b1064e25d4b7454cd4533fd2215f4f0823f12
Binary files /dev/null and b/ckanext-theme_hft/ckanext/theme_hft/public/logo.png differ
diff --git a/ckanext-theme_hft/ckanext/theme_hft/templates/base.html b/ckanext-theme_hft/ckanext/theme_hft/templates/base.html
new file mode 100644
index 0000000000000000000000000000000000000000..d8ebc5ce6ae72837bc3404a45b5bb9b4af040746
--- /dev/null
+++ b/ckanext-theme_hft/ckanext/theme_hft/templates/base.html
@@ -0,0 +1,7 @@
+{% ckan_extends %}
+
+{% block styles %}
+	{{ super() }}
+	<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.2/css/all.css" integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay" crossorigin="anonymous">
+	{% asset 'theme_hft/theme.css' %}
+{% endblock %}
diff --git a/ckanext-theme_hft/ckanext/theme_hft/templates/footer.html b/ckanext-theme_hft/ckanext/theme_hft/templates/footer.html
new file mode 100644
index 0000000000000000000000000000000000000000..36696af153016295d8eb4bbe2c01603a7fdda942
--- /dev/null
+++ b/ckanext-theme_hft/ckanext/theme_hft/templates/footer.html
@@ -0,0 +1,43 @@
+{% ckan_extends %}
+
+{# override footer.html #}
+{% block footer_content %}
+	<div class="row">
+		<div class="col-md-4 attribution">
+			<img src="/img/footer/Innovative_Hochschule_Initiative_BMBF_GWK_RGB.png" height='90'/>
+		</div>
+		<div class="col-md-2 attribution">
+			<img src="/img/footer/M4_LAB_LOGO_Graustufen.png" height='80'/>
+		</div>
+		<div class="col-md-3 footer-links">
+			<a href="https://twitter.com/InnolabM4">
+				<i class="fa fa-twitter fa-3x"></i>
+			</a>
+			<a href="https://wwww.facebook.com/HfTStuttgart/">
+				<i class="fa fa-facebook-square fa-3x"></i>
+			</a>
+			<a href="https://www.instagram.com/m4_lab/">
+				<i class="fa fa-instagram fa-3x"></i>
+			</a>
+			<a href="https://de.linkedin.com/school/hochschule-f%C3%BCr-technik-stuttgart-%E2%80%93-university-of-applied-sciences/">
+				<i class="fa fa-linkedin fa-3x"></i>
+			</a>
+			<a href="https://www.youtube.com/channel/UCi0_JfF2qMZbOhOnNH5PyHA">
+				<i class="fa fa-youtube-play fa-3x"></i>
+			</a>
+		</div>
+		<div class="col-md-3 footer-links">
+			<div class="row">
+				<div class="col">Hochschule für Technik Stuttgart</div>
+			</div>
+			<div class="row">
+				<div class="col-md-6">
+					<a href="https://www.hft-stuttgart.de/impressum">Impressum</a>
+				</div>
+				<div class="col-md-6">
+					<a href="https://www.hft-stuttgart.de/datenschutz">Datenschutz</a>
+				</div>
+			</div>
+		</div>
+	</div>
+{% endblock %}
diff --git a/ckanext-theme_hft/ckanext/theme_hft/templates/header.html b/ckanext-theme_hft/ckanext/theme_hft/templates/header.html
new file mode 100644
index 0000000000000000000000000000000000000000..df7c8d8f2cb346316de03b25f86b5fcc793cec27
--- /dev/null
+++ b/ckanext-theme_hft/ckanext/theme_hft/templates/header.html
@@ -0,0 +1,9 @@
+{% ckan_extends %}
+
+{# exclude About #}
+{% block header_site_navigation_tabs %}
+	{{ h.build_nav_main(
+		('dataset.search', _('Datasets')),
+		('organization.index', _('Organizations')),
+		('group.index', _('Groups')) ) }}
+{% endblock %}
diff --git a/ckanext-theme_hft/ckanext/theme_hft/templates/home/index.html b/ckanext-theme_hft/ckanext/theme_hft/templates/home/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..6489246211907e9b24bd0c260bff573749497ae8
--- /dev/null
+++ b/ckanext-theme_hft/ckanext/theme_hft/templates/home/index.html
@@ -0,0 +1,2 @@
+{# process the default index.html first #}
+{% ckan_extends %}
diff --git a/ckanext-theme_hft/ckanext/theme_hft/templates/home/snippets/promoted.html b/ckanext-theme_hft/ckanext/theme_hft/templates/home/snippets/promoted.html
new file mode 100644
index 0000000000000000000000000000000000000000..9166e5c07d2e4fc6ad3911a17b10d4ecc5d9b22e
--- /dev/null
+++ b/ckanext-theme_hft/ckanext/theme_hft/templates/home/snippets/promoted.html
@@ -0,0 +1,4 @@
+{% ckan_extends %}
+
+{# remove promoted image #}
+{% block home_image %}{% endblock %}
diff --git a/ckanext-theme_hft/setup.py b/ckanext-theme_hft/setup.py
new file mode 100644
index 0000000000000000000000000000000000000000..fdfee06e615db3b6bde893eb0a6d68f0dbf97fd8
--- /dev/null
+++ b/ckanext-theme_hft/setup.py
@@ -0,0 +1,97 @@
+# -*- coding: utf-8 -*-
+# Always prefer setuptools over distutils
+from setuptools import setup, find_packages
+from codecs import open  # To use a consistent encoding
+from os import path
+
+here = path.abspath(path.dirname(__file__))
+
+# Get the long description from the relevant file
+with open(path.join(here, 'README.md'), encoding='utf-8') as f:
+    long_description = f.read()
+
+setup(
+    name='''ckanext-theme_hft''',
+
+    # Versions should comply with PEP440.  For a discussion on single-sourcing
+    # the version across setup.py and the project code, see
+    # http://packaging.python.org/en/latest/tutorial.html#version
+    version='0.0.1',
+
+    description=''' Customized UI of CKAN of HFT Stuttgart''',
+    long_description=long_description,
+    long_description_content_type="text/markdown",
+
+    # Choose your license
+    license='AGPL',
+
+    # See https://pypi.python.org/pypi?%3Aaction=list_classifiers
+    classifiers=[
+        # How mature is this project? Common values are
+        # 3 - Alpha
+        # 4 - Beta
+        # 5 - Production/Stable
+        'Development Status :: 4 - Beta',
+
+        # Pick your license as you wish (should match "license" above)
+        'License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)',
+
+        # Specify the Python versions you support here. In particular, ensure
+        # that you indicate whether you support Python 2, Python 3 or both.
+        'Programming Language :: Python :: 2.7',
+    ],
+
+
+    # What does your project relate to?
+    keywords='''data catalog''',
+
+    # You can just specify the packages manually here if your project is
+    # simple. Or you can use find_packages().
+    packages=find_packages(exclude=['contrib', 'docs', 'tests*']),
+        namespace_packages=['ckanext'],
+
+    install_requires=[
+      # CKAN extensions should not list dependencies here, but in a separate
+      # ``requirements.txt`` file.
+      #
+      # http://docs.ckan.org/en/latest/extensions/best-practices.html
+      # add-third-party-libraries-to-requirements-txt
+    ],
+
+    # If there are data files included in your packages that need to be
+    # installed, specify them here.  If using Python 2.6 or less, then these
+    # have to be included in MANIFEST.in as well.
+    include_package_data=True,
+    package_data={
+    },
+
+    # Although 'package_data' is the preferred approach, in some case you may
+    # need to place data files outside of your packages.
+    # see http://docs.python.org/3.4/distutils/setupscript.html
+    # installing-additional-files
+    # In this case, 'data_file' will be installed into '<sys.prefix>/my_data'
+    data_files=[],
+
+    # To provide executable scripts, use entry points in preference to the
+    # "scripts" keyword. Entry points provide cross-platform support and allow
+    # pip to create the appropriate form of executable for the target platform.
+    entry_points='''
+        [ckan.plugins]
+        theme_hft=ckanext.theme_hft.plugin:ThemeHftPlugin
+
+        [babel.extractors]
+        ckan = ckan.lib.extract:extract_ckan
+    ''',
+
+    # If you are changing from the default layout of your extension, you may
+    # have to change the message extractors, you can read more about babel
+    # message extraction at
+    # http://babel.pocoo.org/docs/messages/#extraction-method-mapping-and-configuration
+    message_extractors={
+        'ckanext': [
+            ('**.py', 'python', None),
+            ('**.js', 'javascript', None),
+            ('**/templates/**.html', 'ckan', None),
+        ],
+    }
+)