diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..14bc68c7cc2ac75f3ade400869623729943f03ae
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/nbproject/private/
\ No newline at end of file
diff --git a/amd/build/sembasednav.min.js b/amd/build/sembasednav.min.js
new file mode 100644
index 0000000000000000000000000000000000000000..2746e1d6f2e060c807757b3633ab4f513a6bcbb0
--- /dev/null
+++ b/amd/build/sembasednav.min.js
@@ -0,0 +1 @@
+define(["jquery"],function(t){function a(a){t('.list-group-item[data-key="'+a+'"]').click(function(){t(this);!function(a,i){t('.list-group-item[data-parent-key="'+i+'"]').each(function(){var a=t(this),i=a.data("key");a.addClass("localboostnavigationcollapsedparent"),t('.list-group-item[data-parent-key="'+i+'"]').addClass("localboostnavigationcollapsedchild")})}(0,a)})}return{closeAllChildNodes:function(t){a(t)}}});
\ No newline at end of file
diff --git a/amd/src/sembasednav.js b/amd/src/sembasednav.js
new file mode 100644
index 0000000000000000000000000000000000000000..8c8c2bd0baa1c68375e91f886cb36763740206e9
--- /dev/null
+++ b/amd/src/sembasednav.js
@@ -0,0 +1,37 @@
+define(['jquery'], function ($) {
+
+    /**
+     * Handles the actual closing of nodes
+     * @param {Object} $node
+     * @param {String} nodeName
+     */
+    function handleClosingNodes($node, nodeName) {
+        $('.list-group-item[data-parent-key="' + nodeName + '"]').each(function () {
+            var $this = $(this);
+            var key = $this.data('key');
+            $this.addClass('localboostnavigationcollapsedparent');
+            $('.list-group-item[data-parent-key="' + key + '"]').addClass('localboostnavigationcollapsedchild');
+        });
+    }
+
+    /**
+     * Closes all child nodes of given node name
+     * Fixes second level children (e.g Semester modules) not closing when mycourses gets closed
+     * @param {String} nodeName
+     */
+    function closeAllChildNodes(nodeName) {
+        var $node = $('.list-group-item[data-key="' + nodeName + '"]');
+
+        $node.click(function () {
+            var $this = $(this);
+
+            handleClosingNodes($this, nodeName);
+        });
+    }
+
+    return {
+        closeAllChildNodes: function (nodeName) {
+            closeAllChildNodes(nodeName);
+        }
+    };
+});
\ No newline at end of file
diff --git a/lang/en/local_sembasednav.php b/lang/en/local_sembasednav.php
index db6d42d838f5705bba8b72875eeef4d5275a4df3..28078692f45fd0ec996ee86287229fc99139bab1 100644
--- a/lang/en/local_sembasednav.php
+++ b/lang/en/local_sembasednav.php
@@ -19,10 +19,25 @@
  *
  * @package     local_sembasednav
  * @category    string
- * @copyright   2020 Peter Fricke <peter.fricke@hs-hannover.de>
+ * @copyright   2020 Julian Wendling <julian.wendling@stud.hs-hannover.de>
  * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
 defined('MOODLE_INTERNAL') || die();
 
