Page 1 of 1

Can an article include another entry's body text?

Posted: Thu Jul 28, 2005 7:34 pm
by gwilsonmail
Is it possible to include the entry body text of one s9y entry in another entry?

I'm thinking of using one s9y blog to store some text entries that can then be included in an entry of another blog.

Thanks

Re: Can an article include another entry's body text?

Posted: Thu Jul 28, 2005 11:52 pm
by garvinhicking
You could write a plugin for that. Specifically, a markup plugin that reacts to:

Code: Select all

[s9y-include-entry:123:body]
(instead of "123" use your entryid, instead of "body" you can use any column of the entry)

Coding that would be not so hard. In fact I just committed the "includeentry" plugin to CVS:

Code: Select all

<?php

// Probe for a language include with constants. Still include defines later on, if some constants were missing
$probelang = dirname(__FILE__) . '/lang_' . $serendipity['lang'] . '.inc.php';
if (file_exists($probelang)) {
    include $probelang;
}

switch ($serendipity['lang']) {
    case 'de':
        @define('PLUGIN_EVENT_INCLUDEENTRY_NAME',     'Textformatierung: Eintragsdaten einfügen');
        @define('PLUGIN_EVENT_INCLUDEENTRY_DESC',     'Ermöglicht das Hinzufügen von HTML-ähnlichen Tags um Teile von anderen Einträgen einzubinden. Benutzen Sie folgende Formatierung: [s9y-include-entry:XXX:YYY]. Ersetzen Sie XXX mit der Ziel-ID des Eintrags und YYY mit dem Zielfeldnamen der Datenbank (z.B. "body", "extended", "title" usw.).');
        break;

    case 'en':
    case 'es':
    default:
        @define('PLUGIN_EVENT_INCLUDEENTRY_NAME',     'Markup: Include entry data');
        @define('PLUGIN_EVENT_INCLUDEENTRY_DESC',     'Allows you to add HTML-style tags to your entry that includes parts of other entrys. Use this markup: [s9y-include-entry:XXX:YYY]. Replace XXX with the target entryid and YYY with the target field name (i.e. "body", "title", "extended", ...).');
        break;
}


class serendipity_event_includeentry extends serendipity_event
{
    var $title = PLUGIN_EVENT_INCLUDEENTRY_NAME;

    function introspect(&$propbag)
    {
        global $serendipity;

        $propbag->add('name',          PLUGIN_EVENT_INCLUDEENTRY_NAME);
        $propbag->add('description',   PLUGIN_EVENT_INCLUDEENTRY_DESC);
        $propbag->add('stackable',     false);
        $propbag->add('author',        'Garvin Hicking');
        $propbag->add('version',       '1.0');
        $propbag->add('scrambles_true_content', true);
        $propbag->add('requirements',  array(
            'serendipity' => '0.8',
            'smarty'      => '2.6.7',
            'php'         => '4.1.0'
        ));
        $propbag->add('event_hooks',   array('frontend_display' => true));
        $propbag->add('groups', array('MARKUP'));

        $this->markup_elements = array(
            array(
              'name'     => 'ENTRY_BODY',
              'element'  => 'body',
            ),
            array(
              'name'     => 'EXTENDED_BODY',
              'element'  => 'extended',
            ),
            array(
              'name'     => 'COMMENT',
              'element'  => 'comment',
            ),
            array(
              'name'     => 'HTML_NUGGET',
              'element'  => 'html_nugget',
            )
        );

        $conf_array = array();
        foreach($this->markup_elements as $element) {
            $conf_array[] = $element['name'];
        }
        $propbag->add('configuration', $conf_array);
    }

    function introspect_config_item($name, &$propbag)
    {
        $propbag->add('type',        'boolean');
        $propbag->add('name',        constant($name));
        $propbag->add('description', sprintf(APPLY_MARKUP_TO, constant($name)));
        $propbag->add('default', 'true');
        return true;
    }

    function generate_content(&$title) {
        $title = $this->title;
    }

    function parse(&$element) {
        global $serendipity;
        
        $element = preg_replace_callback(
            "@\[s9y-include-entry:([0-9]+):?([^:]+)?\]@isUm",
            array($this, 'parseCallback'),
            $element
        );
        
        return true;
    }

    function parseCallback($buffer) {
        if (!isset($buffer[2]) || empty($buffer[2])) {
            $buffer[2] = 'body';
        }
        
        $id = (int)$buffer[1];
        
        $entry = serendipity_fetchEntry('id', $id);
        $newbuf = $entry[$buffer[2]];
        return $newbuf;
    }
    
    function event_hook($event, &$bag, &$eventData) {
        global $serendipity;

        $hooks = &$bag->get('event_hooks');

        if (isset($hooks[$event])) {
            switch($event) {
              case 'frontend_display':
                
                foreach ($this->markup_elements as $temp) {
                    if (serendipity_db_bool($this->get_config($temp['name'], true)) && isset($eventData[$temp['element']])) {
                        $element = $temp['element'];
                        $this->parse($eventData[$element]);
                    }
                }

                return true;
                break;

              default:
                return false;
            }

        } else {
            return false;
        }
    }
}

/* vim: set sts=4 ts=4 expandtab : */
?>

Posted: Wed Oct 26, 2005 11:05 pm
by judebert
Garvin,

I just updated this to allow you to include entry properties (instead of just entry columns). I wanted a link to a different entry from within my new entry; I used [s9y-include-entry:XXX:prop=permalink] to get it.

If there are any other entry properties (all that's in my database are permalinks, and they're mostly wrong), you could get them the same way: just use prop= in your s9y-include-entry markup.

Here's the modified .php file, in .zip format (sorry, I'm not at a facility where I can make it all pretty): http://judebert.com/wasted_youth/includeentry.zip

Posted: Wed Oct 26, 2005 11:16 pm
by garvinhicking
Hi Judebert!

Looks solid to me, I just committed it with a minor change (allow prop= and prop:). I also reverted your change of   to " " because in HTML all multi blanks are compressed to a single space. Hope that's fine for you :)

Best regards
Garvin

Posted: Thu Oct 27, 2005 3:12 am
by judebert
Oooh... I didn't even know the spaces had been escaped. It's that stupid tool I had to use behind the work^H^H^H^H uhh... library... yeah, library firewall.

I'm surprised prop: works. I originally wanted to do it that way, but I thought it was too much of a pain because we exploded that string on ':'.

Can't wait to see it!

Posted: Thu Oct 27, 2005 11:17 am
by garvinhicking
Oh, you might be right on that prop: thing then. I didn't properly investigate. :)

Pay attention to that firewall of yours ;-)

Regards,
Garvin