Creating an iCalendar File

There are many cases when being able to generate a calender from one or more entities inside Nitride. It can be used to give an overview of past and future pages for posts, to ensure a full buffer of content to handle a vacation, or create a schedule from some metadata.

The iCalendar parsing and serialization comes from Ical.net.

Pipeline Setup

Most of the configuration for the operation comes with setup, using the variety of With* commands to set the value.

public class SitePipeline : PipelineBase
{
    private CreateCalendar createCalendear;

    public SitePipeline(CreateCalendar createCalendear)
    {
        this.createCalendar = createCalendar
            .WithCreateEvent(
				entity => new CalendarEvent
				{
					Summary = entity.Get<string>(),
				})
			.WithCreateCalendarEntity(
				(_calendar, text) => new Entity()
                    .Set(new UPath("/calendar.ics"))
					.SetTextContent(text));
    }
}

There are two required properties that must be set (either by setting the property or using the With* method):

  • CreateEvent takes an entity and create a calendar entry. If this returns null, then no entry will be added. It is recommended setting the Summary property at minimum. If a stable UID is wanted, then it also must be set here. The start, stop, and stamp do not have to be set as they will be after the object is returned.
  • CreateCalendarEntity is used to create the calendar file itself. If using path-based operations, it requires setting a UPath component but may include additional information.

There are some additional optional properties:

  • GetInstant: The callback method to get the NodaTime.Instant from the entity. This defaults to entity.GetOptional<Instant> but could be overridden as needed.
  • PostCreateEvent: A final callback called for each event after CreateEvent is called, the date times are set for start and stop, and the event is about to be added to the calendar.

Adding the Calendar

Calling the operation simply adds the calendar to the output stream.

    /// <inheritdoc />
    public override IAsyncEnumerable<Entity> RunAsync(
        IEnumerable<Entity> entities,
        CancellationToken cancellationToken = default
    )
    {
        return entities
            .Run(this.createCalendar, cancellationToken)
            .ToAsyncEnumerable();

        // The last item in the entities list has a UPath of
        // "/calendar.ics".
    }

Metadata

Project