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
submit()
This is the function called when submitting a post.
update($post)
This is the function called when updating a post.
title($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.
excerpt($post)
This returns the source for the excerpt. The truncation is handled by the caller.
feed_content($post)
This returns the content for a feed entry.
Utility Functions
__init()
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.
__install()
This function is called when the Feather is enabled.
__uninstall($confirm)
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->setField()
This sets a field for your feather, for use on Write/Edit pages.
function __init() {
    $this->setField(
        array(
            # 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(
                 array(
                     "name" => $name,
                     "value" => $value,
                     "selected" => true
                 )
            )
        )
    );
}
$this->setFilter()
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->customFilter()
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");
}
$this->respondTo()
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);
}