Anatomy of a Feather

Feathers enable Chyrp Lite to render different types of content in blog posts. Feathers are simply a class that extends the Feathers class and implements the Feather interface, named after the file and its containing directory (using camelization rules).

class CamelizedFolderName extends Feathers implements Feather {
    public function submit() {
        # Handles post submitting.

    public function update($post) {
        # Handles updating a post.

    public function title($post) {
        # Returns the appropriate source to be treated as a "title" of a post.

    public function excerpt($post) {
        # Returns the appropriate source, unmodified, to be used as an excerpt of a post.

    public function feed_content($post) {
        # Returns the appropriate content for a feed.

Feather Functions

Feathers have some functions required by their interface, and they can optionally implement several utility functions.

Interface Functions


This is the function called when submitting a post.


This is the function called when updating a post.


This function should return the most logical title for the post. If there is no obvious title field that you can return, use $post->title_from_excerpt() to generate one.


This returns the source for the excerpt. The truncation is handled by the caller.


This returns the content for a feed entry.

Utility Functions


This function is called after all modules and feathers are instantiated. This function is preferable to __construct() for interacting with the Chyrp Lite environment, because it will be called once every extension is ready to react to triggers.


This function is called when the Feather is enabled.


This function is called when the feather is disabled. If your feather has a confirm metadata item then the $confirm argument will be true if the user responded affirmatively.

Construct Functions

The Feathers class provides a few functions intended to be used in __construct() or __init():


This sets a field for your feather, for use on Write/Edit pages.

function __init() {
            # The name of the post attribute.
            "attr" => "body",

            # One of text, text_block, file, checkbox, select.
            "type" => "text_block",

            # The label for the field on the Write/Edit page.
            "label" => __("Body", "my_feather"),

            # If set, this will appear alongside the label.
            "note" => __("I am a note!", "my_feather"),

            # Can the field be blank?
            "optional" => true,

            # Can the field be previewed?
            "preview" => true,

            # For file fields: allow multiple files?
            "multiple" => false,

            # For file fields: accepted types.
            "accept" => ".jpg,.gif,.png",

            # For select fields: an array of options.
            "options" => array(
                     "name" => $name,
                     "value" => $value,
                     "selected" => true

This function is used for applying a filter to a given attribute. Filters will be stacked and executed in the order that they are specified, therefore it is usually preferable to specify specialised filters before general-purpose ones.

function __init() {
    $this->setFilter("body", array("markup_post_text", "markup_text"));

This function behaves much like setFilter(), but the second argument is the name of a public function in your feather. Custom filters will be executed before any filters added with setFilter().

function __init() {
    $this->customFilter("body", "my_filter_function");

Calling this sets your feather up to respond to a trigger like a module would. The optional third parameter is the numeric priority for your trigger responder; the default is 10.

function __init() {
    $this->respondTo("feed_item", "my_filter_function", 10);