Page 2 of 2

Re: Faked plugins for TEMPLATES.

Posted: Tue Jun 02, 2009 8:51 pm
by garvinhicking
Hi!
blog.brockha.us wrote:With this technique is it possible, to add extra config entries for plugins, too?
This would be nice.. I could implement some "tabbing" for the plugin display than.
Excuse me, what do you mean?
Could you give a code example for this, to make it easier to understand (for me), what it's all about, Garvin?
Did you have a look at my code example earlier in this thread?

Regards,
Garvin

Re: Faked plugins for TEMPLATES.

Posted: Thu Jan 28, 2010 6:37 pm
by Don Chambers
Garvin - I want to experiment with something, although its ultimate use is anything but certain.

First, do we have a current way to fetch a list of user groups? When creating or editing an entry, I want to experiment with saving one or more groups with the entry then altering what is displayed via entries.tpl based on those values....

I am just not sure how to proceed from here for the "faked plugin" concept, especially since the example earlier in this thread was for a radio button, not a multi select list.

I know, I know... I'm probably in for yet another self-imposed headache!!!! :wink:

EDIT: OK, I'm part way there... I can get the groups as:

Code: Select all

$groups = serendipity_getAllGroups();
echo '<select name="groups[]" multiple="multiple">';
foreach ($groups as $group) {
    echo '<option value="' . $group[id] . '">' . $group[name] . '</option>';
}
Now I just need to do this within the context of the "faked plugins".

Re: Faked plugins for TEMPLATES.

Posted: Fri Jan 29, 2010 9:56 am
by garvinhicking
Hi!

This is untested, but here an example of how to use a select field:

Code: Select all

<?php
// CODE EXAMPLE:  How to save custom field variables within the serendipity "Edit/Create Entry" backend.
//                Any custom variables can later be queried inside the .tpl files through
//                  {if $entry.properties.special_switch == 'true'}...{/if}
// NOTE THAT THE PROPERTY IS ACCED *WITHOUT* the ep_ prefix! EP_ only comes from entryproperties.

// Helper function to get the variable content of a variable (TRUE/FALSE)
function helper_get_value($special_key, &$eventData) {
    global $serendipity;
    $value = (isset($eventData['properties'][$special_key]) && serendipity_db_bool($eventData['properties'][$special_key]))
            || (isset($serendipity['POST']['properties'][$special_key]) && serendipity_db_bool($serendipity['POST']['properties'][$special_key]))
            ? true
            : false;

    return $value;
}

function helper_get_text_value($special_key, &$eventData) {
    global $serendipity;
    
    if (isset($eventData['properties'][$special_key])) return $eventData['properties'][$special_key];
    if (isset($serendipity['POST']['properties'][$special_key])) return $serendipity['POST']['properties'][$special_key];

    return false;
}

// Helper function to store form values into the serendipity database, so that they will be retrieved later.
function helper_store($special_key, $special_val, &$eventData) {
    global $serendipity;

    $q = "DELETE FROM {$serendipity['dbPrefix']}entryproperties WHERE entryid = " . (int)$eventData['id'] . " AND property = '" . serendipity_db_escape_string($special_key) . "'";
    serendipity_db_query($q);

    if (!empty($special_val)) {
        // If a multiselect is injected, we need to convert it to a database string.
        if (is_array($special_val)) {
            $special_val = implode('^', $special_val);
        }
        $q = "INSERT INTO {$serendipity['dbPrefix']}entryproperties (entryid, property, value) VALUES (" . (int)$eventData['id'] . ", '" . serendipity_db_escape_string($special_key) . "', '" . serendipity_db_escape_string($special_val) . "')";
        serendipity_db_query($q);
    }
}

function serendipity_plugin_api_pre_event_hook($event, &$bag, &$eventData, &$addData) {
    global $serendipity;

    // The name of the variable
    $special_key = 'special_switch';

    // Check what Event is coming in, only react to those we want.
    switch($event) {

        // Displaying the backend entry section
        case 'backend_display':
            // INFO: The whole 'entryproperties' injection is easiest to store any data you want. The entryproperties plugin
            // should actually not even be required to do this, as serendipity loads all properties regardless of the installed plugin

            // Check what our special key is set to (checks both POST data as well as the actual data)
            $special_value = helper_get_text_value($special_key, $eventData);

            // If the data comes from save, a multiple selection needs to be converted from a database string to an array.
            if (!is_array($special_value)) {
                $special_value = explode('^', $special_value);
            }

            // This is the actual HTML output on the backend screen.
            echo '<pre>' . print_r($eventData, true) . '</pre>';
            echo "Do you want this entry to be special? ";

            echo '<input type="radio" name="serendipity[properties][' . $special_key . ']" value="true" ' . ($is_special ? 'checked="checked"' : '') . ' id="' . $special_key . '_true">';
            echo '  <label for="' . $special_key . '_true">' . YES . '</label> ';

            echo '<input type="radio" name="serendipity[properties][' . $special_key . ']" value="false" ' . (!$is_special ? 'checked="checked"' : '')  . ' id="' . $special_key . '_false">';
            echo '  <label for="' . $special_key . '_false">' . NO . '</label> ';

            // HTML Select:
            echo '<select multiple="true" name="serendipity[properties][' . $special_key . ']">';
            // Setup an array with our values. It might also contain output from serendipity_getAuthorGroups or whatever.
            $data_array = array('key1' => 'value1', 'key2' => 'value2');
            foreach($data_array AS $data_array_key => $data_array_value) {
                echo '   <option value="' . $data_array_key . '" ' . (in_array($data_array_key, $special_value) ? 'selected="selected"' : '') . '>';
                echo '   ' . $data_array_value . '</option>';
            }
            echo '</select>';
            
            break;

        // To store the value of our entryproperties
        case 'backend_publish':
        case 'backend_save':

            // Call the helper function with all custom variables here.
            helper_store('special_switch', $serendipity['POST']['properties'][$special_key], $eventData);
            break;
    }

}

