A recent client requested a calendar she could use on her website to display events, immediately my thoughts turned to Google calendar. After creating and embedding the Google calendar in an iframe I noticed the style didn’t quite fit with the rest of the site, it looked ok but just didn’t follow suit.
I was surprised to find that adding CSS rules to the parent document didn’t work, even when adding an !important directive to each rule. The reason for this became obvious and actually two-fold;
1. The host document and the document in the iframe are completely separate. This seems an obvious statement to make but quite easy to overlook none the less.
2. The document in the iframe is on a separate domain (google.com in fact) which of course means that most browsers will block any attempt made from another domain to modify content within that document.
After trying all sorts of techniques to circumvent this issue, even proxying the content via my server I actually stumbled on a rather simple solution. Looking at the settings for a Google calendar you are given an snippet of code for embedding it in an iframe, that snippet has a URL in it which looks like this;
http://www.google.com/calendar/embed?src=p58tvijpfqoe83deo2prnd6pqg%40group.calendar.google.com&ctz=Europe/London
This is where you point your iframe to and is the location of the base document for your calendar, take this URL and grab the source (I used wget). Create a new page on your site with the markup retrieved from the aforementioned URL, there are two lines in the code that need updating and they look something like this;
<link type="text/css" rel="stylesheet" href="969ff39784188d8d017a0c60c8f2558aembedcompiled_fastui.css">
<script type="text/javascript" src="969ff39784188d8d017a0c60c8f2558aembedcompiled__en_gb.js"></script>
As you can see, both tags contain relative urls, they need prefixing with “https://www.google.com/calendar/” so they look like this;
<link type="text/css" rel="stylesheet" href="https://www.google.com/calendar/969ff39784188d8d017a0c60c8f2558aembedcompiled_fastui.css">
<script type="text/javascript" src="https://www.google.com/calendar/969ff39784188d8d017a0c60c8f2558aembedcompiled__en_gb.js"></script>
Now you are able to point your iframe to the new page on YOUR domain and not Google’s, add custom CSS declarations to the new document to override elements in the Google calendar.. job done!
One of the changes this has allowed me to make is the ability to wrap the title of a calendar item in the month view, a feature that has been requested to Google by a lot of people!
24 Comments
Can you explain in greater detail (step by step) how to wrap the text of titles? Thank you!!
Sure!, it’s a simple CSS change, setting the white-space property to ‘normal’, but to do that you have to be able to inject CSS in to the iframe that Google calendar presents itself in.
For an example, take a look at http://www.sugarplumcupcakes.co.uk/calendar
Hello! Thank you for your article! I’m very excited about adding word wrap, but unfortunately, I don’t know much about codes and am having trouble following you. I have a calendar at http://lebanonbfc.org/calendar.html. What do I do to add word wrapping to this calendar? Thanks so much for your help!
I have Kompozer as my free html editor – I know how to use that, I just don’t know what codes to copy and paste. Could you guide me through it?
Very Cool solution to a common problem with Google Calendar. Finally word wrap can work, at least on a WordPress site…IF you’d be kind enough to share your instructions to “add custom CSS declarations”…PLEASE
Hi. I’m eager to use this promising technique. But when i download as you describe, i get a file that includes the actual events, hard-coded. That’s no good, as the file will not refresh when events are added or edited, nor will it provide scrolling to future and past events.
Am i doing this wrong?
Thanks!
I’m having the exact same issue. Anyone have an idea?
Same issue here, I’m running different test but seeing the same problem, events are hard coded into place. Any luck from anyone else getting around this?
But this will just give you a copy of the contents of the iFrame. If you want it to update, evey time you add a new event you will have to repeat this process, no?
This is great – exactly what I was looking for! I’ve successfully customized the embedded calendar on my site, and it looks great. The only thing that I need to know is how to change is the format of the “date-label”. Currently, each event has a date-label formatted like this: Friday, 18 July. I would like it to be formatted like this: Friday, July 18. I checked my Google Calendar settings; the Date Format is set to 12/31/2011 and the Language is English (US). I thought that maybe changing the “dateFieldOrder” entry in the markup from “0″ to “1″ might fix it, but no luck. If anyone has an idea of how to reformat the date, I would be grateful for your advice! Thanks!
Katie – Did you customize the wrap-text feature? If so, could you tell me which white-space attribute in the Google Calendar CSS you changed to “normal”? Thanks!
Hi Patrick!
I actually did not customize the wrap-text feature; this particular calendar is in agenda view and has enough room for all the titles to stretch. However, if I were to hazard a guess as to which attribute to change in the Google CSS, I would say .agenda .event-title would be the one. For example, my CSS currently reads as follows:
.agenda .event-title {
clear: none;
color: #D15600;
display: block;
font-size: 12px;
font-style: normal;
font-weight: normal;
margin: 0;
overflow: hidden;
white-space: nowrap;
}
I would change that to:
.agenda .event-title {
clear: none;
color: #D15600;
display: block;
font-size: 12px;
font-style: normal;
font-weight: normal;
margin: 0;
overflow: hidden;
white-space: normal;
}
Hope that helps!
Hey dude, this looks like its awesome but i can’t quite get it to work – Is there anyway you could post your entire iframe embed code rather than just the segments? Obviously block out your calendar link.
I’m just struggling to put all the code together to achieve this.
Hi all,
Thanks for presenting this very clever idea, and hopefully lots of people can get benefit from this. Following the pointers in this article, I’ve prepared the code necessary for doing this. You need to create 2 files: custom_calendar.php (the actual calendar file) and custom_calendar.css (a CSS file to style the calendar to your liking). The first file is the main one that makes this possible; the second file allows you to change any of the CSS properties. Figuring out which CSS properties to change to make this suit your exact needs will probably take some experimentation and reverse-engineering.
Your website needs to be able to serve PHP files for this to work.
custom_calendar.php
custom_calendar.css
In many places having the lines wrap will “mess up” the appearance of the calendar by creating lots of gaps between events. You may need some experimentation to get it to look right for your site.
When I’m doing it this way I get a error 500 code (even using just the code you provided with the holiday calendar. It seemed at first to be caused by the line:
$google_domain = $url['scheme'].'://'.$url['host'].dirname($url['path']).'/';If I replace this the variable with the expected value it works past this line but then brakes elsewhere. Not sure the what the problem is
Because of the way that Google outputs the calendar entries, it puts them into a table. In some cases, when one of the items in that table becomes higher than one line (because of our enabling word-wrapping), the entire row that it’s in becomes higher than it needs to be. This creates the appearance of blank lines underneath some of the entries. There is no way to work around this issue since it’s based on how Google exports the calendar information.
It is nice to be able to display multiple lines, however, it’s just a bit of a shame that the formatting doesn’t come out more cleanly.
Worked like a charm. Thanks!
Genius. THANK YOU!!!
Thanks for the code, tested this and got it working eventually but found that the initial iframe call only loads the first 5 weeks of events. Clicking the navigation links obviously changes the google output but doesn’t refresh the custom_calendar.php page. I suspect you would need to make changes to the javascript file used by Google to update your own pages too.
I gave up at this point as it wasn’t worth the extra time.
Ditto. It’ll pull a certain chunk of events, but if you navigate into the past or future, it won’t load any more. In my case it was a couple month’s worth. This is because the copy of the iframe source saved on the hosting site is a static snapshot of events that were loaded when the wget was run.
Nice explanation. It worked well for me, I was able to format that plain-Jane title on the calendar to match my site. Thank you for taking the time to post this.
This is very cool until Google changes the name of your js file and your calendar goes blank. I guess that this would happen even if you embed the way they tell you to. strange.
Brilliant! Thanks for sharing!
For those of you who use Firefox, view the source of your page – then click on the link to the google calendar – it will show the source code for your calendar. Copy and paste this code onto a new page on your site, update the links to the css and javascript with absolute URLs. In the head section between the enter this css code
span.te-t {
white-space: normal !important;
}
span.te-s {
white-space: normal !important;
}
Works great for me. Thank you!
One Trackback
[...] the web I found one solution: Customising an embedded google calendar, that looked promising. Basically use wget to capture the page that is returned in the embeded code [...]