Restyle Google Calendar 3
Posted April 23rd, 2008 in ProgrammingTags: CSS, Google, Hacking, JavaScript, PHP, Programming
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 never noticed. In any case, the runtime error occurs when //"+a.host+"/calendar
is replaced by //www.google.com/calendar
. 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 original technique for IE but uses the technique from MyGoogleCal2 for all other browsers.
UPDATE: MyGoogleCal now has a fourth version.
Download: mygooglecal3.zip. 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.
<?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: * <iframe src="MyGoogleCal3.php?src=user%40domain.tld"></iframe> * * 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'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 "htmlembed" * 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 "http://www.google.com/calendar/embed?src=user%40domain.tld" in a * browser, * 2) View the source (e.g., View->Page Source in Firefox), * 3) Copy the relative URL of the stylesheet (i.e., the href value of the * <link> tag), * 4) Load the stylesheet in the browser by pasting the stylesheet URL into * the address bar so that it reads similar to: * "http://www.google.com/calendar/embed/d003e2eff7c42eebf779ecbd527f1fe0embedcompiled.css" * 5) Save the stylesheet (e.g., File->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's easier to edit. */ $stylesheet = 'mygooglecal3.css'; /* For the IE stylesheet replace "embed" with "htmlembed" in step (1) */ $stylesheet_ie = 'mygooglecal3ie.css'; /******************************************************************************* * DO NOT EDIT BELOW UNLESS YOU KNOW WHAT YOU'RE DOING ******************************************************************************/ // URL for the calendar $url = ""; $is_ie = FALSE; if(count($_GET) > 0) { if(stristr($_SERVER['HTTP_USER_AGENT'], 'msie') === FALSE) { $url = "http://www.google.com/calendar/embed?" . $_SERVER['QUERY_STRING']; } else { $url = "http://www.google.com/calendar/htmlembed?" . $_SERVER['QUERY_STRING']; $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 = '/(href="render)/'; $replacement = 'href="http://www.google.com/calendar/render'; $buffer = preg_replace($pattern, $replacement, $buffer); $pattern = '/(href="event)/'; $replacement = 'href="http://www.google.com/calendar/event'; $buffer = preg_replace($pattern, $replacement, $buffer); $pattern = '/(http:\/\/www.google.com\/calendar\/htmlembed)/'; $replacement = 'MyGoogleCal3.php'; $buffer = preg_replace($pattern, $replacement, $buffer); $pattern = '/(src="images)/'; $replacement = 'src="http://www.google.com/calendar/images'; $buffer = preg_replace($pattern, $replacement, $buffer); $pattern = '/(<link.*>)/'; $replacement = '<link rel="stylesheet" type="text/css" href="' . $stylesheet_ie . '" />'; $buffer = preg_replace($pattern, $replacement, $buffer); } else { // Point stylesheet and javascript to custom versions $pattern = '/(<link.*>)/'; $replacement = '<link rel="stylesheet" type="text/css" href="' . $stylesheet . '" />'; $buffer = preg_replace($pattern, $replacement, $buffer); $pattern = '/src="(.*js)"/'; $replacement = 'src="MyGoogleCal3js.php?$1"'; $buffer = preg_replace($pattern, $replacement, $buffer); } // display the calendar print $buffer; ?>
The installation of MyGoogleCal3 is more or less the same as the installation for MyGoogleCal2 except you download the zip file above. Also MyGoogleCal3 uses two stylesheets, one for IE and one for all the other browsers.
There is a minor bug. Despite changing the URL from ../images/ext/poweredby.png
to images/poweredby.png
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.
Update (21 Jun 2008): 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.
In the MyGoogleCal3.php in the zip there is a small error. It still uses ‘mygooglecal2.css’;
$stylesheet = ‘mygooglecal2.css’;
$stylesheet_ie = ‘mygooglecal2ie.css’;
But in the zip the files included are
’mygooglecal3.css’ and ‘mygooglecal3ie.css’
Thanks for a great work!
Hey Brian,
First of all THANKS for the code. What a life saver and exactly what I needed. I have spent soooo many hours (as you have I’m sure) tweaking my calendars to get them just right and just when I thought I was done I started noticing the JS errors in IE. I hopped back over to your blog and you had a post about the exact problem. Great! I followed your instructions but all the chrome stuff will not go away. I put up a test page here http://www.dcspride.com/caltest.php The first one is the plain embedded google calendar, the second one is MyGoogleCal2 customized for my site and the third is MyGoogleCal3. The IFRAME lines are exactly the same except for one points to MyGoogleCal2.php and the other to MyGoogleCal3.php. It works fine in FireFox but not in IE. I have looked at this til my eyes are crossed and I need someone else to look at it. What am I doing wrong? Why wont the tabs and google logo go away in version 3 (IE only)?
I change only a couple things in your code. In MyGoogleCal3.php (correct me if I’m wrong in doing that but otherwise it does not work at all)
line 67 pointed to mygooglecal2.css (changed to mygooglecal3.css)
line 71 referred to mygooglecal2ie.css (changed to mygooglecal3ie.css)
line 108 reffereded to MyGoogleCal.php (changed to MyGoogleCal3.php)
Here are the pages I am working on.
http://dev.dcspride.com/ (I need the agenda for this page)
http://dev.dcspride.com/calendar/ (here is the full size calendar)
Both of these pages are still running MyGoogleCal2, Firefox works great, IE js errors
UPDATE: After reading through some of the comments on your site I added &chrome=NAVIGATION to the MyGoogleCal3 calendar on the test page. The logo is gone now but the tabs and all are still there.
Thanks again and I hope you can help me.
Tony
Sorry all for the late reply… been busy with moonlighting with freelance work so I’ve had little time for the blog. In my rush to get version 3 out, I left a few typos. Glad it wasn’t anything someone couldn’t figure out. Thanks paolo! I’ve updated the zip file with the corrections.
First — amazing job on the Google Calendar styling script. Wonderful. I do have what I hope is a quick question: I seem to be having trouble in IE 6 & 7. The code and CSS work for both IE and FF/Other, but the navigation that is displayed on the calendar is different for IE (and &chrome=navigation doesn’t seem to have an effect). The problem is that the IE version lacks the drop-down menu which selects which calendars to display, as well as the “week” option from “week/month/agenda.”
You can see the test in action here:
http://www.itpdev.org/calendar.php
I’ve been doing some pretty serious styling (and I’m having a ball with it thanks to you), but the big selling point on Google for my boss was to have multiple calendars that could be switched on and off. If that doesn’t work, I dunno, he shoots me in the face or something.
I’d appreciate any response at all — even if it’s just, “I have no idea.”
Hi Steve,
GC3 uses the old HTML-based Google Calendar for IE because for whatever reason, styling causes a JavaScript error when navigating to a different date range when using the JavaScript-based Google Calendar. It’s unable to load additional events. This is why the IE version looks different and has less features. To make the navigation go away, use &chrome=none. Beyond that, you have a choice with living with less features but a fully working IE calendar or an IE calendar with broken navigation.
That’s a shame. It’s incredible how IE just always manages to be evil, even in new versions. For the time being, I have two calendars, and so will be providing IE-only links (links that are display:none except in the IE style sheets) that will provide links to a PHP page that has only Calendar A specified in the , then another one that has Calendar B, and one that has Calendars A+B.
This obviously becomes impractical once the number of calendars goes past two, as the permutations get too vast.
My suggestion for a workaround for the JS problem would be a PHP checkbox form that changes the src= of the to include/disclude whatever src= the user needs, and then refresh the page. It’s not quite as slick as the instantly-disappearing JS, but would function basically the same way.
I am not a PHP programmer, however, and so can’t write it myself.
I would like to register my incredulity that Google doesn’t let users easily make these modifications. It seems like such a basic necessity for web designers.
< iframe > was omitted in the above post.
It should say:
“Calendar A specified in the < iframe >, …”
Wow, this is powerful. I’m part of a dance community and want to create a community calendar. Google Calendar is the best option, but I’ll want to integrate it visually better for my new website.
Hey has this happened to anyone else? My calendars just stopped working today…stuck on loading. http://www.dcspride.com and http://www.dcspride.com/calendar. Did google go off and change something again?
I just noticed today that the AGENDA mode is no longer working. I have checked a few of the calendars that are linked from this page and it seems to be affecting others as well. Any thoughts on what the problem may be. I have updated the css file and have been going through that most of the afternoon. I have gone back to the “normal” google calendar for the time beong. Any thoughts or ideas will be appreciated. Thanks for all your hard work.
Pretty cool code. I’ve been looking for something like this for a while. However, it would be great if the AGENDA mode worked. Has anyone been able to figure this out?
Alright guys,
I’ve uploaded a new version of the .zip file. The major change is:
$replacement = ‘src=“MyGoogleCal3js.php?$1″’;
to:
$replacement = ‘src=“MyGoogleCal3.js“‘;
Yes that’s a custom Javascript file. See the update above for more info.
Thanks! That fixed it for me! You da man!
Here’s a strange one: The update worked great for FF and IE, but Safari is still having the “Loading…” error. Any idea why it would either not see the .js or the change in general?
Or does Safari just have the most stubborn cache of all time?
The URL is http://www.itp.edu/calendar.php
This is brilliant and I’d love to implement this on my site — but Steve, I’m having the same problems as you in Safari with the Agenda view. It simply won’t load; seems to run fine on other Mac OS X browsers though. Does anyone have a fix or a workaround? Thanks
This is just what I needed to help customize our school website. I’ve got it working pretty well in Firefox, but have some issues in IE (arrrgh). I can’t seem to get the title, tabs and Google beta image off the top of the calendar. Any ideas? Are the arguments somehow not getting passed in the IE rendering?
http://montessoricelebration.com/calendar2.php is my test site
THANKS!!!
I dont know how many times we are gonna have to do this but thanks AGAIN. My calendar is finally fixed (for the 3rd time) on my site. You are the best. You can see my styling and usage here (click on view calendar link):
http://www.thedesigncoalition.com
Hello,
I have troubles getting other languages to work. No matter what I pass as hl-parameter, the calendar always gets loaded in English! Are there any server parameters that I have to take care of? If I load the URL in a separate window, it gets displayed in the wanted language (German), but inside my page (called via curl) it gets displayed in English.
Other than that, customizing worked pretty fine, great work!
Max
Little follow-up on the languages:
Found out they are hidden in the javascript files, and not within the $buffer from curl_exec. For now I just went through the file and replace the text occurences.
Greets,
Max
ANNABANANA… I was having the same problem… then I read comment #5… I added “&chrome=none” as my first thing after the initial question mark… and I was in business again.
BRIAN (and still appropriate if misspelled BRAIN)… WOW!!! This is powerful, useful stuff. THANK YOU!!! Jeffk said in a comment on an earlier post that you were an “internet-dwelling saint” … and I agree!!! How can we thank you?!? I looked a little, but no “contribute” link, no list of goodies to send… NOTHING! You deserve something beyond just kudos!
BRIAN, might you add the “&chrome=none” option onto list of “VALID QUERY STRING PARAMETERS” in the main MyGoogleCal file? I think it might be useful.
Thanks for the accolades. Unfortunately, with the second job, I haven’t had much opportunity to improve the script (like handling IE better) and also providing support. Thankfully, there are enough comments and replies that cover most problems people encounter.
That said, if you want to leave a monetary donation, click the “Leave a tip” button which goes to my PayPal account.
Thanks John Mark — that tag seemed to do the trick! Now I can play with more formatting and get rid of the blue — whoohooo! Great tool Brian!
Hi there,
Looks like google have changed their code gfor the JS side of things, I have managed to fix it for now, see below
// Fix URLs in the javascript
$pattern = ‘/this\.sc\+\“calendar/’;
$replacement = ’”http://www.google.com/calendar’;
$buffer = preg_replace($pattern, $replacement, $buffer);
// No longer needed by the looks of things
#$pattern = ‘/put\(“baseUrl”,c\)/’;
#$replacement = ‘put(“baseUrl”,“http://www.google.com”)’;
#$buffer = preg_replace($pattern, $replacement, $buffer);
Im going to make further changes so that the code locally cache’s the JS (maybe even the html) and keeps track of the MD5 of it. Technically if the md5 changes then google have changed their code. Get in touch if your interested in a copy when I’m done.
This looks awesome but I’m having some trouble with cURL, basically after scratching my head and looking at the code for a couple of hours I read your MyGoogleCal2 and realised that I don’t have cURL installed. Could anyone help someone with virtually no PHP/ server-side knowledge install it? :<
Thank you very much Brian for pitching in where Google’s fallen short!
Regards
Fet
Chris,
How’s the progress going with the md5 check?
I just discovered this site yesterday I spent the whole day reading all the comments and playing with all the versions. Thanks so much Brian.
This is a great script and I have it working well using FF but the iframe will not show in IE any suggestions what might be the problem?
Could someone tell me which element I need to edit in order to change the background colour behind the calendar title? The style used is inline in the body tag.
Thanks
Pretty cool script. Awesome Job.
One thing I noticed, when I use the included javascript the date picker doesn’t have the hover effects and the calendar picker doesn’t drop down. But if I download a new javascript file those two items will work but then the calendar won’t change months. It get stuck with the loading indicator showing. Any ideas of how I can get the best of both worlds?
Great script, I have been looking for something like this for a long time. I did have a tip that I thought might be worth sharing. My gmail account has several calendars, but I only want to embed one of them on my website. In order to do this, I had to replace the “src=myuser@gmail.com” with the HTML private address available in the “Calendar Details” tab of the gmail calendar settings. Doing so also solved another issue that I was having. I did not want to make my calendar public and searchable on google. Using the private address allows me to keep the calendar private but still post it on my website. Of course, the URL is contained within the HTML code, but I simply password-protected my site (which I wanted to do anyway) and that solves the problem.
hi in this versione Parameter Locale not function ! &hl=it
Why?
help me please..
This works great with firefox but I can’t seem to get the css file for IE to work with it? Are there any known bugs with IE and css configuration?
Or could it possibly be a java script issue?
Jason–
I’ve been having the same problem with IE accepting any .css edits or even resizing. It seems that the “http://www.google.com/calendar/htmlembed?” call is no longer working like before, at least as far as customizing is concerned.
I’m currently using the workaround by eliminating the navigation from the IE side then running it through java (like the other browsers) as normal. It’s not ideal, but I just can’t get the old way to work.
I am also seeing loading within safari browser… Any fixes?
I am also getting calendar.com when clicked on the Google badge near bottom? Any fixes? Thanks