-
Notifications
You must be signed in to change notification settings - Fork 1
How to
PhunCMS is a non-intrusive add-on to your MVC 4+ projects. Adding PhunCMS nuget package only change two files, your web config and a custom PhunCMS bootstrapped file.
PhunCMS is open source and MIT licensed. It is open to bug report, enhancement, and recommendation. Understanding the configuration section
<configSections>
<section name="phuncms" type="Phun.Configuration.PhunCmsConfigurationSection, Phun"
requirePermission="false" />
</configSections>
<phuncms resourceRoute="~/phuncms" contentRoute="CmsContent" adminRoles="Content Admin, System Admin"
domainLevel="1">
<hostAuthorization>
<add key="clienthost1.com" value="RoleForClient1, System Admin" />
</hostAuthorization>
<contentMap>
<add route="CmsContent" repositoryType="sql"
repositorySource="DefaultConnectionStringName"
repositoryTable="CmsContent" repositoryCache="App_Data\CmsContent" />
<add route="CmsContent" repositoryType="file"
repositorySource="App_Data\CmsContent" />
</contentMap>
</phuncms>
[phuncms] - this element must name as "phuncms"
- @resourceRoute: required, configure route for PhunCMS embedded resource.
- @contentRoute: required, configure route for your CMS Content storage, see also [contentMap] element.
- @adminRoles: optional, comma separated list of roles that are Content Admin. If left blank, all authenticated users are Content Admin.
- @disableResourceCache: optional, if false or not set, embedded resources response with HTTP 304 based on the last modified date of the Phun assembly.
[contentMap] [add] - this is just a wrapper element for content routes
- @route: required, this must be the same as contentRoute in [phuncms] element. It maps the route of our CMS content.
- @repositoryType: required, the repository type name: sql, file, or fully qualified assembly name
- @repositorySource: required, this is connection string name for sql. For file, it is the base folder name, if there is no colon in the path; it is assume to be a relative path. "App_Data", "C:\MyContentStore", etc...
- @repositoryTable: require, this is the table name for sql repository.
- @repositoryCache: optional, allow for local caching of sql repository files. Downloading file to a local directory help improve file transfer performance. If the local file is out-of-date, it will be redownloaded; otherwise, the local file will be serve up as content.
- @domainLevel: optional, default to 1 meaning the system will store in separate tenant/host repository for every host, minus "www". So if you have: ftp.phuncms.com, ftp.tom.phuncms.com, tom.phuncms.com, phuncms.com, and www.phuncms.com then the content are separated in four different folders.
[hostAuthorization] [add] - this is for setting up content admin permission for multi-tenant. It gives you the flexibility of hosting for multiple clients and setting up different Content Admin for each client.
- @key: hostname, phuncms.com, funcms.com, etc...
- @value: comma separate list of roles similar to override phuncms@adminRoles value.
Do not manually map your route. It is best to use the default MVC or similar route mapping for maintenance free routing.
- Must use Visual Studio 2012 to open this solution.
- Must run as a IIS website and not Virtual Folder. It was not part of the design so we're not sure if it'll work.
Since PhunCMS is just a plugin to your new or existing MVC4 project, you are free to use any templating engine you choose. Default Razor? Using with StackExchange Razor Markdown? With Spark? With nHaml? Current version of PhunCMS only extended three HtmlHelper methods: PhunRenderPartialContent, PhunRenderPartialForInlineEdit, and PhunRenderBundles. Verbosely, they are exactly what they're named. You may want to render just the content on a page. You can render content that inline editable when a Content Admin visits the page. You are required to render phun bundles which are client-side JavaScript to handle content editing. See example below.
@Html.PhunPartial("LeftHeader")
or
@Html.PhunPartialEditable("h2", "LeftHeader", new { @class= "one" })
@section scripts
{
@Html.PhunBundles()
}
PhunCMS support full page templating. You can use file manager to create a page. A page basically maps or represents a url path. "/Your/Page1" or "/Your/Page2" which is actually physically mapped to a default file on that path: "/Your/Page1/_default" and "/Your/Page2/_default". Anything under this path is considering partial content. So you can also template inside of "_default" file. "_default" file is required to have both the html and head elements. You should also provide page metadata and title for SEO purposes. Example below show how template works:
<div data-cmscontent="LeftHeader"></div><div data-cmscontent="RightHeader"></div>
- The two contents are Ajax loaded and will become inline editable for content admin.
<div data-contentcms>%LeftHeader%</div><div data-cmscontent="RightHeader"></div>
<div>%SomeOtherContent%</div>
- Example will render LeftHeader and SomeOtherContent on server-side, while RightHeader get Ajax load. Both LeftHeader and RightHeader will become inline editable.
- Example above utilizes the current path or relative path to store its data. Therefore, all the partial data will be store in "/Your/Page1/" folder. Let say you're inside of "/Your/Page2/_default" then Absolute path can also be used.
<div data-cmscontent="LeftHeader">%LeftHeader%</div><div data-cmscontent="RightHeader"></div>
<div>%/Your/Page1/SomeOtherContent%</div>
By design, different host content are stored in separate folders; thereby, provide multi-tenant support. This is also beneficial for let say mobile support. If you map your DNS to somesite.com and m.somesite.com, then contents are stored separately for mobile site.
And if you're wondering if you can share content between CMS tenants, the answer is no. To keep the system simple, it was a concious decision not to support content sharing between repositories. This helps decouple the content; and thereby, prevent sudden changes of one tenant content to affect other tenants. Entire folder can be downloaded as a zip file so it's easy to make a copy from one tenant to another.
Did I say the answer is no? Not really. If you custom code the Razor view or template, then you can share that part of the contents. Server-side template is basically the view or theme of your CMS/site.
PhunCMS content repository/connector is of interface base. Therefore, it is user extensible and configures to use the new content repository. See @repositoryType in configuration section.
For now, PhunCMS only provide two repositories: file and sql. Both should be sufficient for now especially the file repository. We attempt to design the sql repository to be more ANSI SQL so it would support multiple backend. As a result, it's not very efferent. There is current work in progress to develop a better sql repository and it will just be for SQL Server.
Since many CMS modules can just file based storage, PhunCMS can also be extended as backend storage for future module.
// map route ~/Wiki
public class WikiController : PhunCmsContentController {
/// <summary>
/// <add route="Wiki" repositoryType="Sql" ... />
/// Initializes a new instance of the <see cref=" WikiController "/> class.
/// </summary>
public WikiController () : base()
{
this.MyContentConfig =
this.Config.ContentMaps.FirstOrDefault(
c =>
string.Compare(c.RouteNormalized, "Wiki", StringComparison.OrdinalIgnoreCase)
== 0);
}
}
All the basic server/connector methods are there. You don't even have to map the route, just use the configuration. Remember [contentMap] element is a collection. So you just need to add a configuration and PhunCMS automatically map you route. You should define a different repository location. Security will be the same as your @contentRoute security.
Although not tested and not recommended, we do provide micro-security by path or route. Let say you template a page and only want a specific user access to that page. You can inject IContentPathPermissionHandler. PhunCmsContentController also defined a greedy constructor that allow for injection of this interface.
/// <summary>
/// Initializes a new instance of the <see cref="PhunCmsContentController" /> class.
/// </summary>
/// <param name="contentPathAdminHandler">The content path admin handler.</param>
public PhunCmsContentController(IContentPathPermissionHandler contentPathAdminHandler)
: this()
{
this.ContentPathPermissionHandler = contentPathAdminHandler;
}
Please review source code for more info on the two methods "upsert" and "upload" that utilize this handler implementation. You client-side code will need to call this server-side actions instead of the regular "create, update, delete" actions. One additional benefit is you can store your permission in a database somewhere; where by, you can have a UI to setup this configuration. Your IContentPathPermissionHandler implementation is just a cache access to this permission database.
See @domainLevel in configuration section above. We currently do not have the capability of parsing top level domain. You want to be conscious about your domain mapping; and so, PhunCMS only other option is to set a depth on domain level mapping. Per the configuration section example above, if you set the @domainLevel value to 2 means that the content will only store under myhost.com location. If you set it to 3, it will be stored under ftp.myhost.com, john.myhost.com, and myhost.com.
To quickly get the project up and running, we adopted createjs as our starter client-side editing tool for the CMS. This is also because PhunCMS follow the same CMS modular movement. Though there is some known issue with createjs such as not supporting all browsers (ie7). Cough, if you're still using IE7 you probably deserved everything else that's coming such as viruses.
Createjs has 4 built in editors. We currently set default to ckeditor because we like all the nice features it provides. The default editor for createjs is Halo. Then there is also Aloha and Redactor. Please see createjs to figure out how to enable these editors: http://createjs.org/
We know that the default FileManager UI is not very pretty, but it does the job. Part of being modular is you can provide your own File Manager UI which should all be in JavaScript. Since you will be writing your site menu with your Razor template, you can link to your own File Manager UI.
As you will find out, different IIS version may handle route and configuration differently. If you required, PhunCMS provide many different routing implementation. Please see phun project app config for additional example and also see Phun.Routing source for this different routing configuration.