?>

Re: Faked plugins for TEMPLATES.

Posted: Fri Jan 29, 2010 3:37 pm
by Don Chambers
That's perfect Garvin! Thanks! Let me give that a try.

I know what I am experimenting with is probably not ideal for faked plugins... but this allows me to learn a bit, and test a concept. If it works as a template option (functionally and practically), then perhaps I can pursue an event plugin... with assistance, of course! :wink:

Re: Faked plugins for TEMPLATES.

Posted: Fri Jan 29, 2010 7:10 pm
by Don Chambers
For this multiselect, you have this:

Code: Select all

            helper_store('special_switch', $serendipity['POST']['properties'][$special_key], $eventData);
But for the radio button, you have this:

Code: Select all

            helper_store('special_switch', $serendipity['POST']['properties']['special_switch'], $eventData);
So, $special_Key, vs 'special_switch'... did you mean one or the other, or are they each correct for their respected purposes?

Still trying to understand the array stuff, will get back to you on that later.

Re: Faked plugins for TEMPLATES.

Posted: Mon Oct 10, 2011 10:00 am
by Timbalu
garvinhicking wrote:I'm having a hard time thinking of cool examples, but Judebert's got it right: Templates can "listen" to events and interface with anything, that previously only plugins could do. This makes templates much more stand-alone.

I still need to think some more about the absolute killer-feature so that you understand why this might be great. ;)
I just came across this very interesting thread. It looks somehow very exciting!

Did someone else or you, Garvin, found some more time to develop different examples, or just produce some more cool ideas on how to use this..., forcing entryproperties..., adding new config entries or hooks to existing plugins...., manipulate events and plugins..., etc. :?:

Re: Faked plugins for TEMPLATES.

Posted: Tue Oct 11, 2011 2:21 am
by Don Chambers
I used this exactly once, and had assistance achieving my need... I barely remember what we did, but could try and dig into it if you like.

Re: Faked plugins for TEMPLATES.

Posted: Tue Oct 11, 2011 9:15 am
by Timbalu
Well, yes. Thank you. I just thought it to be nice to have different solutions for unknown problems, I cant think of by now.

So starting thinking needs some ideas, what this can be about, to push me into the right direction.

When reading this thread, it appeared to me, everybody thought this was something real promising, but no really killer feature idea for the brighter masses arrived. Maybe that is why it was just some short flash and then stopped being worked out... :)

It would be sad it this possibility could not get used for something real creative and just kept sleeping like Rosebud in this forum. :wink:

Re: Faked plugins for TEMPLATES.

Posted: Wed Feb 20, 2013 1:57 pm
by onli
Is this Api still working? Could it be used to register the exernal_plugin-event in a config.inc.php of a template?

Re: Faked plugins for TEMPLATES.

Posted: Wed Feb 20, 2013 3:16 pm
by Don Chambers
The Kinetic template still uses this, but I have not tested Kinetic with the latest 1.7 RC... but I presume it is still working.

What are you trying to do?

Re: Faked plugins for TEMPLATES.

Posted: Wed Feb 20, 2013 3:23 pm
by onli
For the new backend, we want to pack the inline-js into separate files. This gets complicated when the js generated should use dynamic variables like the localisation, which was prior inserted into the js-code via the tpl.

So the idea was to smartify the javascript-files. With the hook, register the link to the js.tpl and let smarty output it there.

I found out that it doesn't work out of the box. Because when going to index.php?/plugin, the config.inc.php ist not read. That is changeable by inserting

Code: Select all

include(S9Y_INCLUDE_PATH . 'include/genpage.inc.php');
in line 403 of the index.php (the "if (preg_match(PAT_PLUGIN, $uri, $matches)) {"-part).

Still struggling to find a good way to pass variables from the .tpl (like the configuration.tpl) to a .js.tpl (which would then get called in the configuration.tpl as index.php?/plugin/*.js).

Re: Faked plugins for TEMPLATES.

Posted: Wed Feb 20, 2013 3:33 pm
by garvinhicking
Hi!

I don't think so; external_plugin is AFAIK routed without loading smarty or a template.

Adding that can lead to all sorts of problems, but mostly it will extremely slow down external_plugin, so this is not an option.

Actually I don't really think it's worth the hassle to outsource that. I know it's cleaner, but apart from that it only has drawbacks and complications.

REgards,
Garvin

Re: Faked plugins for TEMPLATES.

Posted: Wed Feb 20, 2013 4:24 pm
by onli
Adding that can lead to all sorts of problems, but mostly it will extremely slow down external_plugin, so this is not an option.
Not really. Of course, it seems obvious that loading the whole environment adds a lot of load. But the difference in my test is 10-20ms. Seems like most of the stuff apart from the template-data is loaded before and anyway.
That seems acceptable to me, especially since many plugins try to circumvent the external_plugin-event with the PATH-Option anyway.

For the bug-part: including genpage should differ a lot depending on the action, which could be set to empty and the danger thus minimized.

PS: Of course, an alternative is to add a new hook especially for that use-case, so external_plugin doesn't get touched.

Re: Faked plugins for TEMPLATES.

Posted: Mon Mar 04, 2013 4:25 pm
by onli
Note that I now simply went ahead and commited the inclusion of genpage for the external_plugin-event as part of a proof of concept. If the small performance hit really prevents that change from becoming permanent, i will add a specific hook or a mechanism outside of the plugin-api.