-$string['pluginname'] = 'semester based navigation';
+$string['pluginname'] = 'Semester Based Navigation';
+
+$string['setting_nosemestername'] = 'Kurs ohne Semester';
+$string['setting_nosemestername_desc'] = 'Name des Semesters in dem Kurse ohne Semester angezeigt werden';
+
+$string['setting_nodescount'] = 'Anzahl der anzuzeigenden Semester';
+$string['setting_nodescount_desc'] = 'Semesterunabhängiger Nodes nicht mit einbegriffen';
+
+$string['setting_semesterorder'] = 'Semesterreihenfolge';
+$string['setting_semesterorder_desc'] = 'Semesterreihenfolge in der Navigation';
+
+$string['setting_specialNodes'] = 'Position der Special Nodes';
+$string['setting_specialNodes_desc'] = 'z.B. Semesterunabhängig';
+
+$string['setting_openfirstnode'] = 'Erste Semester Node aufgeklappt darstellen';
+$string['setting_openfirstnode_desc'] = '';
diff --git a/lib.php b/lib.php
new file mode 100644
index 0000000000000000000000000000000000000000..0dd94d3a6a50bba73e0d42e1278c023cdc599658
--- /dev/null
+++ b/lib.php
@@ -0,0 +1,309 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * @package    local_sembasednav
+ * @copyright  2020 Julian Wendling, Hochschule Hannover <julian.wendling@stud.hs-hannover.de>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+function local_sembasednav_extend_navigation(global_navigation $navigation)
+{
+    global $PAGE, $CFG;
+
+    $myCoursesNode = $navigation->find('mycourses', global_navigation::TYPE_ROOTNODE);
+    $myCoursesChildNodes = $myCoursesNode->get_children_key_list();
+
+    $maxSemesterNodes = get_config('sembasednav', 'setting_nodescount');
+    $openFirstSemester = get_config('sembasednav', 'setting_openfirstnode');
+    $semesterDescending = get_config('sembasednav', 'setting_semesterorder');
+    $specialNodesFirst = get_config('sembasednav', 'setting_specialNodes');
+
+    // Register JS to close all child nodes from root node (mycourse)
+    $PAGE->requires->js_call_amd('local_sembasednav/sembasednav', 'closeAllChildNodes', [$myCoursesNode->key]);
+
+    try {
+        $courses = enrol_get_my_courses();
+    } catch (Exception $e) {
+        echo $e->getMessage();
+        $courses = [];
+    }
+
+    // Hides courses that are shown by default
+    foreach ($myCoursesChildNodes as $cn) {
+        $myCoursesNode->find($cn, null)->showinflatnavigation = false;
+    }
+
+    // Nodes that are excluded from max semester count - will always be shown
+    $noSemesterAssignedName = get_config('sembasednav', 'setting_nosemestername');
+    $specialNodes = ["Semesterunabhängig", $noSemesterAssignedName];
+    $specialNodesList = [];
+    $mySemesters = [];
+
+    // Sort semester depending on setting
+    if ($semesterDescending == 0) {
+        // Descending
+        usort($courses, function ($a, $b) {
+            $aId = get_semester_id($a->id);
+            $bId = get_semester_id($b->id);
+
+            return strcasecmp($bId, $aId);
+        });
+    } else {
+        // Ascending
+        usort($courses, function ($a, $b) {
+            $aId = get_semester_id($a->id);
+            $bId = get_semester_id($b->id);
+
+            return strcasecmp($aId, $bId);
+        });
+    }
+
+    // Assign all modules and semesters
+    foreach ($courses as $c) {
+        $semesterName = get_semester_name($c->id);
+
+        $courseName = empty($CFG->navshowfullcoursenames) ? $c->shortname : $c->fullname;
+
+        if (in_array($semesterName, $specialNodes, true)) {
+            $specialNodesList[$semesterName][] = $courseName;
+        } else {
+            if (count($mySemesters) >= $maxSemesterNodes) {
+                continue;
+            }
+            $mySemesters[$semesterName][] = $courseName;
+        }
+    }
+
+    if ($specialNodesFirst == 0)
+        add_semester_nodes($specialNodesList, $myCoursesNode);
+
+    // Add all semester nodes
+    add_semester_nodes($mySemesters, $myCoursesNode);
+
+    if ($openFirstSemester)
+        open_first_semester_node($mySemesters, $myCoursesNode);
+
+    // Add all special nodes
+    if ($specialNodesFirst == 1)
+        add_semester_nodes($specialNodesList, $myCoursesNode);
+
+    // Sorts course node alphabetically
+    usort($courses, function ($a, $b) {
+        $aId = $a->shortname;
+        $bId = $b->shortname;
+
+        return strcasecmp($aId, $bId);
+    });
+
+    // Creates all course nodes and assigns them to their semester node
+    foreach ($courses as $c) {
+        $semesterName = get_semester_name($c->id);
+        $semesterKey = create_node_key($semesterName);
+        $semesterNode = $navigation->find($semesterKey, null);
+
+        if (!$semesterNode) {
+            continue;
+        }
+
+        $courseName = empty($CFG->navshowfullcoursenames) ? $c->shortname : $c->fullname;
+        $courseKey = create_node_key($courseName);
+
+        $courseNode = navigation_node::create($courseName, new moodle_url('/course/view.php', array('id' => $c->id)), global_navigation::TYPE_COURSE, $courseName, $courseKey, new pix_icon('i/course', 'grades'));
+        $courseNode->showinflatnavigation = true;
+        $courseNode->add_class('p-l-3');
+        $courseNode->add_class('localboostnavigationcollapsiblechild');
+        if (!$semesterNode->forceopen)
+            $courseNode->add_class('localboostnavigationcollapsedchild');
+
+        $semesterNode->add_node($courseNode);
+    }
+
+
+}
+
+/**
+ * Adds all semester nodes to given parent node and registers
+ * them for collapse navigation js
+ * @param array $semesterList
+ * @param $parentNode
+ * @throws coding_exception
+ * @throws dml_exception
+ */
+function add_semester_nodes(array $semesterList, $parentNode)
+{
+    global $PAGE;
+
+    $collapsenodesforjs = [];
+
+    foreach ($semesterList as $key => $value) {
+        $semesterNode = create_semester_node($key);
+
+        if (!in_array($semesterNode->key, $collapsenodesforjs)) {
+            $collapsenodesforjs[] = $semesterNode->key;
+        }
+
+        $parentNode->add_node($semesterNode);
+    }
+
+    // Apply collapse navigation js to every semeseter
+    if (!empty($collapsenodesforjs)) {
+        $PAGE->requires->js_call_amd('local_boostnavigation/collapsenavdrawernodes', 'init',
+            [$collapsenodesforjs, []]);
+
+        foreach ($collapsenodesforjs as $node) {
+            user_preference_allow_ajax_update('local_boostnavigation-collapse_' . $node . 'node', PARAM_BOOL);
+        }
+    }
+}
+
+/**
+ * @param array $semesterList
+ * @param $myCourseNode
+ */
+function open_first_semester_node(array $semesterList, $myCourseNode)
+{
+    $semesterKeys = array_keys($semesterList);
+
+    if (empty($semesterKeys[0]))
+        return;
+
+    $firstSemesterKey = create_node_key($semesterKeys[0]);
+
+    $semesterNode = $myCourseNode->find($firstSemesterKey, global_navigation::TYPE_CUSTOM);
+
+    $semesterNode->forceopen = true;
+
+    $semesterNode->remove_class('localboostnavigationcollapsedparent');
+}
+
+/**
+ * Creates a semester node with needed cs classes for collapse navigation js
+ * @param string $semesterName
+ * @return navigation_node
+ * @throws coding_exception
+ * @throws dml_exception
+ */
+function create_semester_node(string $semesterName)
+{
+    $localBoostnavigationConfig = get_config('local_boostnavigation');
+    $userprefmycoursesnode = get_user_preferences('local_boostnavigation-collapse_mycoursesnode',
+        $localBoostnavigationConfig->collapsemycoursesnodedefault);
+
+    $semesterKey = create_node_key($semesterName);
+
+    $semesterNode = navigation_node::create($semesterName, new moodle_url('/course/view.php', null), global_navigation::TYPE_CUSTOM, null, $semesterKey, null);
+    $semesterNode->showinflatnavigation = true;
+
+    $semesterNode->add_class('localboostnavigationcollapsibleparent');
+    $semesterNode->add_class('localboostnavigationcollapsedparent');
+    $semesterNode->add_class('localboostnavigationcollapsiblechild');
+
+    if ($userprefmycoursesnode == 1) {
+        $semesterNode->add_class('localboostnavigationcollapsedchild');
+    }
+
+    return $semesterNode;
+}
+
+/**
+ * Creates a whitespace and slash free semester key
+ * @param string $semesterName
+ * @return string
+ */
+function create_node_key(string $semesterName)
+{
+    return "node-" . str_replace([" ", "/"], "-", $semesterName);
+}
+
+/**
+ * Returns semester name of given course id.
+ * If no semester is found, return no semester assigned name.
+ * @param int $id
+ * @return string
+ */
+function get_semester_name(int $id)
+{
+    global $DB;
+
+    $noSemesterAssigned = get_config('sembasednav', 'setting_nosemestername');
+    $semesterName = '';
+
+    try {
+        $semFieldName = $DB->get_record('customfield_field', array('type' => 'semester'), '*', MUST_EXIST);
+    } catch (Exception $e) {
+        return $noSemesterAssigned;
+    }
+
+    try {
+        $allCustomFields = get_course_metadata($id);
+        $semesterField = $allCustomFields[$semFieldName->shortname];
+        $semesterValue = preg_replace('/[^0-9]/', '', $semesterField); // extract semester int from string
+        $semesterName = \customfield_semester\data_controller::get_name_for_semester((int)$semesterValue);
+
+    } catch (Exception $e) {
+    }
+
+    return empty($semesterName) || $semesterName === '' ? $noSemesterAssigned : $semesterName;
+}
+
+/**
+ * @param int $id
+ * @return string
+ */
+function get_semester_id(int $id)
+{
+    global $DB;
+
+    $semesterValue = '';
+
+    try {
+        $semFieldName = $DB->get_record('customfield_field', array('type' => 'semester'), '*', MUST_EXIST);
+    } catch (Exception $e) {
+        return 0;
+    }
+
+    try {
+        $allCustomFields = get_course_metadata($id);
+        $semesterField = $allCustomFields[$semFieldName->shortname];
+        $semesterValue = preg_replace('/[^0-9]/', '', $semesterField); // extract semester int from string
+    } catch (Exception $e) {
+    }
+
+    return empty($semesterValue) || $semesterValue === '' ? 0 : $semesterValue;
+}
+
+// https://docs.moodle.org/dev/Custom_fields_API#Example_code_for_course_custom_fields
+/**
+ * Used to access course semester field
+ * @param $courseid
+ * @return array
+ * @throws moodle_exception
+ */
+function get_course_metadata($courseid)
+{
+    $handler = \core_customfield\handler::get_handler('core_course', 'course');
+    $data = $handler->get_instance_data($courseid);
+    $metadata = [];
+    foreach ($data as $d) {
+        if (empty($d->get_value())) {
+            continue;
+        }
+        $cat = $d->get_field()->get_category()->get('name');
+        $metadata[$d->get_field()->get('shortname')] = $cat . ': ' . $d->get_value();
+    }
+    return $metadata;
+}
\ No newline at end of file
diff --git a/settings.php b/settings.php
index 15e10f431758335561d9dda92159c052293b2e38..aa2e8b872873ef29f24a2c9b3179a24c3065d2f1 100644
--- a/settings.php
+++ b/settings.php
@@ -19,13 +19,61 @@
  *
  * @package     local_sembasednav
  * @category    admin
