For Developers

The News & Blog Feed add-on works out of the box. This page is ment to give developers a guide on how to take advantage of the add-on functionality and to integrate their own custom blocks into the add-on. It is no programming needed what so ever to use the add-on.

The News & Blog Feed add-on offers a class called FeedEntry which gives you all the necessary tools to add a Feed Entry to any block you want, to create feed entries automaticly or to turn existing content into entries in bulk. It also provides the Feed class with some aditional functionality.

 

1. The FeedEntry class

2. How to turn a block into a feed entry

3. How to build an automatism for feed entry creation

4. Turning existing content into entries in bulk

5. The Feed class

 

1. The FeedEntry class


To load the class call: Loader::model('feed_entry', 'news_blog_feed');

Here are the functions of the class:

    /**
     * Checks for clipboard copies of a block.
     * Saves the result in global constants for the save function to pick them up.
     * Use it in the duplicate() function of a block controller.
     *
     * @param    $original_bID    the block id of the original block
     * @param    $new_bID        the block id of the duplicated block
     */

    public static function checkDuplicate($original_bID, $new_bID)

 

    /**
     * Saves a feed entry.
     * Use it in the save() function of a block controller.
     *
     * You can provide the arguments array of the block controller's save function or each value separately.
     * If you provide an arguments array, the anchor name has to be present in the array eather by using
     *
the editMenu() function of this class or by setting it manually by using
     *
the array key ["dm_news_blog_feed_anchor"]. The anchor name is also the entry name.
     * All other arguments array values are optional and can be set or overwritten by using the optional

     *
parameters of this function.
     * If provided a date string in $date, the string has to be parsable by PHP function strtotime().
     *
     * Checks the global constants set by checkDuplicate() and saves the block as a copy if necessary.
     *
     * @param    $bID            the block id
     * @param    $args_anchor    the form arguments as array or anchor name as string
     * @param    $headline        the headline (optional)
     * @param    $copy            the short copy (optional)
     * @param    $date            the date as timestamp or date picker string (optional, default is now)
     * @param    $offset            the offset of the feed entry (optional)
     * @param    $image            the file id of the image (optional)
     */

    public static function save($bID, $args_anchor, $headline = false, $copy = false, $date = false, $offset = false, $image = false)

 

    /**
     * Cleans up the feed entry data in the db tables after a feed entry block got deleted completely from the
     *
site.
Use it in the delete() function of a block controller.
     *
     * @param    $bID            the block id
     */    
    public static function delete($bID
)

 

    /**
     * Returns the feed entry data of a block as an object.
     * {date (Y-m-d), headline, copy, image, page_cID, anchor, offset, timestamp}

     *
     * @param    $bID    the id of the
block
     * @return    object / null
     */

    public static function data($bID)

 

    /**
     * Returns the feed entry anchor tag of a block.
     *
     * @param    $bID    the id of the block
     * @return    string
     */

    public static function anchorTag($bID)

 

     /**
     * Returns the edit form of a feed entry for an add or edit layer of a block.
     * You can defain which input fields will be shown.
     * Also provides the Javascript validation function dmValidateFeedEntry() which can be
     * called in the generall validation function ccmValidateBlockForm() of the auto.js file.
     *
     * @param    $bID            the id of the block
     * @param    $show_anchor    show the anchor field (optional, default is true)
     * @param    $show_headline    show the headline field (optional, default is true)
     * @param    $show_copy        show the copy field (optional, default is true)
     * @param    $show_date        show the date field (optional, default is true)
     * @param    $show_offset    show the offset field (optional, default is true)
     * @param    $show_image        show the image field (optional, default is true)
     * @return    string
     */
    public static function editForm($bID, $show_anchor = true, $show_headline = true, $show_copy = true, $show_date = true, $show_offset = true, $show_image = true)

 

    /**
     * Creates or updates a generic feed entry.
     * This function can be used to build an automatism for creating and/or updating feed entries on the fly.
     * The function is looking into the given area of the page and creates a generic entry in it if none exists
     * or updates the first entry it founds.
     *
     * The anchor is also the entry name.
     * If provided a date string in $date, the string has to be parsable by the PHP function strtotime().
     *
     * A created area is not showing on the page unless you actually place it in the template:

     *
$area->display($c); The area and the entry are connected to the page, no matter if the area
     *
is displayed on the page or not.
     *
     * @param    $page            the id of the page or the page object itself
     * @param    $area            the name of the area or the area object in which the entry is placied/updated
     * @param    $create_area    if $area is a string and it doesn't exit an area with this name, create it (bool)
     * @param    $update            should an already existing entry be updated (boolean)
     * @param    $anchor            the anchor name, has to be unique on the page
     * @param    $headline        the headline (optional)
     * @param    $copy            the short copy (optional)
     * @param    $date            the date as timestamp or date string (optional, default is now)
     * @param    $offset            the offset of the feed entry (optional)
     * @param    $image            the file id of the image (optional)
     */

    public static function automatedEntry($page, $area, $create_area, $update, $anchor, $headline = false, $copy = false, $date = false, $offset = false, $image = false)

 

    /**
     * Removes generic feed entries.
     * The function looks into the area of the page and deletes eather the first generic feed entry it finds

     *
or all.
     *

     *
All instances of the entry block are getting deleted.
     *
     * @param    $page            the id of the page or the page object itself
     * @param    $area            the name of the area or the area object itself
     * @param    $all            remove all generic feed entries in the area (optional, default is false)
     */

    public static function removeAutomatedEntry($page, $area, $all = false)

 


