Google Calendar Plugin

google_cal plugin by Kite
Embeds a Google Calendar into a wiki page

Last updated on 2007-05-01. Provides Syntax.
No compatibility info given!

Similar to hcalendar.

Tagged with calendar, embed, google.

    This plugin integrates a Google Calendar into a DokuWiki page.

    With a serious nod to iframe by Christopher Smith. Minimal changes were made (improvements, I hope).

    Syntax

    {{cal>kite@puzzlers.org[614,640]|Kite's Test}}

    Pretty simple:

    • an email address with a shared/private calendar.
    • the [614,640] are width and height – these are both optional, but must be enclosed in [ , ] if present. If only one value is supplied, it is assumed to be the height.
    • the | marks the 'alternate text' used for a title; otherwise you get the default configured in Google.

    Configuration

    The plugin has one configuration setting, which can be set via the admin/configuration settings page.

    • $gcal_js_ok — default value - false, set to true to enable JavaScript URLs.
    • iframe by Christopher Smith uses $js_ok

    I don't know if it is better to allow one value for both plugins, or not. Also, due to the limited nature of this plugin, I don't think this option will actually make any difference. It has not been tested.

    Installation

    Be sure that, while cutting and pasting, no extra spaces or anything are before the <?PHP or after the ?> as this will cause errors while producing headers.

    Place this file in lib/plugins/google_cal/syntax.php (Updated 2010-02-08 for conformance notes).

    syntax.php
    <?php
    /**
     * Plugin google_cal: Inserts an Google Calendar iframe
     * 
     * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
     * @author     Kite <Kite@puzzlers.org>,  Christopher Smith <chris@jalakai.co.uk> 
     * @seealso    (http://www.dokuwiki.org/plugin:iframe)
     */
     
    if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
    if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
    require_once(DOKU_PLUGIN.'syntax.php');
     
    /**
     * All DokuWiki plugins to extend the parser/rendering mechanism
     * need to inherit from this class
     */
    class syntax_plugin_google_cal extends DokuWiki_Syntax_Plugin {
     
        function getInfo(){
          return array(
            'author1' => 'Kite',
            'email1'  => 'kite@puzzlers.org',
    		'author2' => 'Christopher Smith',
            'email2'  => 'chris@jalakai.co.uk',
            'date'   => '2007-05-01',
            'name'   => 'Google Calendar Plugin',
            'desc'   => 'Adds a Google Calendar iframe 
                         syntax: {{cal>name@address[w,h]|alternate text}}',
            'url'    => 'http://www.dokuwiki.org/plugin:google_cal',
          );
        }
     
        function getType() { return 'substition'; }
        function getPType(){ return 'block'; }
        function getSort() { return 305; }
        function connectTo($mode) { 
    		$this->Lexer->addSpecialPattern('{{cal>[^}]*?}}',$mode,'plugin_google_cal'); 
        }
     
        function handle($match, $state, $pos, &$handler){
     
    	if(preg_match('/{{cal>(.*)/', $match)) {             // Hook for future features
    	  // Handle the simplified style of calendar tag
    	  $match = html_entity_decode(substr($match, 6, -2));
    	  @list($url, $alt) = explode('|',$match,2);
    	  $matches=array();
    	// '/^\s*([^\[|]+)(?:\[(?:([^,\]]*),)?([^,\]]*)\])?(?:\s*(?:\|\s*(.*))?)?$/mD'
    	  if (preg_match('/(.*)\[(.*)\]$/',trim($url),$matches)) {
    		$url = $matches[1];
    		if (strpos($matches[2],',') !== false) {
    		  @list($w, $h) = explode(',',$matches[2],2);
              } else {
                   $h = $matches[2];
                   $w = '98%';
              }
            } else {
              $w = '98%';
    	  $h = '600';
            }
    	if (!isset($alt)) $alt = '';
     
    	if (!$this->getConf('js_ok') && substr($url,0,11) == 'javascript:') {
    	  	return array('error', $this->getLang('gcal_No_JS'));
    	}
    	return array('wiki', hsc(trim("$url")), hsc(trim($alt)), hsc(trim($w)), hsc(trim($h))); 
    	} else {
    	  return array('error', $this->getLang("gcal_Bad_iFrame"));  // this is an error
    	} // matched {{cal>...
        }
     
        function render($mode, &$renderer, $data) {
     
          list($style, $url, $alt, $w, $h) = $data;
          if($mode == 'xhtml'){
              // Two styles: wiki and error
    		  switch($style) {
              case 'wiki':
                $renderer->doc .= "<iframe src='http://www.google.com/calendar/embed?src=$url&amp;height=$h&amp;title=$alt'".
                    "title='$alt'  width='$w' height='$h' frameborder='0'></iframe>\n";
    	    break;
              case 'error':
                $renderer->doc .= "<div class='error'>$url</div>";
                break;
              default:
                $renderer->doc .= "<div class='error'>" . $this->getLang('gcal_Invalid_mode') . "</div>";
                break;
              }
              return true;
          }
          return false;
        }
    }
    ?>

    Place this file in lib/plugins/google_cal/conf/metadata.php

    metadata.php
    <?php
    /*
     * google_cal plugin, configuration metadata
     *
     * @author    Christopher Smith <chris@jalakai.co.uk>
     */
    $meta['gcal_js_ok']  = array('onoff');
    ?>

    Place this file in lib/plugins/google_cal/conf/default.php

    default.php
    <?php
    /*
     * google_cal plugin, default configuration settings
     *
     * @author    Christopher Smith <chris@jalakai.co.uk>
     */
    $conf['gcal_js_ok'] = false;
     
    ?>

    Languages

    Of course, you may need to translate these to your own locale. I prefer to make error messages relatively vague but unique so I can track them back to where the error was found without overloading a user with technical info they shouldn't have or want.

    Place this file in lib/plugins/google_cal/lang/en/lang.php

    lang.php
    <?php
    /**
     * English language file
     *
     * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
     * @author     kite <Kite@puzzlers.org>
     */
     
    $lang['gcal_Bad_calendar'] = 'Invalid Google Calendar request.';
    $lang['gcal_No_JS'] = 'The wiki can not display this calendar.';
    $lang['gcal_Invalid_mode'] = 'Google Calendar plugin error.';
     
    ?>

    Place this file in lib/plugins/google_cal/lang/en/settings.php

    settings.php
    <?php
    /**
     * English language file
     *
     * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
     * @author     Christopher Smith <chris@jalakai.co.uk>
     */
     
    // for the configuration manager
    $lang['gcal_js_ok']  = 'Allow JavaScript URLs';
     
    ?>

    Download

    Hi, I've translated the error messages to de_DE and uploaded it.

    Just unpack and use it =)

    regards Ferhat Dogru

    google_cal.zip

    Discussion

    First release posted April 26, 2007 by kite [at] puzzlers [dot] org.

    One improvement over iframe by Christopher Smith was the regular expression

    function connectTo($mode) { 
        $this->Lexer->addSpecialPattern('{{cal>[^}]*?}}',$mode,'plugin_google_cal'); 
    }

    By adding [^}]* the expression is prevented from crossing a boundary into another tag if, for example, you put two calendars on the same page. The lexer patterns are all greedy by nature so this is something I find needs to be in more plugins.

    The '?' after the '*' reverses the greediness of the quantifier — Christopher Smith 2007-08-26 12:02
    function getPType(){ return 'block'; }

    This method was added so that the plugin informs DokuWiki to close any <p> tags that are open before this plugin is called so the frame is not bound in a paragraph.

    I have several Google Calendars tied to my Gmail account. Is there a way to specify just one calendar, or a sub-group (i.e. 3 out of 5 calendars). — Jason 2007-06-08 18:51
    Same for me. I do have several calendars in my account and just some are shared… and I would like to have the specify which calendars should be visible.
       The quick answer is yes.  At the Google calendar webpage, click on manage calendars.  Then click on the particular calendar that you are
       interested in using.  In the Calendar Address box you should see a calendar id that looks like a randomly generated bunch of letters 
       @group.calendar.google.com.  Plug this in as the address instead of {{cal>yourname@gmail.com}}.  
       I.e. {{cal>[randomletters]@group.calendar.google.com}}.  Seems to be working for me.  Cheers.  
       Ethan Farquhar 2007-08-13
    Nice job ! It work fine ! Just one suggest : I choose different colors for several calendars (i.e. light green for one). I would like to recover the colour of the interested calendar !

    Nicolas 2007-24-08 15:26

    Re: Nicolas and Jason:
    I got this to work with iframes, both displaying multiple calendars and preserving my color choices! Here's how:
    I went to /my calendar/settings/, selected a calendar, and under “Embed this Calendar” section, I clicked “Customize the color, size, and other options”. This opens the editor for their »frame code. Select the calendars you want to display in the iframe, and the code will update.
    Remove this part:

    <iframe src="http://www.google.com/calendar/embed?height=600&amp;wkst=1&amp;bgcolor=%23FFFFFF&amp;


    That should leave you with “src=%your email address%…..etc.”, copy everything after “src=” all the way to the end of the Time Zone section.
    This should leave you with something like this:

         {{cal>myemailaddress%40gmail.com&amp;color=%231B887A&amp;src=xxxxrandomnumberhashxxxxxx%40group.calendar.google.com&amp;color=%232952A3&amp;src=xxxxrandomnumberhashxxxxxx%40group.calendar.google.com&amp;color=%23705770&amp;src=xxxxrandomnumberhashxxxxxx%40group.calendar.google.com&amp;color=%230D7813&amp;src=xxxxrandomnumberhashxxxxxx%40group.calendar.google.com&amp;color=%232952A3&amp;src=xxxxrandomnumberhashxxxxxx%40group.calendar.google.com&amp;color=%235229A3&amp;src=xxxxrandomnumberhashxxxxxx%40group.calendar.google.com&amp;color=%230D7813&amp;ctz=America%2FChicago[800,600]|It works!}}


    BrentDunnaway 2009-08-07 13:49

    Hi - I was wondering if it was possible to login to the calendar automatically when the page loads? Thanks - David
    Hi - Is there a working example somewhere ?

    XHTML Conformance

    IFrames element do not have an alt attribute, thus leading to validation errors. This is easily fixed in syntax.php replacing

                $renderer->doc .= "<iframe src='http://www.google.com/calendar/embed?src=$url&height=$h&title=$alt' ".
                    "alt='$alt' title='$alt'  width='$w' height='$h' frameborder='0'></iframe>\n";
    

    al line 80 by

                $renderer->doc .= "<iframe src='http://www.google.com/calendar/embed?src=$url&height=$h&title=$alt' ".
                    "title='$alt'  width='$w' height='$h' frameborder='0'></iframe>\n";
    

    Additionally, it is not permitted to have verbatim & in hrefs. They have to be encoded using the HTML entity &amp;. The previous line has to be altered further to read:

                $renderer->doc .= "<iframe src='http://www.google.com/calendar/embed?src=$url&amp;height=$h&amp;title=$alt'".
                    "title='$alt'  width='$w' height='$h' frameborder='0'></iframe>\n";
    
    Interesting notes; I've applied them to the source above. Kite 2010-02-08

    Future Directions

    • This should be able to cope with an <iframe…></iframe> from Google; wasn't able to make that work this time around due to some parsing and regular expression problems.
    • This should probably check the user's email but … since it has to go to Google's calendar engine anyway, I can rely on their response to be “reasonable” for now.
     
    plugin/google_cal.txt · Last modified: 2010/02/08 20:04 by 74.93.99.97
     
    Except where otherwise noted, content on this wiki is licensed under the following license:CC Attribution-Noncommercial-Share Alike 3.0 Unported
    Imprint Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki
    WikiForumIRCBugsGitXRefTranslate