<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Linden LAN &#187; Google</title>
	<atom:link href="http://www.lindenlan.net/tag/google/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.lindenlan.net</link>
	<description></description>
	<lastBuildDate>Sat, 29 Nov 2014 04:54:20 +0000</lastBuildDate>
	<language>en-US</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	
	<item>
		<title>MyGoogleCal is now RESTYLEgc</title>
		<link>http://www.lindenlan.net/2009/07/06/mygooglecal-is-now-restylegc/</link>
		<comments>http://www.lindenlan.net/2009/07/06/mygooglecal-is-now-restylegc/#comments</comments>
		<pubDate>Mon, 06 Jul 2009 16:24:40 +0000</pubDate>
		<dc:creator><![CDATA[Admin]]></dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[RESTYLEgc]]></category>

		<guid isPermaLink="false">http://www.lindenlan.net/?p=323</guid>
		<description><![CDATA[I finally got around to spinning off MyGoogleCal as a separate website. I opted to rename the script to RESTYLEgc to avoid stepping on Google’s toes. It was something that’s been gestating over the past year. I completed the site over the holiday weekend since I had the time available. The new site is at [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>I finally got around to spinning off MyGoogleCal as a separate website.  I opted to rename the script to RESTYLEgc to avoid stepping on Google’s toes.  It was something that’s been gestating over the past year.  I completed the site over the holiday weekend since I had the time available.  The new site is at <a href="http://www.restylegc.com/">www.restylegc.com</a>.  I’m also hosting the script at <a href="http://code.google.com/p/restylegc">Google Code</a>, and I even added a <a href="http://groups.google.com/group/RESTYLEgc">Google Group</a> to facilitate discussions.  After seeing the comments top 100, I realize a blog really isn’t suitable for lengthy discussions.  Hopefully, the forum and wiki features will be better for the end-user.</p>
<p>I updated MyGoogleCal4 with a small bugfix this weekend as well.  That will be the last update.  Future development will continue with RESTYLEgc.  Since the code was originally public domain, I opted to go with an MIT open source license.  I also got the code in a Subversion repository which I should’ve done a long time ago.  With the Issues tab at Google Code, I can better track and encourage bug reports and feature requests.</p>
<p>The code is still free, but paid support is available.  I’ve also got some other ideas of where I want to take the site.  So stay tuned!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lindenlan.net/2009/07/06/mygooglecal-is-now-restylegc/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Restyle Google Calendar 4</title>
		<link>http://www.lindenlan.net/2008/12/04/restyle-google-calendar-4/</link>
		<comments>http://www.lindenlan.net/2008/12/04/restyle-google-calendar-4/#comments</comments>
		<pubDate>Thu, 04 Dec 2008 07:00:55 +0000</pubDate>
		<dc:creator><![CDATA[Brian]]></dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.lindenlan.net/?p=252</guid>
		<description><![CDATA[As a few users of MyGoogleCal3 have already pointed out, the script no longer works properly. That’s the bad news. The good news is version 4 does work. In fact, with the latest changes Google made to their code, ALL the features that were broken in 3 appear to be working now—Agenda/Week view, the calendar [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>As a few users of <a href="http://www.lindenlan.net/2008/04/23/restyle-google-calendar-3/">MyGoogleCal3</a> have already pointed out, the script no longer works properly.  That’s the bad news.  The good news is version 4 does work.  In fact, with the latest changes Google made to their code, ALL the features that were broken in 3 appear to be working now—Agenda/Week view, the calendar navigation buttons, and IE is fixed.   Please download and test out the latest version, and report any bugs in the comments and I’ll try to resolve them as time allows.</p>
<p><span id="more-252"></span><br />
<strong>UPDATE (2009 July 5):</strong> <a href="http://www.lindenlan.net/2009/07/06/mygooglecal-is-now-restylegc/">MyGoogleCal is now RESTYLEgc</a>.</p>
<p><strong>UPDATE (2009 June 23):</strong> Google’s recent update broke the jQuery injection.  In fact, the update is incompatible with injecting jQuery, Prototype, and MooTools.  The only JavaScript framework that works is Dojo.  I updated the code to inject that framework instead.  For those people who value stability over having the latest and greatest features, I also added a comment to MyGoogleCal4js.php that explains how to freeze the calendar version.  That should hopefully help all you fellow developers who tire of your clients calling you when their calendar breaks.</p>
<p><strong>UPDATE (2009 May 3):</strong> <span style="text-decoration: line-through;">MyGoogleCal4 now supports jQuery manipulation of the DOM.</span>  This gives the ability to apply styles after page load.  As an example, the default code removes the inline style on the body tag allowing the stylesheet to set the background color.  The default code also removes the width property from the inline style of the bubble class so that its width can be set in the stylesheet as well.  This should help overcome many of the problems that can’t be solved directly using a stylesheet.  You can thank <a href="http://techtriad.com/">TechTriad.com</a> for funding this new feature.</p>
<p>Download: <a href='http://www.lindenlan.net/wp-content/uploads/2008/12/mygooglecal4.zip'>mygooglecal4.zip</a>.  Contains MyGoogleCal4.php, MyGoogleCal4js.php, mygooglecal4.css, and images.  The CSS file is not guaranteed to be up-to-date so you may have to follow the instructions described in the PHP file to download the latest version from Google.  phpinfo.php is used for diagnostic purposes to make sure your PHP installation is working and that it has the required plugins.  In the archive folder, you can find previous versions of Google’s Javascript and CSS files, in case you want to use those (see MyGoogleCal4js.php).</p>
<pre class="brush: php">
&lt;?php
/*******************************************************************************
 * FILE: MyGoogleCal4.php
 *
 * DESCRIPTION:
 *  This script is an intermediary between an iframe and Google Calendar that
 *  allows you to override the default style.
 *
 * USAGE:
 *  &lt;iframe src=&quot;MyGoogleCal4.php?src=user%40domain.tld&quot;&gt;&lt;/iframe&gt;
 *
 *  where user@domain.tld is a valid Google Calendar account.
 *
 * VALID QUERY STRING PARAMETERS:
 *    title:         any valid url encoded string 
 *                   if not present, takes title from first src
 *    showTitle:     0 or 1 (default)
 *    showNav:       0 or 1 (default)
 *    showDate:      0 or 1 (default)
 *    showTabs:      0 or 1 (default)
 *    showCalendars: 0 or 1 (default)
 *    mode:          WEEK, MONTH (default), AGENDA
 *    height:        a positive integer (should be same height as iframe)
 *    wkst:          1 (Sun; default), 2 (Mon), or 7 (Sat)
 *    hl:            en, zh_TW, zh_CN, da, nl, en_GB, fi, fr, de, it, ja, ko, 
 *                   no, pl, pt_BR, ru, es, sv, tr
 *                   if not present, takes language from first src
 *    bgcolor:       url encoded hex color value, #FFFFFF (default)
 *    src:           url encoded Google Calendar account (required)
 *    color:         url encoded hex color value     
 *                   must immediately follow src
 *    
 *    The query string can contain multiple src/color pairs.  It&#039;s recommended 
 *    to have these pairs of query string parameters at the end of the query 
 *    string.
 *
 * HISTORY:
 *   03 December 2008 - Original release
 *                      Uses technique from MyGoogleCal2 for all browsers,
 *                      rather than giving IE special treatment.
 *   16 December 2008 - Modified MyGoogleCal4js.php so that the regex does a
 *                      general match rather than specifically look for the
 *                      variable &#039;Ac&#039;.
 *   Mar--Apr    2009 - Added jQuery for modifying the style after page load
 *   23 June     2009 - Replaced jQuery with Dojo since jQuery, Prototype, and
 *                      MooTools are not compatible
 *   05 July     2009 - Fixed bug to remove width style from bubble
 *                      
 *   
 * ACKNOWLEDGMENTS:
 *   Michael McCall (http://www.castlemccall.com/) for pointing out &quot;htmlembed&quot;
 *   Mike (http://mikahn.com/) for the link to the online CSS formatter
 *   TechTriad.com (http://techtriad.com/) for requesting and funding the 
 *       Javascript code to edit CSS properties and for selflessly letting the
 *       code be published for everyone&#039;s use and benefit.
 *   
 *
 * copyright (c) by Brian Gibson
 * email: bwg1974 yahoo com
 ******************************************************************************/

/* URL for overriding stylesheet
 * The best way to create this stylesheet is to 
 * 1) Load &quot;http://www.google.com/calendar/embed?src=user%40domain.tld&quot; in a
 *    browser,
 * 2) View the source (e.g., View-&gt;Page Source in Firefox),
 * 3) Copy the relative URL of the stylesheet (i.e., the href value of the 
 *    &lt;link&gt; tag), 
 * 4) Load the stylesheet in the browser by pasting the stylesheet URL into 
 *    the address bar so that it reads similar to:
 *    &quot;http://www.google.com/calendar/d003e2eff7c42eebf779ecbd527f1fe0embedcompiled.css&quot;
 * 5) Save the stylesheet (e.g., File-&gt;Save Page As in Firefox)
 * Edit this new file to change the style of the calendar.
 *
 * As an alternative method, take the URL you copied in Step 3, and paste it
 * in the URL field at http://mabblog.com/cssoptimizer/uncompress.html.
 * That site will automatically format the CSS so that it&#039;s easier to edit.
 */
$stylesheet = &#039;mygooglecal4.css&#039;;

/*******************************************************************************
 * DO NOT EDIT BELOW UNLESS YOU KNOW WHAT YOU&#039;RE DOING
 ******************************************************************************/

// URL for the calendar
$url = &quot;&quot;;
if(count($_GET) &gt; 0) {
  $url = &quot;http://www.google.com/calendar/embed?&quot; . $_SERVER[&#039;QUERY_STRING&#039;];
}

// Request the calendar
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$buffer = curl_exec($ch);
curl_close($ch);

// Point stylesheet and javascript to custom versions
$pattern = &#039;/(&lt;link.*&gt;)/&#039;;
$replacement = &#039;&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;&#039; . $stylesheet . &#039;&quot; /&gt;&#039;;
$buffer = preg_replace($pattern, $replacement, $buffer);

$pattern = &#039;/src=&quot;(.*js)&quot;/&#039;;
$replacement = &#039;src=&quot;MyGoogleCal4js.php?$1&quot;&#039;;  
$buffer = preg_replace($pattern, $replacement, $buffer);

// Add a hook to the window onload function
$pattern = &#039;/}\);}&lt;\/script&gt;/&#039;;
$replacement = &#039;}); myGoogleCal();}&lt;/script&gt;&#039;;
$buffer = preg_replace($pattern, $replacement, $buffer);

// Use DHTML to modify the DOM after the calendar loads
$pattern = &#039;/(&lt;\/head&gt;)/&#039;;
$replacement = &lt;&lt;&lt;MGC
&lt;script type=&quot;text/javascript&quot; src=&quot;http://ajax.googleapis.com/ajax/libs/dojo/1.3.1/dojo/dojo.xd.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
function myGoogleCal() {
    // remove inline style from body so background-color can be set using the stylesheet
    dojo.removeAttr(dojo.body(),&#039;style&#039;);

    // iterate over each bubble and remove the width property from the style attribute
    // so that the width can be set using the stylesheet
    dojo.query(&#039;.bubble&#039;).forEach(function(node){
        dojo.attr(node, {style:{&#039;width&#039;: &#039;&#039;}});
    });

    // see Dojo documentation for other ways to edit DOM
    // http://dojotoolkit.org/
}
&lt;/script&gt;
&lt;/head&gt;
MGC;
$buffer = preg_replace($pattern, $replacement, $buffer);

// display the calendar
print $buffer;
?&gt;

?&gt;
</pre>
<p>If you look at lines 39–41 in MyGoogleCal4js.php, you’ll see how simple the fix is.  No more XmlHttpRequest bugs.  Thank you, Google.</p>
<pre class="brush: php">
&lt;?php header(&quot;Content-type: application/x-javascript&quot;);
/*******************************************************************************
 * FILE: MyGoogleCal4js.php
 *
 * DESCRIPTION:
 *  Companion file for MyGoogleCal4.php to edit the javascript file that
 *  generates the Google Calendar.
 *   
 * USAGE:
 *  There are no user-editable parameters.
 *
 * copyright (c) by Brian Gibson
 * email: bwg1974 yahoo com
 ******************************************************************************/
// URL for the javascript
$url = &quot;&quot;;
if(count($_GET) &gt; 0) {
  $url = &quot;http://www.google.com/calendar/&quot; . $_SERVER[&#039;QUERY_STRING&#039;];
}

/* If you would like to freeze the calendar version, download the Javascript
 * file using the same method for downloading the CSS file, as described in
 * the main script.  You can find some previous versions in the archive folder.
 * NOTE: You should use the corresponding CSS file as well.
 *
 * Edit and uncomment the following line to freeze the calendar version.
 */
//$url = &quot;http://myserver.tld/path/to/archive/6a3eb8ba4a07edb76f79a18d6bdb8933embedcompiled__en.js&quot;;

// Request the javascript
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$buffer = curl_exec($ch);
curl_close($ch);

// Fix URLs in the javascript
$pattern = &#039;/this\.[a-zA-Z]{2}\+&quot;calendar/&#039;;
$replacement = &#039;&quot;http://www.google.com/calendar&#039;;
$buffer = preg_replace($pattern, $replacement, $buffer);

// Display the javascript
print $buffer;
?&gt;
</pre>
<p>The installation of MyGoogleCal4 is the same as the <a href="http://www.lindenlan.net/2008/03/22/how-to-install-mygooglecal2php/">installation for MyGoogleCal2</a> except you download the zip file above.  You can ignore step 3 regarding the .htaccess file.  As far as I can tell, it’s no longer needed.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lindenlan.net/2008/12/04/restyle-google-calendar-4/feed/</wfw:commentRss>
		<slash:comments>134</slash:comments>
		</item>
		<item>
		<title>Restyle Google Calendar 3</title>
		<link>http://www.lindenlan.net/2008/04/23/restyle-google-calendar-3/</link>
		<comments>http://www.lindenlan.net/2008/04/23/restyle-google-calendar-3/#comments</comments>
		<pubDate>Thu, 24 Apr 2008 05:46:09 +0000</pubDate>
		<dc:creator><![CDATA[Brian]]></dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.lindenlan.net/2008/04/23/restyle-google-calendar-3/</guid>
		<description><![CDATA[MyGoogleCal2 no longer works 100% in Internet Explorer. A runtime error occurs when navigating month-to-month or when switching to Agenda mode. The workaround is to simply hide the navigation interface. Now, I don’t know if this bug was introduced when Google updated the code last month, or if it’s always been there and I just [&#8230;]]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.lindenlan.net/2007/10/14/restyle-google-calendar-2/">MyGoogleCal2</a> no longer works 100% in Internet Explorer.  A runtime error occurs when navigating month-to-month or when switching to Agenda mode.  The workaround is to simply hide the navigation interface.  Now, I don’t know if this bug was introduced when Google updated the code last month, or if it’s always been there and I just never noticed.  In any case, the runtime error occurs when <code>//"+a.host+"/calendar</code> is replaced by <code>//www.google.com/calendar</code>.  Given the poor debugging available in IE, I didn’t get very far with figuring out why IE breaks.  I suspect that when IE makes an XmlHttpRequest, it’s double checking that the request URL matches up with the server host, or something to that effect.  Since Google obfuscates the Javascript code, it’s just way too hard to try and fix it.  Instead, I’ve opted to create a new version of MyGoogleCal that uses the <a href="http://www.lindenlan.net/2006/10/08/restyle-google-calendar/">original technique</a> for IE but uses the technique from MyGoogleCal2 for all other browsers.</p>
<p><span id="more-57"></span></p>
<p><strong>UPDATE:</strong> MyGoogleCal now has a <a href="http://www.lindenlan.net/2008/12/04/restyle-google-calendar-4/">fourth version</a>.</p>
<p>Download: <a href='http://www.lindenlan.net/wp-content/uploads/2008/04/mygooglecal3.zip' title='MyGoogleCal3 Zip file'>mygooglecal3.zip</a>.  Contains MyGoogleCal3.php, MyGoogleCal3js.php, mygooglecal3.css, mygooglecal3ie.css, and an .htaccess file.  The CSS files are not guaranteed to be up-to-date so you may have to follow the instructions described in the PHP file to download the latest version from Google.</p>
<pre class="brush: php">
&lt;?php
/*******************************************************************************
 * FILE: MyGoogleCal3.php
 *
 * DESCRIPTION:
 *  This script is an intermediary between an iframe and Google Calendar that
 *  allows you to override the default style.
 *
 * USAGE:
 *  &lt;iframe src=&quot;MyGoogleCal3.php?src=user%40domain.tld&quot;&gt;&lt;/iframe&gt;
 *
 *  where user@domain.tld is a valid Google Calendar account.
 *
 * VALID QUERY STRING PARAMETERS:
 *    title:         any valid url encoded string 
 *                   if not present, takes title from first src
 *    showTitle:     0 or 1 (default)
 *    showNav:       0 or 1 (default)
 *    showDate:      0 or 1 (default)
 *    showTabs:      0 or 1 (default)
 *    showCalendars: 0 or 1 (default)
 *    mode:          WEEK, MONTH (default), AGENDA
 *    height:        a positive integer (should be same height as iframe)
 *    wkst:          1 (Sun; default), 2 (Mon), or 7 (Sat)
 *    hl:            en, zh_TW, zh_CN, da, nl, en_GB, fi, fr, de, it, ja, ko, 
 *                   no, pl, pt_BR, ru, es, sv, tr
 *                   if not present, takes language from first src
 *    bgcolor:       url encoded hex color value, #FFFFFF (default)
 *    src:           url encoded Google Calendar account (required)
 *    color:         url encoded hex color value     
 *                   must immediately follow src
 *    
 *    The query string can contain multiple src/color pairs.  It&#039;s recommended 
 *    to have these pairs of query string parameters at the end of the query 
 *    string.
 *
 * HISTORY:
 *   21 June     2008 - Reverted to an older custom JavaScript file
 *   18 May      2008 - Corrected a bunch of typos 
 *   24 April    2008 - Original release
 *                      Uses the technique from MyGoogleCal for IE browsers and
 *                      the technique from MyGoogleCal2 for the rest.
 *   
 * ACKNOWLEDGMENTS:
 *   Michael McCall (http://www.castlemccall.com/) for pointing out &quot;htmlembed&quot;
 *   Mike (http://mikahn.com/) for the link to the online CSS formatter
 *
 * copyright (c) by Brian Gibson
 * email: bwg1974 yahoo com
 ******************************************************************************/

/* URL for overriding stylesheet
 * The best way to create this stylesheet is to 
 * 1) Load &quot;http://www.google.com/calendar/embed?src=user%40domain.tld&quot; in a
 *    browser,
 * 2) View the source (e.g., View-&gt;Page Source in Firefox),
 * 3) Copy the relative URL of the stylesheet (i.e., the href value of the 
 *    &lt;link&gt; tag), 
 * 4) Load the stylesheet in the browser by pasting the stylesheet URL into 
 *    the address bar so that it reads similar to:
 *    &quot;http://www.google.com/calendar/embed/d003e2eff7c42eebf779ecbd527f1fe0embedcompiled.css&quot;
 * 5) Save the stylesheet (e.g., File-&gt;Save Page As in Firefox)
 * Edit this new file to change the style of the calendar.
 *
 * As an alternative method, take the URL you copied in Step 3, and paste it
 * in the URL field at http://mabblog.com/cssoptimizer/uncompress.html.
 * That site will automatically format the CSS so that it&#039;s easier to edit.
 */
$stylesheet = &#039;mygooglecal3.css&#039;;

/* For the IE stylesheet replace &quot;embed&quot; with &quot;htmlembed&quot; in step (1) 
 */
$stylesheet_ie = &#039;mygooglecal3ie.css&#039;;

/*******************************************************************************
 * DO NOT EDIT BELOW UNLESS YOU KNOW WHAT YOU&#039;RE DOING
 ******************************************************************************/

// URL for the calendar
$url = &quot;&quot;;
$is_ie = FALSE;
if(count($_GET) &gt; 0) {
  if(stristr($_SERVER[&#039;HTTP_USER_AGENT&#039;], &#039;msie&#039;) === FALSE) {
    $url = &quot;http://www.google.com/calendar/embed?&quot; . $_SERVER[&#039;QUERY_STRING&#039;];
  } else {
    $url = &quot;http://www.google.com/calendar/htmlembed?&quot; . $_SERVER[&#039;QUERY_STRING&#039;];
    $is_ie = TRUE;
  }
}

// Request the calendar
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$buffer = curl_exec($ch);
curl_close($ch);

if($is_ie) {
  // Fix hrefs, image sources, and stylesheet
  $pattern = &#039;/(href=&quot;render)/&#039;;
  $replacement = &#039;href=&quot;http://www.google.com/calendar/render&#039;;
  $buffer = preg_replace($pattern, $replacement, $buffer);

  $pattern = &#039;/(href=&quot;event)/&#039;;
  $replacement = &#039;href=&quot;http://www.google.com/calendar/event&#039;;
  $buffer = preg_replace($pattern, $replacement, $buffer);

  $pattern = &#039;/(http:\/\/www.google.com\/calendar\/htmlembed)/&#039;;
  $replacement = &#039;MyGoogleCal3.php&#039;;
  $buffer = preg_replace($pattern, $replacement, $buffer);

  $pattern = &#039;/(src=&quot;images)/&#039;;
  $replacement = &#039;src=&quot;http://www.google.com/calendar/images&#039;;
  $buffer = preg_replace($pattern, $replacement, $buffer);

  $pattern = &#039;/(&lt;link.*&gt;)/&#039;;
  $replacement = &#039;&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;&#039; . $stylesheet_ie . &#039;&quot; /&gt;&#039;;
  $buffer = preg_replace($pattern, $replacement, $buffer);
} else {
  // Point stylesheet and javascript to custom versions
  $pattern = &#039;/(&lt;link.*&gt;)/&#039;;
  $replacement = &#039;&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;&#039; . $stylesheet . &#039;&quot; /&gt;&#039;;
  $buffer = preg_replace($pattern, $replacement, $buffer);

  $pattern = &#039;/src=&quot;(.*js)&quot;/&#039;;
  $replacement = &#039;src=&quot;MyGoogleCal3js.php?$1&quot;&#039;;
  $buffer = preg_replace($pattern, $replacement, $buffer);
}

// display the calendar
print $buffer;
?&gt;
</pre>
<p>The installation of MyGoogleCal3 is more or less the same as the <a href="http://www.lindenlan.net/2008/03/22/how-to-install-mygooglecal2php/">installation for MyGoogleCal2</a> except you download the zip file above.  Also MyGoogleCal3 uses two stylesheets, one for IE and one for all the other browsers.</p>
<p>There is a minor bug.  Despite changing the URL from <code>../images/ext/poweredby.png</code> to <code>images/poweredby.png</code> in the IE CSS file, this does not make the Powered by Google logo appear in the lower right.  I think that’s OK since it doesn’t appear on Google’s site either.</p>
<p><strong>Update (21 Jun 2008):</strong> Google changed the JavaScript once again and this time very radically.  I’ve been keeping snapshots of their JavaScript code, so I’ve changed the script to load an older customized .js file.  This is a quick fix.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lindenlan.net/2008/04/23/restyle-google-calendar-3/feed/</wfw:commentRss>
		<slash:comments>35</slash:comments>
		</item>
		<item>
		<title>How To Install MyGoogleCal2.php</title>
		<link>http://www.lindenlan.net/2008/03/22/how-to-install-mygooglecal2php/</link>
		<comments>http://www.lindenlan.net/2008/03/22/how-to-install-mygooglecal2php/#comments</comments>
		<pubDate>Sun, 23 Mar 2008 05:12:37 +0000</pubDate>
		<dc:creator><![CDATA[Brian]]></dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.lindenlan.net/2008/03/22/how-to-install-mygooglecal2php/</guid>
		<description><![CDATA[One of my readers asked for a step-by-step set of instructions to install MyGoogleCal2.php. My original posts for restyling Google Calendar did assume a certain level of expertise. This should hopefully help those who are still confused. Download mygooglecal2.zip. Unzip the file on your server, typically into a subfolder named ‘mygooglecal’. If your web server [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>One of my readers asked for a step-by-step set of instructions to install <a href="http://www.lindenlan.net/2007/10/14/restyle-google-calendar-2/">MyGoogleCal2.php</a>.  My original posts for restyling Google Calendar did assume a certain level of expertise.  This should hopefully help those who are still confused.</p>
<p><span id="more-54"></span></p>
<ol>
<li>
<p>Download <a href='http://www.lindenlan.net/wp-content/uploads/2007/10/mygooglecal2.zip' title='MyGoogleCal2 zip file'>mygooglecal2.zip</a>.</p>
</li>
<li>
<p>Unzip the file on your server, typically into a subfolder named ‘mygooglecal’.</p>
</li>
<li>
<p>If your web server supports .htaccess files and your site does not already have one, just move the .htaccess file that was in the zip file to the root of your site.  If your web site already has an .htaccess file, then you will need to copy the mod_rewrite rules from the the zip file’s .htaccess file to the existing one.</p>
</li>
<li>
<p>If you have not already done so, go to the <a href="http://www.google.com/calendar/embed/EmbedHelper_en.html">Embeddable Calendar Helper</a> and generate the HTML code for the calendar.  Place this code into the page that will display the calendar.</p>
</li>
<li>
<p>The HTML code for the Google Calendar is an &lt;iframe&gt; tag.  You need to edit the src attribute to point to MyGoogleCal2.php <em>on your server</em> and not http://www.google.com/calendar/embed.  See ‘USAGE:’ in the MyGoogleCal2.php file for an example.</p>
</li>
<li>
<p>That’s the basic installation.  You should be able to edit the included CSS file.  If you want to use a different CSS file or move it somewhere else, make sure to update the $stylesheet variable in MyGoogleCal2.php.  Remember, the CSS file is not guaranteed to be up-to-date so you may have to download your own copy.  Just follow the directions listed in MyGoogleCal2.php.</p>
</li>
</ol>
<p>Some additional notes:</p>
<ul>
<li>
<p>Some of the colors that the Google Calendar uses are: #c3d9ff, #bcd, #cde, #e8eef7, #e5ecf9, and #112abb.  That should help when editing the CSS file.  I highly recommend using Firefox and the <a href="https://addons.mozilla.org/en-US/firefox/addon/1843">Firebug extension</a>.  The extension has an Inspect feature that let’s you select a DOM object and see its element ID, class, and style attributes.  That will help identify which CSS rule you need change.</p>
</li>
<li>
<p>If the display of the calendar is blank, that usually means your PHP configuration is wrong and most likely the curl module is not installed or disabled.  Open the phpinfo.php file included in the zip file.  This will list a bunch of debug information about your web server’s PHP configuration.  If you do not see curl listed or curl is listed but disabled, then you will need to talk to your system administrator to fix it.</p>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.lindenlan.net/2008/03/22/how-to-install-mygooglecal2php/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Calendar Casting Call</title>
		<link>http://www.lindenlan.net/2008/01/10/calendar-casting-call/</link>
		<comments>http://www.lindenlan.net/2008/01/10/calendar-casting-call/#comments</comments>
		<pubDate>Fri, 11 Jan 2008 02:51:24 +0000</pubDate>
		<dc:creator><![CDATA[Brian]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Hacking]]></category>

		<guid isPermaLink="false">http://www.lindenlan.net/2008/01/10/calendar-casting-call/</guid>
		<description><![CDATA[Did you restyle your embedded Google Calendar using MyGoogleCal? Maybe you’ve restyled Google Calendar Gadget by following my instructions to modify the XML configuration? Do you want to show off how you integrated your calendar into your site? Just leave a URL comment with a link to your web site.]]></description>
				<content:encoded><![CDATA[<p>Did you restyle your embedded Google Calendar using <a href="http://www.lindenlan.net/2007/10/14/restyle-google-calendar-2/">MyGoogleCal</a>?  Maybe you’ve <a href="http://www.lindenlan.net/2007/06/18/restyle-google-calendar-gadget/">restyled Google Calendar Gadget</a> by following my instructions to modify the XML configuration?  Do you want to show off how you integrated your calendar into your site?  Just leave a URL comment with a link to your web site.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lindenlan.net/2008/01/10/calendar-casting-call/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Restyle Google Calendar 2</title>
		<link>http://www.lindenlan.net/2007/10/14/restyle-google-calendar-2/</link>
		<comments>http://www.lindenlan.net/2007/10/14/restyle-google-calendar-2/#comments</comments>
		<pubDate>Mon, 15 Oct 2007 04:38:54 +0000</pubDate>
		<dc:creator><![CDATA[Brian]]></dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.lindenlan.net/2007/10/14/restyle-google-calendar-2/</guid>
		<description><![CDATA[The long awaited new version of MyGoogleCal is here. It supports the new AJAX-enabled Javascript method Google switched to last month. As a bonus, the new version has native support for multiple calendars each with their own colors! Other changes to the code include officially switching from fopen to curl to retrieve the data. Furthermore, [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>The long awaited new version of <a href="http://www.lindenlan.net/2006/10/08/restyle-google-calendar/">MyGoogleCal</a> is here.  It supports the new AJAX-enabled Javascript method Google switched to last month.  As a bonus, the new version has native support for multiple calendars each with their own colors!  Other changes to the code include officially switching from fopen to curl to retrieve the data.  Furthermore, the code replaces much less HTML since it’s encapsulated in Javascript.  Without further ado…</p>
<p><span id="more-39"></span></p>
<p><strong>UPDATE:</strong> MyGoogleCal now has a <a href="http://www.lindenlan.net/2008/04/23/restyle-google-calendar-3/">third version</a>.</p>
<p>Download: <a href='http://www.lindenlan.net/wp-content/uploads/2007/10/mygooglecal2.zip' title='mygooglecal2.zip'>mygooglecal2.zip</a>.  Contains MyGoogleCal2.php, mygooglecal2.css, MyGoogleCal2js.php, and an .htaccess file.  The CSS file is not guaranteed to be up-to-date so you may have to follow the instructions described in the PHP file to download the latest version from Google.</p>
<pre class="brush: php">
&lt;?php
/*******************************************************************************
 * FILE: MyGoogleCal2.php
 *
 * DESCRIPTION:
 *  This script is an intermediary between an iframe and Google Calendar that
 *  allows you to override the default style.
 *
 * USAGE:
 *  &lt;iframe src=&quot;MyGoogleCal2.php?src=user%40domain.tld&quot;&gt;&lt;/iframe&gt;
 *
 *  where user@domain.tld is a valid Google Calendar account.
 *
 * VALID QUERY STRING PARAMETERS:
 *    title:         any valid url encoded string 
 *                   if not present, takes title from first src
 *    showTitle:     0 or 1 (default)
 *    showNav:       0 or 1 (default)
 *    showDate:      0 or 1 (default)
 *    showTabs:      0 or 1 (default)
 *    showCalendars: 0 or 1 (default)
 *    mode:          WEEK, MONTH (default), AGENDA
 *    height:        a positive integer (should be same height as iframe)
 *    wkst:          1 (Sun; default), 2 (Mon), or 7 (Sat)
 *    hl:            en, zh_TW, zh_CN, da, nl, en_GB, fi, fr, de, it, ja, ko, 
 *                   no, pl, pt_BR, ru, es, sv, tr
 *                   if not present, takes language from first src
 *    bgcolor:       url encoded hex color value, #FFFFFF (default)
 *    src:           url encoded Google Calendar account (required)
 *    color:         url encoded hex color value     
 *                   must immediately follow src
 *    
 *    The query string can contain multiple src/color pairs.  It&#039;s recommended 
 *    to have these pairs of query string parameters at the end of the query 
 *    string.
 *
 * HISTORY:
 *   22 March    2008 - Replaced the custom javascript with a PHP script that 
 *                      uses the same technique as MyGoogleCal.php
 *   14 March    2008 - Update to match Google changes to javascript code
 *   14 January  2008 - Fixed Add to Calendar URL to point to Google
 *    3 January  2008 - Reverted back to customized javascript code to fix
 *                      bug where no data is displayed when navigating
 *                      into future or past
 *                      Note: imported calendars (e.g. iCal) should work again
 *   29 October  2007 - Update to match Google changes to javascript code
 *                      Note: imported calendars (e.g. iCal) do not work
 *   14 October  2007 - Original release
 *   
 * copyright (c) by Brian Gibson
 * email: bwg1974 yahoo com
 ******************************************************************************/

/* URL for overriding stylesheet
 * The best way to create this stylesheet is to 
 * 1) Load &quot;http://www.google.com/calendar/embed?src=user%40domain.tld&quot; in a
 *    browser,
 * 2) View the source (e.g., View-&gt;Page Source in Firefox),
 * 3) Copy the relative URL of the stylesheet (i.e., the href value of the 
 *    &lt;link&gt; tag), 
 * 4) Load the stylesheet in the browser by pasting the stylesheet URL into 
 *    the address bar so that it reads similar to:
 *    &quot;http://www.google.com/calendar/embed/d003e2eff7c42eebf779ecbd527f1fe0embedcompiled.css&quot;
 * 5) Save the stylesheet (e.g., File-&gt;Save Page As in Firefox)
 * Edit this new file to change the style of the calendar.
 *
 * As an alternative method, take the URL you copied in Step 3, and paste it
 * in the URL field at http://mabblog.com/cssoptimizer/uncompress.html.
 * That site will automatically format the CSS so that&#039;s more easily editable.
 */
$stylesheet = &#039;mygooglecal2.css&#039;;

/*******************************************************************************
 * DO NOT EDIT BELOW UNLESS YOU KNOW WHAT YOU&#039;RE DOING
 ******************************************************************************/

// URL for the calendar
$url = &quot;&quot;;
if(count($_GET) &gt; 0) {
  $url = &quot;http://www.google.com/calendar/embed?&quot; . $_SERVER[&#039;QUERY_STRING&#039;];
}

// Request the calendar
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$buffer = curl_exec($ch);
curl_close($ch);

// Point stylesheet and javascript to custom versions
$pattern = &#039;/(&lt;link.*&gt;)/&#039;;
$replacement = &#039;&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;&#039; . $stylesheet . &#039;&quot; /&gt;&#039;;
$buffer = preg_replace($pattern, $replacement, $buffer);

$pattern = &#039;/src=&quot;(.*js)&quot;/&#039;;
$replacement = &#039;src=&quot;MyGoogleCal2js.php?$1&quot;&#039;;
$buffer = preg_replace($pattern, $replacement, $buffer);

// display the calendar
print $buffer;
?&gt;
</pre>
<p>Use is similar to the original MyGoogleCal.php.  To help create the &lt;iframe&gt;, you can use the <a href="http://www.google.com/calendar/embed/EmbedHelper_en.html">Embeddable Calendar Helper</a>.  Just remember to update the src attribute to point to MyGoogleCal2.php and not http://www.google.com/calendar/embed.  </p>
<p><span style="text-decoration: line-through;">In addition to a custom CSS file the script makes use of a custom Javascript file.  Each URL is set after the script’s header and includes instructions on how to download versions of these files from Google.  This is important since it appears that the Javascript file is localized.  (I included copies that I downloaded in the above Zip file.)</span> </p>
<p><strong>Update (22 Mar 08):</strong> I created a new PHP file, MyGoogleCal2js.php, which downloads the JavaScript code and edits the code on-the-fly.  This negates the need to maintain a customized version of the JavaScript code on the same server as the MyGoogleCal.php script.   This should also lessen the chance that MyGoogleCal2.php will break when Google updates the code as long as the changes are minor.</p>
<p>The UI images are no longer contained in the CSS file.  You have two options on how to handle this.  If your site runs off of Apache, you can create a rewrite rule to hotlink to the Google images.  (I included an .htaccess file in the Zip file above that has a sample rule.)  The other, more conventional option is to create an “images” subfolder where the script is located and place copies of these images there.  You will definitely have to do this if you want to replace those images with customized versions. (I included images in the Zip file.)</p>
<p>What I’m hung-up on right now is figuring out a way to not have to save and rewrite the Javascript file.  The Javascript file is responsible for drawing the calendar, retrieving the XML data from Google, and then putting that data into the calendar.   The <code>_init()</code> function dynamically creates the URL from which to retrieve the XML data by using the browser’s window.location.host property.  Since the browser will presumably be pointing to your site, the host property will not be www.google.com.  As a result, the Javascript <span style="text-decoration: line-through;">hangs at the XML loading stage</span> fails to retrieve data when navigating into the future or past.  My attempts at circumventing this problem has been met with little success.</p>
<p>I tried the passthru directive in .htaccess file like so:</p>
<pre class="brush: xhtml">
RewriteRule ^(calendar/feeds/.*)$ http://www.google.com/$1 [P]
</pre>
<p>The browser spits out a 502 error.    </p>
<p>A redirect, [R] instead of [P], only works half-way.  The XmlHttpRequest goes thru but the data is rejected because it’s considered insecure since you can’t load data retrieved from an external domain.</p>
<p>I also tried ProxyPass/ProxyPassReverse to map</p>
<pre class="brush: xhtml">
/calendar/
</pre>
<p>to</p>
<pre class="brush: xhtml">

http://www.google.com/calendar

</pre>
<p>but it simply results in an error.  I’ll have to consult with my host to figure if the error is the configuration on their end or mine.</p>
<p><strong>Update (03 Jan 08):</strong> <em>After talking with my hosting provider it turns out this error is the fault of my virtual server and it won’t be fixed since they’re retiring the hardware.  I’ve been placed in the queue to migrate my account over to a new (hopefully problem-free) server.  In any case, I’ll definitely revisit this solution after the migration is over and test it then.</em></p>
<p>For more info, checkout: <a href="http://www.xml.com/pub/a/2005/11/09/fixing-ajax-xmlhttprequest-considered-harmful.html">Fixing AJAX: XMLHttpRequest Considered Harmful</a> or <a href="http://developer.yahoo.com/javascript/howto-proxy.html">Use a Web Proxy for Cross-Domain XMLHttpRequest Calls</a>.  The last one has pretty pictures.</p>
<p>Failed experiments include:</p>
<ul>
<li>
<p>Use the Javascript prototype mechanism to somehow override the window.location.host property to return a string of my choosing.</p>
</li>
<li>
<p>Rewrite a request to www.google.com to point to MyGoogleCal2.php so that I could inject code into the calendar page.  I thought this had a lot promise up until the point I realized I couldn’t put an .htaccess file at google.com. This was one of those “Duh!” moments.</p>
</li>
<li>
<p>Manipulate the &lt;iframe&gt; DOM in order to change its document.styleSheets property directly.  Due to security reasons, you can’t modify, let alone read, the DOM properties across different domains.</p>
</li>
<li>
<p>Proxy the XmlHttpRequest thru a curl script.  This almost worked.  The curl request succeeded in getting the JSON data, but for whatever reason, the Javascript code failed to do anything with it.  Depending on the content-type requested for the response, either nothing happening or the browser would spit out a Javascript error.  I’m sure it had to with an incomplete request header or returning just the response data instead of the entire response.  But whatever reason it was, this solution seemed more trouble than it was worth.</p>
</li>
</ul>
<p><span style="text-decoration: line-through;"><strong>Update (29 Oct 07):</strong> <em>Google’s new version of the Javascript code does not require any customization.  Do you suppose some Google developer read my post? <img src="http://www.lindenlan.net/wp-includes/images/smilies/icon_smile.gif" alt=":-)" class="wp-smiley" /> However, a side-effect is that imported calendars do not work.  I’m betting it has to do with XmlHttpRequest permissions, but I won’t know for certain without further investigation.</em></span> </p>
<p>When you’re done restyling your calendar, <a href="http://www.lindenlan.net/2008/01/10/calendar-casting-call/">show it off</a>!  Oh and don’t forget to Digg the article.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lindenlan.net/2007/10/14/restyle-google-calendar-2/feed/</wfw:commentRss>
		<slash:comments>79</slash:comments>
		</item>
		<item>
		<title>How To Add A Meetup Calendar To Google Calendar</title>
		<link>http://www.lindenlan.net/2007/08/06/how-to-add-a-meetup-calendar-to-google-calendar/</link>
		<comments>http://www.lindenlan.net/2007/08/06/how-to-add-a-meetup-calendar-to-google-calendar/#comments</comments>
		<pubDate>Tue, 07 Aug 2007 05:13:29 +0000</pubDate>
		<dc:creator><![CDATA[Brian]]></dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Calendar]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[How To]]></category>

		<guid isPermaLink="false">http://www.lindenlan.net/2007/08/06/how-to-add-a-meetup-calendar-to-google-calendar/</guid>
		<description><![CDATA[I stumbled upon Meetup.com while looking for some local groups that matched my interests. I noticed that each group has its own calendar. Since I hack Google Calendar, I was wondering how to get a Meetup calendar on Google Calendar, rather than manually adding events by hand. Here’s how… Login into Google Calendar On the [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>I stumbled upon <a href="http://www.meetup.com/">Meetup.com</a> while looking for some local groups that matched my interests.  I noticed that each group has its own calendar.  Since I hack Google Calendar, I was wondering how to get a Meetup calendar on Google Calendar, rather than manually adding events by hand.  Here’s how…</p>
<p><span id="more-34"></span></p>
<ol>
<li>
<p>Login into Google Calendar</p>
</li>
<li>
<p>On the left hand side, under My Calendars, click Add and a drop down menu should appear</p>
</li>
<li>
<p>Click Add by URL</p>
</li>
<li>
<p>In a new tab/window, go to a Meetup group</p>
</li>
<li>
<p>Click on Calendar</p>
</li>
<li>
<p>Scroll to the bottom of the page, until you see Subscribe</p>
</li>
<li>
<p>Right click the iCal link and select Copy Link Location if you use Firefox (a similar option should be available for other browsers)</p>
</li>
<li>
<p>Go back to the Google Calendar tab/window</p>
</li>
<li>
<p>Paste the link in the Public Calendar Address field and click the Add button</p>
</li>
<li>
<p>Click OK to return to your Google Calendar</p>
</li>
</ol>
<p>If all goes well, the events from the Meetup group should appear on your calendar after a short while.  It takes time for Google Calendar to load the remote calendar.  This will work for any iCal address you find on the web.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lindenlan.net/2007/08/06/how-to-add-a-meetup-calendar-to-google-calendar/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Restyle Google Calendar Gadget</title>
		<link>http://www.lindenlan.net/2007/06/18/restyle-google-calendar-gadget/</link>
		<comments>http://www.lindenlan.net/2007/06/18/restyle-google-calendar-gadget/#comments</comments>
		<pubDate>Tue, 19 Jun 2007 00:16:34 +0000</pubDate>
		<dc:creator><![CDATA[Brian]]></dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.lindenlan.net/2007/06/18/restyle-google-calendar-gadget/</guid>
		<description><![CDATA[My how-to for restyling Google Calendar is by far this blog’s most popular post so far. Right from the start, people had requested that I adjust the code to accommodate Google Calendar’s mini-mode. It certainly was possible using the technique I used, but it did break the agenda which was flaky to begin with given [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>My <a href="http://www.lindenlan.net/2006/10/08/restyle-google-calendar/">how-to for restyling Google Calendar</a> is by far this blog’s most popular post so far.  Right from the start, people had requested that I adjust the code to accommodate Google Calendar’s mini-mode.  It certainly was possible using the technique I used, but it did break the agenda which was flaky to begin with given the fact the feature was experimental.  Every once in a while, I’d check on the stability of mini-mode to determine if it was ripe for some hacking.  Then one day the mode simply didn’t work anymore.  It was weird, but after further research I found out why.  Mini-mode was superseded by the <a href="http://www.google.com/ig/directory?synd=open&#038;num=24&#038;url=http://www.google.com/ig/modules/calendar-for-your-site.xml">Google Calendar Gadget</a>.  The configuration form does provide some customization of the style, but it is certainly limited.  So just like before, I poked and prodded the code until I was able to find the means to restyle the gadget.</p>
<p><span id="more-29"></span></p>
<p>First step is to go to the <a href="http://www.google.com/ig/directory?synd=open&#038;num=24&#038;url=http://www.google.com/ig/modules/calendar-for-your-site.xml">Google Calendar Gadget</a> page.  Click on the “Add to Your Webpage” button.  The reason I don’t provide a direct link is because clicking on the button appears to set some locale settings.  Once there you can roughly style the calendar the way you want—like the overall size, what border, whether you want to display the calendar, agenda, or both, which calendar(s) you want to load, the link color for each event (which can be different for each calendar), etc.  Note that the calendar URL that you want to use is the XML one.  You get the URL by going to your <a href="http://www.google.com/calendar/">Google Calendar</a>, click on “Manage Calendars,” click the specific calendar, and then clicking the XML button under “Calendar Address.”  Just copy and paste the address into the form.  After you are done previewing the calendar, you’ll want to click the “Get the Code” button which will generate a script block that will be the foundation on which we’ll build.  </p>
<p>Let’s dissect the generated HTML.</p>
<pre class="brush: plain">
&lt;script src=&quot;http://gmodules.com/ig/ifr
</pre>
<p>This is some JavaScript that’s part of iGoogle and the Google Gadget framework.  A lot of the behind the scenes magic happens here.  What I’ve determined so far is that this creates a table and iframe to contain the gadget.  There’s some bad news because of this, but I’ll get to that later.</p>
<pre class="brush: plain">
?url=http://www.google.com/ig/modules/calendar-for-your-site.xml
</pre>
<p>This XML file is what defines the gadget itself.  This is where we’ll be doing most of our restyling.</p>
<pre class="brush: plain">
&amp;up_showCalendar2=1
&amp;up_showAgenda=1
&amp;up_calendarFeeds=(%7B%7D)
&amp;up_firstDay=Sunday
&amp;up_syndicatable=true
&amp;up_stylesheet=
&amp;up_sub=1
</pre>
<p>Now I added carriage returns to improve readability.  Most of these settings map directly to settings you set in the form.  Supposedly you can supply your own stylesheet, but the fact of the matter is it gets ignored because, as we’ll see later, the gadget provides it’s own styles inline.  </p>
<pre class="brush: plain">
&amp;up_c0u=http%3A%2F%2Fwww.google.com%2Fcalendar%2Ffeeds%2Fuser%2540domain.tld%2Fpublic%2Fbasic
&amp;up_c0c=
&amp;up_c1u=
&amp;up_c1c=
&amp;up_c2u=
&amp;up_c2c=
&amp;amp;up_c3u=
&amp;amp;up_c3c=
</pre>
<p>These are the XML feeds for each of the calendars.  You can embed up to four calendars and each can have a different color.  The colors won’t show up in the calendar view but will show up in the agenda view for each event link as well as each subscription link.</p>
<pre class="brush: plain">
&amp;up_min=
&amp;up_start=
&amp;up_timeFormat=1%3A00pm
&amp;up_calendarFeedsImported=0
&amp;synd=open
&amp;w=320
&amp;h=450
&amp;title=Google+Calendar
&amp;border=%23ffffff%7C3px%2C1px+solid+%23999999
&amp;output=js&quot;&gt;&lt;/script&gt;
</pre>
<p>Some more settings.  You can have a blank title if you want.  This is also where the border is defined.  Again you can have a blank border or you can be very fancy with your border design as long as it’s valid <a href="http://www.string-functions.com/urlencode.aspx">URL encoded</a> CSS.  You can also tweak the width and height if the need arises.</p>
<p>The next step is download the <a href="http://www.google.com/ig/modules/calendar-for-your-site.xml">source code</a> for the gadget.  (You can select “File-&gt;Save Page As” in Firefox if you load the source code in the browser.)  This way we now have a copy of the gadget that we can modify.  Open up the XML file in your favorite editor.  Scroll down until you find the style block.  This is where most of the style changes can be made.  Anywhere you see <code>#c3d9ff</code> or <code>rgb(195, 217, 255)</code> is Google blue.    Most of the class selectors are self-explanatory.  The one style that’s not in the style block that you may wish to change is the one contained in the table with the id <code>pickerContainer__MODULE_ID__</code>.  This is the color for the “Loading…” splash.  </p>
<p>The last step is to change the script block that loads the gadget.  Instead of </p>
<pre class="brush: plain">
&lt;script src=&quot;http://gmodules.com/ig/ifr?url=http://www.google.com/ig/modules/calendar-for-your-site.xml
</pre>
<p>you need to change it to</p>
<pre class="brush: plain">
&lt;script src=&quot;http://gmodules.com/ig/ifr?url=http://mywebsite.com/path/to/file/calendar-for-your-site.xml
</pre>
<p>Don’t forget to upload the edited XML file to your web site.  That should do it.  </p>
<p>Now about that problem I alluded to earlier.  The JavaScript that loads the gadget unfortunately has some hard coded styles, in particular, it sets the background to white.  White is certainly a popular background color, but obviously not all web sites follow that convention.  The only way to do that is to use JavaScript to dynamically change the style.  In the XML file, locate this script block at the bottom:</p>
<pre class="brush: js">
if (navigator.userAgent.toLowerCase().indexOf(&#039;msie&#039;) != -1) {
  document.body.onload = function() { new _CalendarModule(__MODULE_ID__); };
} else {
  new _CalendarModule(__MODULE_ID__);
}
</pre>
<p>and change it to</p>
<pre class="brush: js">
if (navigator.userAgent.toLowerCase().indexOf(&#039;msie&#039;) != -1) {
  document.body.onload = function() { new _CalendarModule(__MODULE_ID__); document.body.style.backgroundColor = &quot;gray&quot;; };
} else {
  new _CalendarModule(__MODULE_ID__);
  document.body.style.backgroundColor = &quot;gray&quot;;
}
</pre>
<p>Of course feel free to change the color string to match your web site.  Now don’t be surprised if after reloading the page, the background doesn’t change.  I’m not a 100% sure why this is the case.  My best guess is that the code is being cached, but clearing it on the client side doesn’t seem to have an effect.  So there appears to be some server-side caching going on.  The good news is that eventually the cached version times out and the correct background color will display.  This technique can also be used to load a background image or change other style settings.</p>
<p>Assuming you do change the background color you will have to host your own corner images on your web site.  Locate these lines in the style block of the XML file.</p>
<pre class="brush: xml">
td.tl {background:url(&quot;http://www.google.com/calendar/images/corner_tl.gif&quot;) top left}
td.bl {background:url(&quot;http://www.google.com/calendar/images/corner_bl.gif&quot;) bottom left}
td.tr {background:url(&quot;http://www.google.com/calendar/images/corner_tr.gif&quot;) top right}
td.br {background:url(&quot;http://www.google.com/calendar/images/corner_br.gif&quot;) bottom right}
</pre>
<p>You will need to download, edit those GIF files to match your background color, and then upload the files to your site.  Once that’s done, you’ll need to update the XML file to reflect the new URLs for those images.</p>
<p>Happy styling!  When you’re done restyling your calendar, <a href="http://www.lindenlan.net/2008/01/10/calendar-casting-call/">show it off</a>!</p>
<p>P.S. The technique used to <a href="http://www.lindenlan.net/2006/10/08/restyle-google-calendar/">restyle Google Calendar</a> can be used to edit the XML file.  I leave this as an exercise for the reader.  The technique described above doesn’t require PHP so will be most applicable to those non-programmers out there.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lindenlan.net/2007/06/18/restyle-google-calendar-gadget/feed/</wfw:commentRss>
		<slash:comments>34</slash:comments>
		</item>
		<item>
		<title>Restyle Google Calendar</title>
		<link>http://www.lindenlan.net/2006/10/08/restyle-google-calendar/</link>
		<comments>http://www.lindenlan.net/2006/10/08/restyle-google-calendar/#comments</comments>
		<pubDate>Mon, 09 Oct 2006 00:14:45 +0000</pubDate>
		<dc:creator><![CDATA[Brian]]></dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.lindenlan.net/2006/10/08/restyle-google-calendar/</guid>
		<description><![CDATA[I had suggested that my company use Google Calendar to publish events. It’s easy, it can be made public and shareable, and it beats figuring out how to publish an Outlook/Exchange calendar on the web. (From what I’ve read about Google Calendar, you can publish multiple calendars individually controlling the level of privacy and publicity—ooo, [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>I had suggested that my company use <a href="http://www.google.com/calendar/">Google Calendar</a> to publish events.  It’s easy, it can be made public and shareable, and it beats figuring out how to publish an Outlook/Exchange calendar on the web.  (From what I’ve read about Google Calendar, you can publish multiple calendars individually controlling the level of privacy and publicity—ooo, maybe we can migrate away from Exchange…)  Yet, the coolest part about Google Calendar is that you can embed it in your web page using an iframe which Google provides a handy-dandy configurator to generate the HTML.  The worst part about Google Calendar is that you embed it in your web page using an iframe.</p>
<p><span id="more-11"></span></p>
<p><strong>UPDATE:</strong> New post on the <a href="http://www.lindenlan.net/2007/10/14/restyle-google-calendar-2/">new version of MyGoogleCal</a>.</p>
<p><strong>UPDATE:</strong> Around September 7, 2007, Google rolled out a JavaScript version of the embedded calendar.  See <a href="#comment-586">Comments #71 and #72</a> for a workaround. </p>
<p><strong>UPDATE:</strong> New post on how to <a href="http://www.lindenlan.net/2007/06/18/restyle-google-calendar-gadget/">restyle Google Calendar Gadget</a>.</p>
<p>An iframe is truly a page within a page from the start html tag down to the end html tag.  Therefore it has it’s own separate scope which means you can’t inherit styles from the parent page.  If my company’s web site had a cerulean blue theme, then I wouldn’t really care.  Unfortunately, the web site is colored various shades of green.  Clash-o-matic.  </p>
<p>What’s the solution?  Use an intermediary script to request the calendar document and then replace the stylesheet link with a link to my own stylesheet.  Voila!</p>
<pre class="brush: php">
&lt;?php
/*******************************************************************************
 * FILE: MyGoogleCal.php
 * 
 * DESCRIPTION:
 *  This script is an intermediary between an iframe and Google Calendar that
 *  allows you to override the default style.
 *
 * USAGE:
 *  &lt;iframe src=&quot;MyGoogleCal.php&quot;&gt;&lt;/iframe&gt; 
 *   OR
 *  &lt;iframe src=&quot;MyGoogleCal.php?src=user%40domain.tld&quot;&gt;&lt;/iframe&gt;
 *  
 *  where user@domain.tld is a valid Google Calendar account.
 *
 * HISTORY:
 *    8 September 2007 - Changed calendar URL to use &quot;htmlembed&quot; instead of 
 *                       &quot;embed&quot; since Google switched to using JavaScript
 *                       to generate the calendar.  
 *                       (Credit: Michael McCall http://www.castlemccall.com/)
 *   18 November 2006 - Simplified $query code block to read original query
 *                      string, rather than rebuilding it.  Doing it this way
 *                      allows the combination of multiple calendars.
 *    7 October  2006 - Original release
 *
 * copyright (c) by Brian Gibson
 * email: bwg1974 yahoo com  
 ******************************************************************************/

/* URL for overriding stylesheet
 * The best way to create this stylesheet is to load the embedded calendar in a
 * browser, view the source, determine the URL of the stylesheet, load the
 * stylesheet in the browser, and then save the file or copy and paste into an
 * editor.  Edit this new file to change the style of the calendar.
 * NOTE: There are (4) relative image URLs that must be changed to absolute URLs 
 * in the compiled Google stylesheet.
 */
$stylesheet = &#039;/css/mygooglecal.css&#039;;

/* Default URL
 * This is the embeddable public address for the calendar.  If this value is an
 * empty string, then the script will return a blank page if a valid query 
 * string is not submitted. This URL will typically be of the form
 *
 *   http://www.google.com/calendar/htmlembed?src=user%40domain.tld  
 *
 * where user@domain.tld is a valid Google Calendar account
 */
$url = &quot;&quot;;

// If a query string is supplied, pass it along to Google.
$query = &quot;&quot;;
if(count($_GET) &gt; 0) {
  $query = $_SERVER[&#039;QUERY_STRING&#039;];
  $url = &quot;http://www.google.com/calendar/htmlembed?&quot; . $query;
}

// Request the calendar
$buffer = &quot;&quot;;
$fd = fopen ($url, &quot;r&quot;);
while (!feof ($fd))
    $buffer .= fread($fd, 8192);
fclose ($fd);

// Fix hrefs, image sources, and stylesheet
$pattern = &#039;/(href=&quot;render)/&#039;;
$replacement = &#039;href=&quot;http://www.google.com/calendar/render&#039;;
$buffer = preg_replace($pattern, $replacement, $buffer);

$pattern = &#039;/(href=&quot;event)/&#039;;
$replacement = &#039;href=&quot;http://www.google.com/calendar/event&#039;;
$buffer = preg_replace($pattern, $replacement, $buffer);

$pattern = &#039;/(http:\\/\\/www.google.com\\/calendar\\/htmlembed)/&#039;;
$replacement = &#039;MyGoogleCal.php&#039;;
$buffer = preg_replace($pattern, $replacement, $buffer);

$pattern = &#039;/(src=&quot;images)/&#039;;
$replacement = &#039;src=&quot;http://www.google.com/calendar/images&#039;;
$buffer = preg_replace($pattern, $replacement, $buffer);

$pattern = &#039;/(&lt;link.*&gt;)/&#039;;
$replacement = &#039;&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;&#039; . $stylesheet . &#039;&quot; /&gt;&#039;;
$buffer = preg_replace($pattern, $replacement, $buffer);

// display the calendar
print $buffer;
?&gt;
</pre>
<p>If you already have an embedded calendar, just put this script on your web site and change the iframe src attribute to point to this file with the same query string and it should work.  You will get an unstyled calendar.  Download and save the stylesheet for your Google Calendar to your web site, update the <code>$stylesheet</code> variable, reload the page and your calendar is styled.  Now edit the stylesheet to make it better integrated.</p>
<p>Questions, suggestions, bugs, etc. email or leave a comment.</p>
<ul>
<li>
<p>How do I color-code events from different calendars? This is a work-in-progress. It’ll be done when it’s done. Tips (see link below) will encourage me to finish it faster. <img src="http://www.lindenlan.net/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" />  If you do leave a tip because you want this feature, please indicate that in the Item text field.</p>
</li>
<li>
<p>How do I download the stylesheet? See <a href="#comment-8">Comment #5</a>.</p>
</li>
<li>
<p>How do I change the calendar images, for example, the buttons? See <a href="#comment-11">Comment #8</a>.</p>
</li>
<li>
<p>How do I get mini-mode to work?  You don’t. See my post on how to <a href="http://www.lindenlan.net/2007/06/18/restyle-google-calendar-gadget/">restyle Google Calendar Gadget</a>.</p>
</li>
<li>
<p>No, I don’t like Google Calendar Gadget. I want to restyle the calendar in mini mode. See <a href="#comment-19">Comment #16</a>.</p>
</li>
<li>
<p>My web host disabled fopen() or I think fopen() is not secure enough so I’d prefer curl(). See <a href="#comment-33">Comment #20</a>.</p>
</li>
<li>
<p>How do I get rid of the Google logo? See <a href="#comment-37">Comment #24</a>.</p>
</li>
<li>
<p>How do I get the event details to appear in a pop-up window?  See <a href="#comment-41">Comment #27</a>.</p>
</li>
<li>
<p>How do I change the background color? See <a href="#comment-472">Comment #64.</a></p>
</li>
<li>
<p>HELP! My calendar disappeared! All I can see is the title (and a JavaScript error)! What do I do? See <a href="#comment-586">Comments #71 and #72.</a></p>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.lindenlan.net/2006/10/08/restyle-google-calendar/feed/</wfw:commentRss>
		<slash:comments>110</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 0.736 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2026-04-13 18:43:41 -->

<!-- Compression = gzip -->