2. How to turn a block into a feed entry

As an example I'll show how to turn the standard content block into a blog or news post which will show up in a News or Blog Feed. We need to make a few changes in the blocks controller and view. Therefore create the blocks/content folder and put the files controller.php and view.php into it. The contents of these files are:

 

controller.php

<?php defined('C5_EXECUTE') or die("Access Denied.");

class ContentBlockController extends Concrete5_Controller_Block_Content {

    protected $btCacheBlockOutputForRegisteredUsers = false;
       
    public function save($args) {
       
        parent::save($args);
       
        $th = Loader::helper('text');
       
        Loader::model('feed_entry', 'news_blog_feed');
        FeedEntry::save($this->bID, "content_".$this->bID, 'A Content Blog', $th->sanitize($args['content'], 100));
    }

    public function duplicate($new_bID) {
       
        Loader::model('feed_entry', 'news_blog_feed');
        FeedEntry::checkDuplicate($this->bID, $new_bID);
   
        parent::duplicate($new_bID);
    }
   
    public function delete() {
      
        Loader::model('feed_entry', 'news_blog_feed');
        FeedEntry::delete($this->bID);
   
        parent::delete();
    }
       
}

 

view.php

<?php defined('C5_EXECUTE') or die("Access Denied.");

    Loader::model('feed_entry', 'news_blog_feed');
    print FeedEntry::anchorTag($bID);

    $content = $controller->getContent();
    print $content;

 

That's it. From now on each added content block creates also a Feed Entry. In order to work, you probably need to clear the cache and refresh the content block in the Block Types section of the Dashboard.

 

Let's have a look what is new in the two files. What you always do first is to load the model class.

In the save function of the controller you simply save the Feed Entry. To have an unique anchor name we use the block id to mark the anchor. You can use your own counter or a value out of the to be saved arguments. Everything is fine as long as the anchor name is unique on the page and fits the HTML name specifications. As headline we use a static phrase since the content block doesn't offer us a title. The copy gets shortened to 100 characters by using the text helper.
The parent save function is called in front of the feed entry save function in case the parent save function needs to do some work with its form values before saving and we are using one of its values (content).

In the duplicate function the block gets analyzed if it is a copy from the clipboard. If that step is missing, a copy would never loose its relation to the original block and if you would update a copied block, all appearances of the original block in a feed would be replaced by the copy and vice versa.

The delete function takes care of cleaning up the database entries after the block got deleted from the site.

The caching of the block output for registered users has to be turned off otherwise the information line of the feed entry in edit mode would be cached and also show up if the page is not in edit mode anymore.

In the view you just print out the anchor tag of the entry in front of the content of the block.


Even though the above example works just fine, it has two disadvantages. The anchor name, which is also the feed entry name, is always a generic name with a counter and the headline is always the same. It would be nice if the user could enter these values as well.

Luckily the class provides a function which creates the extra form values in the add and edit menu of the block. In order to use the function we must first copy the original files of the block which take care of the add and edit menu into our folder. You'll find the files in concrete/blocks/content. Copy add.php and edit.php into the folder blocks/content. Now append the following code to the end of each file:

<?php
    Loader::model('feed_entry', 'news_blog_feed');
    echo FeedEntry::editForm($bID, true, true, false);
?>

The function editForm(...) creates the feed entry form. It expects the block id as first parameter. All other parameters are optional and give you the possibility to define which values you actually ask for and which you provide by yourself. Since the copy of the content block will also be the copy of the feed entry we don't need to show the copy input field.

If you use the editForm(...) function, you don't have to set each value in the save(...) function anymore. The values will be already in the arguments array of the controller save function. You only have to set the values which you didn't ask for with the editForm(...) function. In our case the copy. So, change the code in the save function of the controller to:

        FeedEntry::save($this->bID, $args, false, $th->sanitize($args['content'], 100));

