SpoonCMS 1.0.1.2

dotnet add package SpoonCMS --version 1.0.1.2
NuGet\Install-Package SpoonCMS -Version 1.0.1.2
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SpoonCMS" Version="1.0.1.2" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add SpoonCMS --version 1.0.1.2
#r "nuget: SpoonCMS, 1.0.1.2"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install SpoonCMS as a Cake Addin
#addin nuget:?package=SpoonCMS&version=1.0.1.2

// Install SpoonCMS as a Cake Tool
#tool nuget:?package=SpoonCMS&version=1.0.1.2

SpoonCMS

A lightweight .NET core CMS for page content

Why would you use this?

Mostly because you like coding in .Net, but want some flexibility in your content. For the longest time in .Net web dev, if you wanted content management you had to choose between an extremely complex CMS systems that felt like a language/platform unto itself, or deploy updates to html or content files everytime you wanted any update with little exception. So I built a very simple system to manage content (actual content) that did these key things:

  • Easy to integrate (less than 10 lines of code for base implementation)
  • Simple conceptually (You store HTML, you get HTML out)
  • Let's me code in .Net without impediment
  • Can use LiteDB or Postgres as a data source

This is the core of what SpoonCMS does: very simple page content management. No routing, no complex auth systems, just managing the markup on your page.

Getting started

Install the Nuget package: Install-Package SpoonCMS -Version 1.0.1.2 Setup your routes to the admin page and setup the injection of the SpoonData class

 public void ConfigureServices(IServiceCollection services)
{
    ...
    string connString = @"Data\DB\";
    ISpoonData spoonData = SpoonWebWorker.GenerateDataWorker(SpoonDBType.LiteDB, connString);
    SpoonWebWorker.AdminPath = "/adminControl";
    SpoonWebWorker.SpoonData = spoonData;

    services.AddSingleton<ISpoonData>(spoonData);
    ...
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    ...
   app.Map(SpoonWebWorker.AdminPath, SpoonWebWorker.BuildAdminPageDelegate);  
    ...
}

And you now have it installed and can access the admin page at the path you specificy. You will also have a reference to the SpoonData class using dependency injection to access your content like so

public class HomeController : Controller
{
    private readonly ISpoonData _spoonData;

    public HomeController(ISpoonData spoonData)
    {
        _spoonData = spoonData;
    }
    public IActionResult Index()
    {
        HomePageViewModel vm = new HomePageViewModel();
        Container con = _spoonData.GetContainer("HomePage");
        vm.rows = con.GetItem("rows").Value;
        vm.carousel = con.GetItem("myCarousel").Value;
        
        ViewData["Title"] = con.GetItem("pageTitle").Value;
        return View(vm);
    }
...

The Admin

The approach for the admin is to be as simple as possible, without the common instituational feel some CMS give off. The example project has example data and will redirect you to the admin on load. Here I have recreated and broke down the sample MVP project that comes with VS. You will see the list of containers you have created on the left:

Once you select a container, the container's content items will show with a list at the bottom and are orderable.

The editor will show the content as an HTML WYSIWYG editor by default, but you can choose to (and commonly recommended) work in the source. Code your markup in your IDE of choice, verify it, then paste it into the admin.

You can save content items individually, or save them all and their order within the container using the "Save All & Order" button. Remember, if you save the order of the items, you are also saving all the ContentItem in the container as well.

Key Concepts

There are really only 2 classes that you would utilize from code.

The ContentItem class is the basis for your content. For the most part, this will store the name name of your Content (For instance: "HeaderContent") and the value of it which would usually be HTML (<div>This is the Header Content</div>). ContentItems will be stored in a Container, which at it's heart is just a collection of ContentItem.

After you have stored content into a container, you would access it like so:

_spoonData.GetContainer("ContainerName").GetItem("ContentItemName").Value;

Containers are best used to reflect content item collections that will be utilized together. Common use is to have a Container reflect a page, and then ContentItem that are within it represent those dynamic sections. For instance, loading the homepage using spoon.

Container container = _spoonData.GetContainer("HomePage");
PageViewModel vm = new PageViewModel();

vm.headerContent = container.GetItem("HeaderContent").Value;
vm.bodyCotentBlock = container.GetItem("BodyContentBlock").Value;
vm.rightRail = container.GetItem("RightRailContent").Value;
vm.leftNav = container.GetItem("LeftNavLinks").Value;
vm.footer = container.GetItem("FooterContent").Value;

Now you can populate them on the view. Remember to use @Html.Raw since the html is stored encoded

<body>
    <div id="header-block">@Html.Raw(Model.headerContent)</div>
    <div id="body-copy">@Html.Raw(Model.bodyCotentBlock)</div>
    <div id="right-rail">@Html.Raw(Model.rightRail)</div>
    <div id="left-nav">@Html.Raw(Model.leftNav)</div>
    <div id="footer">@Html.Raw(Model.footer)</div>
</body>

Read more at: https://github.com/BenTMatthews/SpoonCMS

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.1.2 936 7/31/2018
1.0.1.1 830 7/29/2018
1.0.1 867 7/29/2018
1.0.0 851 7/29/2018
0.2.3 941 2/25/2018
0.2.2 905 2/21/2018

Release Notes:

- Added support for postgres
-  Dependency cleanup and performance improvement