Customising an embedded google calendar

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!

This entry was posted in Uncategorized. Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

24 Comments

  1. Courtney
    Posted February 2, 2011 at 5:03 pm | Permalink

    Can you explain in greater detail (step by step) how to wrap the text of titles? Thank you!!

    • danhigham
      Posted February 2, 2011 at 5:16 pm | Permalink

      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.

  2. Dave Brandt
    Posted February 4, 2011 at 7:00 pm | Permalink

    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!

    • Dave Brandt
      Posted February 4, 2011 at 7:01 pm | Permalink

      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?

  3. Posted February 23, 2011 at 1:34 pm | Permalink

    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 ;-)

  4. Posted March 8, 2011 at 5:46 am | Permalink

    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!

    • Richard
      Posted May 4, 2011 at 2:59 pm | Permalink

      I’m having the exact same issue. Anyone have an idea?

    • Posted March 8, 2012 at 6:22 pm | Permalink

      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?

  5. Michele
    Posted April 9, 2011 at 1:46 am | Permalink

    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?

  6. Katie
    Posted July 18, 2011 at 9:05 pm | Permalink

    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!

    • Patrick
      Posted July 21, 2011 at 11:50 pm | Permalink

      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!

      • Katie
        Posted July 26, 2011 at 12:52 am | Permalink

        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!

  7. Posted August 22, 2011 at 11:20 am | Permalink

    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.

  8. Atisha
    Posted October 23, 2011 at 12:36 am | Permalink

    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


    <?php
    $your_google_calendar="https://www.google.com/calendar/embed?src=usa__en@holiday.calendar.google.com&gsessionid=OK";
    $url= parse_url($your_google_calendar);
    $google_domain = $url['scheme'].'://'.$url['host'].dirname($url['path']).'/';

    // Load and parse Google's raw calendar
    $dom = new DOMDocument;
    $dom->loadHTMLfile($your_google_calendar);

    // Change Google's CSS file to use absolute URLs (assumes there's only one element)
    $css = $dom->getElementByTagName('link')->item(0);
    $css_href = $css->getAttributes('href');
    $css->setAttributes('href', $google_domain . $css_href);

    // Change Google's JS file to use absolute URLs
    $scripts = $dom->getElementByTagName('script')->item(0);
    foreach ($scripts as $script) {
    $js_src = $script->getAttributes('src');
    if ($js_src) $script->setAttributes('src', $google_domain . $js_src);
    }

    // Create a link to a new CSS file called custom_calendar.css
    $element = $dom->createElement('link');
    $element->setAttribute('type', 'text/css');
    $element->setAttribute('rel', 'stylesheet');
    $element->setAttribute('href', 'custom_calendar.css');

    // Append this link at the end of the element
    $head = $dom->getElementByTagName('head')->item(0);
    $head->appendChild($element);

    // Export the HTML
    echo $dom->saveHTML();
    ?>

    custom_calendar.css


    .dp-cur, .chip dt, .te, .te-t, .te-rev-s, .rb-n, .rb-i, .agenda, .event-title{
    white-space:normal !important;
    }

    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.

    • Posted March 8, 2012 at 6:49 pm | Permalink

      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

  9. Atisha
    Posted October 24, 2011 at 11:18 am | Permalink

    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.

  10. Jacob Krekura.com
    Posted October 28, 2011 at 6:04 pm | Permalink

    Worked like a charm. Thanks!

  11. ksvendsboe
    Posted November 9, 2011 at 5:57 pm | Permalink

    Genius. THANK YOU!!!

  12. Mike
    Posted December 1, 2011 at 9:41 am | Permalink

    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.

    • Evan
      Posted January 12, 2012 at 6:27 pm | Permalink

      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.

  13. Posted December 30, 2011 at 6:17 pm | Permalink

    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.

  14. pelicanPaul
    Posted January 16, 2012 at 8:01 pm | Permalink

    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.

  15. Dave
    Posted February 22, 2012 at 7:15 am | Permalink

    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

  1. [...] 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 [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>