Now you provide also the feed entry input fields in the add and edit menu of the content block. But the validation for a unique anchor/entry name in the form is still missing. The editForm(...) function creates a Javascript function which can be used to do just that. Since the content block doesn't have a form validation in the first place you have to create the auto.js file in the folder blocks/content with the following content:

 

auto.js

ccmValidateBlockForm = function() {
    dmValidateFeedEntry();
    return false;
}


The function dmValidateFeedEntry() does the validation of the feed entry values. It gets called in the general block validation function ccmValidateBlockForm() provided by concrete5. If the block has already an auto.js file, copy the file in your folder as well and place the feed entry validation function in the general block validation function. If the auto.js function doesn't define a general function, append the above code to the end of the file.

The add-on comes with 7 content feed entry blocks which are all variations of content blocks providet by concrete5. These blocks are altered basicly in the way just described. So, there are plenty examples to look up.

 

3. How to build an automatism for feed entry creation

If you like to connect the use of a certain page type with the automated creation of a feed entry, you can use the automatedEntry(...) function. Place the function in the page type template and everytime a page of this type is created or viewed an entry gets created or updated.

The function is looking into the given area of the page and creates a generic entry in it if none exists or updates the first generic entry block it finds. You can also choose to create the area if it doesn't exist yet. If you do so, the area and its content (the entry) will be connected to the page but not displayed as long as you don't explicitly place the code for this into the template: $area->display($c);
You have the choice if you would like to hide the entry from the editor and have full controll over the content of the entry or if you like to place the entry into a displayed area where the editor can make adjustments to the entry. If the editor can edit the entry, you should set the update parameter of the function to false, otherwise the function will undo the editor's changes on the next page load.


Here an example of an automated feed entry which uses the page name as headline and its description as copy:

    Loader::model('feed_entry', 'news_blog_feed');
    FeedEntry::automatedEntry($c, 'Feed Entry', true, true, "automated", $c->getCollectionName(), $c->getCollectionDescription());


4. Turning existing content into entries in bulk

The function descriped in the previous chapter can also be used to create entries on already existing pages with just one page call. To do this you would place a little piece of code in one of your page type templates where the code is calling the function in a loop and iterates over the pages. Then just view a page of the page type to execute the code. After you are done, remove the code from the template again.


Here an example where all child pages of home would get an entry:

    Loader::model('feed_entry', 'news_blog_feed');
    $home = Page::getByID(1);
    $children = $home->getCollectionChildrenArray();
    for ($i = 0; $i < count($children); $i++) {
        $page = Page::getByID($children[$i], "ACTIVE");
        FeedEntry::automatedEntry($page, 'Feed Entry', true, true, "automated", $page->getCollectionName(), $page->getCollectionDescription());
    }


If you like to delete the entries again, you can use the removeAutomatedEntry(...) function:

    Loader::model('feed_entry', 'news_blog_feed');
    $home = Page::getByID(1);
    $children = $home->getCollectionChildrenArray();
    for ($i = 0; $i < count($children); $i++) {
        $page = Page::getByID($children[$i], "ACTIVE");
        FeedEntry::removeAutomatedEntry($page, 'Feed Entry');
    }


5. The Feed Class


To load the class call: Loader::model('feed', 'news_blog_feed');

Here are the functions of the class:

    /**
     * Returns the number of the entries which are in the scope of a feed.
     * The scope is defined by the selected pages of the feed and the date and age limit of the entries.
     *
     * To define a feed you have to provide the page where the feed is located. If more than one feed
     * is on the page, you can provide the order number of the feed. It defines if the feed is the first,
     * second, ... returned by concrete5. If you provide an area, the function will only look into this area
     * and the order number refers to the feeds in the area.
     *
     * The function is not considering scheduled guest access or viewing permissions of entries
     * nor timeframed pages.
     *
     * If entries are not viewable by the user because of scheduled guest access or viewing permissions,
     * the returned number will be off by the amount of these entries.
     *
     * In the case of timeframed pages (Version Online Time Schedule add-on), the function is only looking
     * for entries in the active version of a page. The returned number will be off by the difference between
     * the active version and the actual shown version.
     *
     * If the provided $page, $order_number or $area is not applicable, the function returns -1.
     *
     *
     * @param    $page   the id of the page or the page object itself where the feed is located
     * @param    $order_number    which feed on the page or in the area (optional, default 1)
     * @param    $area    the name of the area or the area object itself in which the feed is located (optional)
     * @return    integer
     */
    public static function getEntriesNumber($page, $order_number = 1, $area = null)