diff --git a/zero.Core/Entities/Modules/ModuleType.cs b/zero.Core/Entities/Modules/ModuleType.cs
new file mode 100644
index 00000000..5dd54458
--- /dev/null
+++ b/zero.Core/Entities/Modules/ModuleType.cs
@@ -0,0 +1,75 @@
+using System;
+using System.Collections.Generic;
+
+namespace zero.Core.Entities
+{
+ ///
+ /// A module type holds information about a Module implementation
+ ///
+ public class ModuleType : ModuleType where T : Module, new()
+ {
+ public ModuleType() : base(typeof(T)) { }
+ }
+
+
+ ///
+ /// A module type holds information about a Module implementation
+ ///
+ public class ModuleType
+ {
+ ///
+ /// Type of the associated module class
+ ///
+ public Type ContentType { get; private set; }
+
+ ///
+ /// Alias for querying
+ ///
+ public string Alias { get; set; }
+
+ ///
+ /// Name of the module type
+ ///
+ public string Name { get; set; }
+
+ ///
+ /// Optional description
+ ///
+ public string Description { get; set; }
+
+ ///
+ /// Icon of the module type
+ ///
+ public string Icon { get; set; }
+
+ ///
+ /// Optionally group modules together
+ ///
+ public string Group { get; set; }
+
+ ///
+ /// Page types where this module type is not allowed.
+ /// This will only work when operating within the page context.
+ ///
+ public List DisallowedPageTypes { get; set; } = new List();
+
+
+ public ModuleType(Type type)
+ {
+ ContentType = type;
+ }
+
+ public static ModuleType Convert(ModuleType model) where T : Module, new()
+ {
+ return new ModuleType(model.ContentType)
+ {
+ Alias = model.Alias,
+ Name = model.Name,
+ Description = model.Description,
+ Icon = model.Icon,
+ Group = model.Group,
+ DisallowedPageTypes = model.DisallowedPageTypes
+ };
+ }
+ }
+}
diff --git a/zero.Core/Options/ModuleOptions.cs b/zero.Core/Options/ModuleOptions.cs
new file mode 100644
index 00000000..0869ca70
--- /dev/null
+++ b/zero.Core/Options/ModuleOptions.cs
@@ -0,0 +1,48 @@
+using System;
+using System.Collections.Generic;
+using zero.Core.Entities;
+
+namespace zero.Core.Options
+{
+ public class ModuleOptions : ZeroBackofficeCollection, IZeroCollectionOptions
+ {
+ public ModuleOptions()
+ {
+
+ }
+
+
+ public void Add(ModuleType moduleType) where T : Module, new()
+ {
+ Items.Add(ModuleType.Convert(moduleType));
+ }
+
+
+ public void Add(string alias, string name, string description, string icon, string group = null, List disallowedPageTypes = null) where T : Module, new()
+ {
+ Items.Add(new ModuleType(typeof(T))
+ {
+ Alias = alias,
+ Name = name,
+ Description = description,
+ Icon = icon,
+ Group = group,
+ DisallowedPageTypes = disallowedPageTypes ?? new List()
+ });
+ }
+
+
+ public void Add(Type type, string alias, string name, string description, string icon, string group = null, List disallowedPageTypes = null)
+ {
+ Items.Add(new ModuleType(type)
+ {
+ Alias = alias,
+ Name = name,
+ Description = description,
+ Icon = icon,
+ Group = group,
+ DisallowedPageTypes = disallowedPageTypes ?? new List()
+ });
+ }
+ }
+}
diff --git a/zero.Core/Options/ZeroOptions.cs b/zero.Core/Options/ZeroOptions.cs
index 1f2bf9df..25dca9f8 100644
--- a/zero.Core/Options/ZeroOptions.cs
+++ b/zero.Core/Options/ZeroOptions.cs
@@ -19,6 +19,7 @@ namespace zero.Core.Options
Sections = new SectionOptions();
Features = new FeatureOptions();
Pages = new PageOptions();
+ Modules = new ModuleOptions();
Permissions = new PermissionOptions();
Settings = new SettingsOptions();
Spaces = new SpaceOptions();
@@ -60,6 +61,9 @@ namespace zero.Core.Options
///
public PageOptions Pages { get; private set; }
+ ///
+ public ModuleOptions Modules { get; private set; }
+
///
public PermissionOptions Permissions { get; private set; }
@@ -137,6 +141,11 @@ namespace zero.Core.Options
///
PageOptions Pages { get; }
+ ///
+ ///
+ ///
+ ModuleOptions Modules { get; }
+
///
///
///
diff --git a/zero.Debug/TestData/Modules/DownloadModule.cs b/zero.Debug/TestData/Modules/DownloadModule.cs
new file mode 100644
index 00000000..4f9a6e8f
--- /dev/null
+++ b/zero.Debug/TestData/Modules/DownloadModule.cs
@@ -0,0 +1,10 @@
+using System.Collections.Generic;
+using zero.Core.Entities;
+
+namespace zero.TestData
+{
+ public class DownloadModule : Module
+ {
+ public string Name { get; set; }
+ }
+}
diff --git a/zero.Debug/TestData/Modules/GalleryModule.cs b/zero.Debug/TestData/Modules/GalleryModule.cs
new file mode 100644
index 00000000..1001aa2c
--- /dev/null
+++ b/zero.Debug/TestData/Modules/GalleryModule.cs
@@ -0,0 +1,14 @@
+using System.Collections.Generic;
+using zero.Core.Entities;
+
+namespace zero.TestData
+{
+ public class GalleryModule : Module
+ {
+ public List ImageIds { get; set; } = new List();
+
+ public bool IsBigger { get; set; }
+
+ public bool IsFirstImageBigger { get; set; }
+ }
+}
diff --git a/zero.Debug/TestData/Modules/HeadlineModule.cs b/zero.Debug/TestData/Modules/HeadlineModule.cs
new file mode 100644
index 00000000..48ea5d5f
--- /dev/null
+++ b/zero.Debug/TestData/Modules/HeadlineModule.cs
@@ -0,0 +1,12 @@
+using System;
+using zero.Core.Entities;
+
+namespace zero.TestData
+{
+ public class HeadlineModule : Module
+ {
+ public string Headline { get; set; }
+
+ public string Subline { get; set; }
+ }
+}
diff --git a/zero.Debug/TestData/Modules/RichtextModule.cs b/zero.Debug/TestData/Modules/RichtextModule.cs
new file mode 100644
index 00000000..849f5680
--- /dev/null
+++ b/zero.Debug/TestData/Modules/RichtextModule.cs
@@ -0,0 +1,12 @@
+using System;
+using zero.Core.Entities;
+
+namespace zero.TestData
+{
+ public class RichtextModule : Module
+ {
+ public string Text { get; set; }
+
+ public bool IsBigger { get; set; }
+ }
+}
diff --git a/zero.Debug/TestData/Modules/TextWithImageModule.cs b/zero.Debug/TestData/Modules/TextWithImageModule.cs
new file mode 100644
index 00000000..b02f1b3b
--- /dev/null
+++ b/zero.Debug/TestData/Modules/TextWithImageModule.cs
@@ -0,0 +1,16 @@
+using System;
+using zero.Core.Entities;
+
+namespace zero.TestData
+{
+ public class TextWithImageModule : Module
+ {
+ public string Headline { get; set; }
+
+ public string Text { get; set; }
+
+ public string ImageId { get; set; }
+
+ public bool IsLeftAligned { get; set; }
+ }
+}
diff --git a/zero.Debug/TestData/TestPlugin.cs b/zero.Debug/TestData/TestPlugin.cs
index c28d9b19..a7b7e3f7 100644
--- a/zero.Debug/TestData/TestPlugin.cs
+++ b/zero.Debug/TestData/TestPlugin.cs
@@ -30,6 +30,12 @@ namespace zero.TestData
zero.Pages.Add("content", "Page", "Page consisting of modules", "fth-box", allowAsRoot: true, allowAllChildrenTypes: true);
zero.Pages.Add("root", "Homepage", "Entry point for the website", "fth-home", allowAsRoot: true, allowAllChildrenTypes: true);
zero.Pages.Add("redirect", "Redirect", "Redirect to another page or an external URL", "fth-external-link", allowAsRoot: true, allowedChildrenTypes: new List() { "content", "redirect" });
+
+ zero.Modules.Add("richtext", "Richtext", "Simple richtext block editor", "fth-align-left", "Texts");
+ zero.Modules.Add("headline", "Headline", "Headline with optional subline", "fth-underline", "Texts");
+ zero.Modules.Add("textWithImage", "Text with image", "Short textblock with image", "fth-layers", "Texts", new List() { "root" });
+ zero.Modules.Add("gallery", "Gallery", "Image gallery grid", "fth-image", "Media");
+ zero.Modules.Add("download", "Downloads", "List containing downloads", "fth-download", "Lists");
}
public void ConfigureServices(IServiceCollection services)
diff --git a/zero.Web.UI/Sass/Canvas/_navigation.scss b/zero.Web.UI/Sass/Canvas/_navigation.scss
index 49468136..39a21f2b 100644
--- a/zero.Web.UI/Sass/Canvas/_navigation.scss
+++ b/zero.Web.UI/Sass/Canvas/_navigation.scss
@@ -60,7 +60,7 @@ a.app-nav-item
align-items: center;
font-size: var(--font-size);
padding: 0 var(--padding);
- height: 52px;
+ height: 50px;
color: var(--color-fg-dim);
&:hover
@@ -78,6 +78,7 @@ a.app-nav-item
color: var(--color-fg);
background: var(--color-bg-bright-two);
font-weight: 700;
+ border-right: 3px solid var(--color-primary);
.app-nav-item-icon
{
diff --git a/zero.Web.UI/Sass/Modules/_link.scss b/zero.Web.UI/Sass/Modules/_link.scss
index b1171e7b..6a2f2805 100644
--- a/zero.Web.UI/Sass/Modules/_link.scss
+++ b/zero.Web.UI/Sass/Modules/_link.scss
@@ -2,18 +2,7 @@
.ui-link
{
- color: var(--color-primary);
- text-decoration: underline dotted var(--color-primary);
+ color: var(--color-fg-dim);
+ text-decoration: underline dotted var(--color-fg-dim);
text-underline-offset: 3px;
-
- &.is-minor
- {
- color: var(--color-fg-dim);
- text-decoration: none;
-
- &:hover
- {
- color: var(--color-fg);
- }
- }
}
\ No newline at end of file