Feature Request:Scheduled publish / unpublish support on Custom Data Types


One use case is that, there's only 1 page, and a seperated folder containing all data items. Like Blogs, News, etc.

In this case, a data item is actually a 'page', so it make sense to enable users to schedule publish / unpublish date for data items ( instances of custom Data Type ) just like the pages.


burningice wrote Apr 19, 2014 at 6:56 PM

Publish/unpublish for pages seems to be implemented quite clumpsy and very much as an afterthought :(

The best for you is most likely to create your own datafacade-classes for your data which handles the filtering based on a publish/unpublished schedule. An example of this is this generic teaser module which support setting these dates and handles the filtering before returning data-instances further up the chain



elencala wrote Apr 20, 2014 at 6:34 AM


Thank you for the quick and detailed response.

This approach seems neat comparing to the pages implementation.

Will it still benefit from c1 caching? When data changes, will it automatically refresh cache no matter which data store(xml/sql)?

burningice wrote Apr 20, 2014 at 10:44 AM

Depends what you have in mind when you say caching.

The most effective caching done by C1 is the Full Page Caching which only takes the modification of the actual page into account. Since the default duration is 60 seconds though, i wouldn't see it as a problem that some data doesn't get hidden/shown right on the exact second but maybe up to a minute later.

Another caching is in the Datalayer but it generally only works when you're querying data by its key. As soon as you have where-statements in there the query would continue down to the SQL database or xml-files, unless you do your own caching mechanisms.

Since this kind of publish/unpublish works using extra data on each record, its important always to do the filtering, since you can have "unpublished" data in the published table, but because the FilterPublishedDate method takes an IQueryable<T>, C1 is smart enough to append the WHERE to the actual sql-query being constructed and executed so there is no really overhead doing it this way. This is fundamentally different than the way C1 handles publish/unpublish of pages, where the datarecords actually are moved back and forth between the published and unpublished tables.

Another neat trick is that you can extend FilterPublishedDate a bit, and instead of hardcoding now to DateTime.Now, you could say that if you're logged in the C1 Console, and you have the querystring ?now=12-12-2014 in the pagerequest, then now should be the date specified in the querystring. This way you can preview how your page would look like on a certain date/time. Very very valuable when you ie. have some banners which should become visible on the 1st of December but you need to make sure how its going to look before hand.

wrote Apr 20, 2014 at 1:18 PM

elencala wrote Apr 20, 2014 at 6:36 PM

Yeah 60 seconds is totally fine in my case.

Regarding the Datalayer caching, just to make sure I'm not misunderstanding anything ( English is not my first language ). It only works when I query data by its key, means it doesn't work when I query a collection, nor FirstOrDefault from a collection. Correct?

From what I've been learning from this post, C1 full page caching caches the rendered pages ( html strings? ). If some data is modified, will it drop & rebuild the cache immediately or do it on the next 60-seconds checkpoint? When it does that, it just rebuild the 'changed' pages, right?

I'm going to read c1 doc again...

The neat trick you offered is very useful indeed. I'll try to implement it in my work. Since I'm quite new to C1 and this could be considered as my first c1 project, I'll be very appreciate if you point me some ways. :)

elencala wrote Apr 20, 2014 at 6:39 PM

Btw, C1 crashed when I was trying to install your Teaser package. Says it can't find CompositeC1Contrib.Sorting.dll. Manually copying the file to /bin could solve this. Then I tried to install Sorting package, but it crashed again, same error. A small bug maybe? C1 version 4.1.

burningice wrote Apr 20, 2014 at 7:08 PM

Nja... its because C1 package system doesn't really handle interdependencies between packages like NuGet does. The requirements for the Teaser package is
  • Sorting 1.4.1 which has a requirement on
  • Core 0.6 (which there isn't a package for)
I admit there could be an easier way to install the C1Contrib packages, but since they are generally not something simple out-of-the-box gallery-thingy or videoplayer which editors would quickly install and use, but fundamental building blocks developers would need i presume that most developers would be able to get them installed one way or the other.

There could also be some bindings to Razor 3.0 somewhere along the way, i know this will be updated and fixed in C1 for version 4.2 but until then, make sure to have the newest Web Pages and Razor binaries and do an assembly redirect in your web.config so all references to those assemblies are forwarded to version

You can see here how C1 handles the Full Page caching https://bitbucket.org/actoas/composite-c1/src/b22758141cade32fa21625c782a6e64eb3600611/CompositeC1/Composite/Core/WebClient/ApplicationLevelEventHandlers.cs?at=default#cl-255. The Changeddate of a page gets a part of the cache key, meaning that as soon as an editor edits a page it will be flushed. As for Datalayer caching, then i would assume that every query which only involved a lookup on the key, that would be something like .FirstOrDefault(d => d.Id == ...), .Where(d => d.Id == ...), .Single(d => d.Id == ...) and so on would use some internal caching. But i'm not 100% sure.

elencala wrote Apr 21, 2014 at 6:09 PM

Thank you very much, I'll dive into it from there.

Anyway, will this become an out-of-box feature in C1 in the future? I think it should be a common requirement.

wrote Apr 23, 2014 at 12:39 PM

burningice wrote Feb 9, 2015 at 5:36 PM

This is now an out-of-the-box feature in C1. When adding/editing datatypes that implements IPublishControlled (the 'Has Publishing' checkmark when creating dynamic types), you now have to implicit bindings in your FormDefinition
  • PublishDate
  • UnpublishDate
If you haven't edited the custom markup yourself, these two new fields will show up automatically, otherwise you would need to make two small changes in the Form Defintion xml files for the types you want to publish/unpublish.

In the bindings-section, add these two new bindings
<cms:binding name="PublishDate" type="System.DateTime" optional="true" />
<cms:binding name="UnpublishDate" type="System.DateTime" optional="true" />
In the layout-section, add these two new fields at the bottom
<DateSelector Label="Publish date">
          <cms:bind source="PublishDate" />
      <DateSelector Label="Unpublish date">
          <cms:bind source="UnpublishDate" />
The publish/unpublish works 100% the same was as for pages, so no need to change any of your functions or other data-specific code.

The feature was added in this changeset https://bitbucket.org/actoas/composite-c1-acto-build/commits/b8cada267041af9ae65ebfddf584c523ffa7d828 - i can't promise when it will make it to an official C1 release, but hopefully soon.

elencala wrote Feb 12, 2015 at 8:29 AM


Thanks a lot.

May I ask what's the difference between this release and offical C1 release?

And how can I 'update' my C1 installation to this version? Simply copy & overwrite will probably break something I suppose?

burningice wrote Feb 12, 2015 at 11:01 AM

The Acto Build is a superset of the official C1, meaning that its 1:1 and 100% code and feature compatible.

Generally we try only to add features through the C1Contrib project, but sometimes changes to the core are necessary, ie. to support this feature request. Of other features implemented in the Acto Build these can be mentioned

burningice wrote Feb 24, 2015 at 11:52 AM

It looks like the feature is going to make it into the next release of C1 so stay tuned :)


elencala wrote Feb 26, 2015 at 8:10 AM


When could we expect to see a major release? ;)

mawtex wrote Feb 26, 2015 at 9:21 AM

We hope to push a very stable and feature complete beta within a week or two. And if we don't get any bad feedback we will likely release some weeks after.