- * @copyright   2020 Peter Fricke <peter.fricke@hs-hannover.de>
+ * @copyright   2020 Julian Wendling <julian.wendling@stud.hs-hannover.de>
  * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
 defined('MOODLE_INTERNAL') || die();
+require_once(__DIR__ . '/lib.php');
 
-if ($ADMIN->fulltree) {
-   // TODO: Define the plugin settings page.
-   // https://docs.moodle.org/dev/Admin_settings
+if ($hassiteconfig) {
+    // New settings page.
+    $page = new admin_settingpage('sembasednav',
+        get_string('pluginname', 'local_sembasednav', null, true));
+
+    if ($ADMIN->fulltree) {
+        // Default-Settings auf 0 da ein aktueller Bug besteht, der die Default-Settings nicht übernimmt.
+        // Name for courses without a semester
+        $setting = new admin_setting_configtext('sembasednav/setting_nosemestername',
+            get_string('setting_nosemestername', 'local_sembasednav', null, true),
+            get_string('setting_nosemestername_desc', 'local_sembasednav', null, true), 'Ohne Semester', PARAM_TEXT);
+        $page->add($setting);
+
+        // Default-Settings auf 0 da ein aktueller Bug besteht, der die Default-Settings nicht übernimmt.
+        // Visible semester nodes
+        $setting = new admin_setting_configtext('sembasednav/setting_nodescount',
+            get_string('setting_nodescount', 'local_sembasednav', null, true),
+            get_string('setting_nodescount_desc', 'local_sembasednav', null, true), 0, PARAM_INT);
+        $page->add($setting);
+
+        // Default-Settings auf 0 da ein aktueller Bug besteht, der die Default-Settings nicht übernimmt.
+        // Open first semester
+        $page->add(new admin_setting_configcheckbox('sembasednav/setting_openfirstnode',
+            get_string('setting_openfirstnode', 'local_sembasednav', null, true),
+            get_string('setting_openfirstnode_desc', 'local_sembasednav', null, true),
+            0));
+
+        // Semester order
+        $name = 'sembasednav/setting_semesterorder';
+        $title = get_string('setting_semesterorder', 'local_sembasednav');
+        $description = get_string('setting_semesterorder_desc', 'local_sembasednav');
+        $choices[0] = 'Absteigend';
+        $choices[1] = 'Aufsteigend';
+        $setting = new admin_setting_configselect($name, $title, $description, null, $choices);
+        $setting->set_updatedcallback('theme_reset_all_caches');
+        $page->add($setting);
+
+        // Position of special nodes
+        $name = 'sembasednav/setting_specialNodes';
+        $title = get_string('setting_specialNodes', 'local_sembasednav');
+        $description = get_string('setting_specialNodes_desc', 'local_sembasednav');
+        $choices[0] = 'Oberhalb der Semester';
+        $choices[1] = 'Unterhalb der Semester';
+        $setting = new admin_setting_configselect($name, $title, $description, null, $choices);
+        $setting->set_updatedcallback('theme_reset_all_caches');
+        $page->add($setting);
+    }
+
+    // Add settings page to the appearance setting category.
+    $ADMIN->add('appearance', $page);
 }
diff --git a/version.php b/version.php
index 4b4d3448ac15e3f3a19c3f571bfc95b93a89b613..ef096afe2759647ba57b2b731d3ae22fac5080ac 100644
--- a/version.php
+++ b/version.php
@@ -31,4 +31,5 @@ $plugin->requires = 2019052000;
 $plugin->maturity = MATURITY_ALPHA;
 $plugin->dependencies = [
     'customfield_semester' => 2020041301,
-];
+    'local_boostnavigation' => 2020111600
+];
\ No newline at end of file