Sunday, May 13, 2012

Customizing Blogger Template

Note: the following is out of date. I no longer customize blogger. I now use dynamic views. I decided they were better at laying out content for consumption by a variety of devices that I am. The only thing I customize for dynamic views is the CSS.

Blogger > Template > Customize > Advanced > Add CSS > ... > Apply to Blog

Customizations for Non-Dynamic Views

There doesn't seem to be much official advice on this topic. Eventually I busted functionality. Here's what I've found to be safe. First create a new blog with the simple template. Then backup its template. Then use that as the starting point for your edits.

Add meta, link, script at top of <head>

  <head>
    <!-- begin custom -->
    <meta content='width=device-width, initial-scale=1, maximum-scale=1' name='viewport'/>
    <meta content='text/html; charset=utf-8' http-equiv='content-type'/>
    <link href='http://michael.holtstrom.com/styles.css' rel='StyleSheet' type='text/css'/>
    <link href='http://michael.holtstrom.com/style3.css' rel='StyleSheet' type='text/css'/>
    <link href='http://michael.holtstrom.com/hosted/sh/styles/shCoreDefault.css' rel='stylesheet' type='text/css'/>
    <script src='http://michael.holtstrom.com/util.js' type='text/javascript'/>
    <script type='text/javascript'>
      slowOnIpad = new Image(); 
      slowOnIpad.src = "http://michael.holtstrom.com/img/grey.png";
    </script>
    <!-- end custom -->

If you have specified the viewport like me, make sure to remove the one specified by blogger.

    <b:else/>
      <meta content='width=1100' name='viewport'/>

Replace the entire <b:skin><![CDATA[ with styles of your choice. Note that I cause several standard blogger elements to not display.

<b:skin><![CDATA[
/* topbar, title widget, powered-by widget, atom subscription */
#navbar, #Header1, #Attribution1, .feed-links {
 display: none;
}
#sidebar-right-1 .widget {
 padding: 4px 9px 5px 8px;
}
#sidebar-right-1 a {
 cursor: pointer;
 text-decoration: none;
 color: #FFFEEA;
}
#sidebar-right-1 a:hover {
 text-decoration: underline;
}
.post-title {
 font: normal normal 1.5em Arial, Verdana, Helvetica, sans-serif;
}
/* 1em top/bottom margins collapse with 1em margins of paragraphs */
.post-body {
 margin: 1em 0 1em 0;
}
.post-body p {
 margin: 1em 0.6em 1em 0.6em;
 text-align: justify;
}
.post-footer-line-2 {
 float: left;
}
.post-footer-line-3 {
 clear: both;
}
#bc_0_1L { /* at bottom of comments */
 margin: 0;
 padding: 0;
}
#comment-editor {
 width: 745px;
 margin: 0 0 0 10px;
 height: 195px;
}
#comments .comment-footer { /* at bottom of comments */
 display: none;
}
#comments p:last-child { /* empty p at bottom of comments */
 display: none;
}
#twitter_update_list {
 list-style-type: none;
 padding: 0;
 margin: 0 0 4px 0;
}
#twitter_update_list a {
 color: #B26639;
}
#twitter_follow {
 text-align: center;
 font-size: 0.7em;
}
]]></b:skin>

Delete the entire <b:template-skin>...</b:template-skin>, it's just another block of css that will be obsolete once you've completed the below.

Delete the entire <header>...</header>

Add a custom topbar at the top of <body...>

  <body expr:class='&quot;loading&quot; + data:blog.mobileClass'>
  <!-- begin custom -->
  <div class='topbar' id='topbar'>
    <div id='topcontent'/>
    <div class='background'/>
  </div><!--topbar-->
  <script src='http://michael.holtstrom.com/topbar.php' type='text/javascript'/>
  <!-- end custom -->

Add script before bottom of </body>

<!-- custom twitter -->
<script src='http://twitter.com/javascripts/blogger.js' type='text/javascript'/>
<script src='http://twitter.com/statuses/user_timeline/mholtstrom.json?callback=twitterCallback2&amp;count=3' type='text/javascript'/>

<!-- custom syntaxhighlighter -->
<script src='http://michael.holtstrom.com/hosted/sh/scripts/shCore.js' type='text/javascript'/>
<script src='http://michael.holtstrom.com/hosted/sh/scripts/shBrushBash.js' type='text/javascript'/>
<script src='http://michael.holtstrom.com/hosted/sh/scripts/shBrushCpp.js' type='text/javascript'/>
<script src='http://michael.holtstrom.com/hosted/sh/scripts/shBrushCss.js' type='text/javascript'/>
<script src='http://michael.holtstrom.com/hosted/sh/scripts/shBrushJava.js' type='text/javascript'/>
<script src='http://michael.holtstrom.com/hosted/sh/scripts/shBrushJScript.js' type='text/javascript'/>
<script src='http://michael.holtstrom.com/hosted/sh/scripts/shBrushPhp.js' type='text/javascript'/>
<script src='http://michael.holtstrom.com/hosted/sh/scripts/shBrushSql.js' type='text/javascript'/>
<script src='http://michael.holtstrom.com/hosted/sh/scripts/shBrushXml.js' type='text/javascript'/>
<script type='text/javascript'>
 SyntaxHighlighter.config.bloggerMode = true;
 SyntaxHighlighter.defaults[&#39;gutter&#39;] = false;
 SyntaxHighlighter.defaults[&#39;toolbar&#39;] = false;
 SyntaxHighlighter.all();
</script>

</body>

Replace <b:section-contents id='sidebar-right-1'>...</b:section-contents> with the Label, Twitter, Picasa, Archive widgets. Since we're starting from a test blogs template you should fetch exactly your current widgets from your current template. You can't edit widgets from template backup/restore. Blogger will auto-modify this section. But you can make slight customizations like deleting the quick-edit links.

<b:section-contents id='sidebar-right-1'>
<b:widget id='Label1' locked='false' title='' type='Label'>
<b:includable id='main'>
  <b:if cond='data:title'>
    <h2><data:title/></h2>
  </b:if>
  <div expr:class='&quot;widget-content &quot; + data:display + &quot;-label-widget-content&quot;'>
    <b:if cond='data:display == &quot;list&quot;'>
      <ul>
      <b:loop values='data:labels' var='label'>
        <li>
          <b:if cond='data:blog.url == data:label.url'>
            <span expr:dir='data:blog.languageDirection'><data:label.name/></span>
          <b:else/>
            <a expr:dir='data:blog.languageDirection' expr:href='data:label.url'><data:label.name/></a>
          </b:if>
          <b:if cond='data:showFreqNumbers'>
            <span dir='ltr'>(<data:label.count/>)</span>
          </b:if>
        </li>
      </b:loop>
      </ul>
    <b:else/>
      <b:loop values='data:labels' var='label'>
        <span expr:class='&quot;label-size label-size-&quot; + data:label.cssSize'>
          <b:if cond='data:blog.url == data:label.url'>
            <span expr:dir='data:blog.languageDirection'><data:label.name/></span>
          <b:else/>
            <a expr:dir='data:blog.languageDirection' expr:href='data:label.url'><data:label.name/></a>
          </b:if>
          <b:if cond='data:showFreqNumbers'>
            <span class='label-count' dir='ltr'>(<data:label.count/>)</span>
          </b:if>
        </span>
      </b:loop>
    </b:if>
  </div>
</b:includable>
</b:widget>
<b:widget id='HTML1' locked='false' title='' type='HTML'>
<b:includable id='main'>
  <!-- only display title if it's non-empty -->
  <b:if cond='data:title != &quot;&quot;'>
    <h2 class='title'><data:title/></h2>
  </b:if>
  <div class='widget-content'>
    <data:content/>
  </div>
</b:includable>
</b:widget>
<b:widget id='Slideshow1' locked='false' title='' type='Slideshow'>
<b:includable id='main'>
  <!-- only display title if it's non-empty -->
  <b:if cond='data:title != &quot;&quot;'>
    <h2 class='title'><data:title/></h2>
  </b:if>
  <div class='widget-content'>
    <div class='slideshow-container' expr:id='data:widget.instanceId + &quot;_slideshow&quot;'>
      <span class='slideshow-status'>Loading...</span>
    </div>
  </div>
</b:includable>
</b:widget>
<b:widget id='BlogArchive1' locked='false' title='' type='BlogArchive'>
<b:includable id='toggle' var='interval'>
  <b:if cond='data:interval.toggleId'>
  <b:if cond='data:interval.expclass == &quot;expanded&quot;'>
    <a class='toggle' href='javascript:void(0)'>
      <span class='zippy toggle-open'>&#9660;&#160;</span>
    </a>
  <b:else/>
    <a class='toggle' href='javascript:void(0)'>
      <span class='zippy'>
        <b:if cond='data:blog.languageDirection == &quot;rtl&quot;'>
          &#9668;&#160;
        <b:else/>
          &#9658;&#160;
        </b:if>
      </span>
    </a>
  </b:if>
 </b:if>
</b:includable>
<b:includable id='interval' var='intervalData'>
  <b:loop values='data:intervalData' var='i'>
      <ul class='hierarchy'>
        <li expr:class='&quot;archivedate &quot; + data:i.expclass'>
          <b:include data='i' name='toggle'/>
          <a class='post-count-link' expr:href='data:i.url'><data:i.name/></a>
            <span class='post-count' dir='ltr'>(<data:i.post-count/>)</span>
          <b:if cond='data:i.data'>
            <b:include data='i.data' name='interval'/>
          </b:if>
          <b:if cond='data:i.posts'>
            <b:include data='i.posts' name='posts'/>
          </b:if>
        </li>
      </ul>
  </b:loop>
</b:includable>
<b:includable id='menu' var='data'>
  <select expr:id='data:widget.instanceId + &quot;_ArchiveMenu&quot;'>
    <option value=''><data:title/></option>
    <b:loop values='data:data' var='i'>
      <option expr:value='data:i.url'><data:i.name/> (<data:i.post-count/>)</option>
    </b:loop>
  </select>
</b:includable>
<b:includable id='flat' var='data'>
  <ul class='flat'>
    <b:loop values='data:data' var='i'>
      <li class='archivedate'>
        <a expr:href='data:i.url'><data:i.name/></a> (<data:i.post-count/>)
      </li>
    </b:loop>
  </ul>
</b:includable>
<b:includable id='posts' var='posts'>
  <ul class='posts'>
    <b:loop values='data:posts' var='i'>
      <li><a expr:href='data:i.url'><data:i.title/></a></li>
    </b:loop>
  </ul>
</b:includable>
<b:includable id='main'>
  <b:if cond='data:title'>
    <h2><data:title/></h2>
  </b:if>
  <div class='widget-content'>
  <div id='ArchiveList'>
  <div expr:id='data:widget.instanceId + &quot;_ArchiveList&quot;'>
    <b:if cond='data:style == &quot;HIERARCHY&quot;'>
     <b:include data='data' name='interval'/>
    </b:if>
    <b:if cond='data:style == &quot;FLAT&quot;'>
      <b:include data='data' name='flat'/>
    </b:if>
    <b:if cond='data:style == &quot;MENU&quot;'>
      <b:include data='data' name='menu'/>
    </b:if>
  </div>
  </div>
  </div>
</b:includable>
</b:widget>
</b:section-contents>

Delete the fluff Faux Columns

  <div class='body-fauxcolumns'>
    <div class='fauxcolumn-outer body-fauxcolumn-outer'>
    <div class='cap-top'>
      <div class='cap-left'/>
      <div class='cap-right'/>
    </div>
    <div class='fauxborder-left'>
    <div class='fauxborder-right'/>
    <div class='fauxcolumn-inner'>
    </div>
    </div>
    <div class='cap-bottom'>
      <div class='cap-left'/>
      <div class='cap-right'/>
    </div>
    </div>
  </div>

  <div class='content-fauxcolumns'>
    <div class='fauxcolumn-outer content-fauxcolumn-outer'>
    <div class='cap-top'>
      <div class='cap-left'/>
      <div class='cap-right'/>
    </div>
    <div class='fauxborder-left'>
    <div class='fauxborder-right'/>
    <div class='fauxcolumn-inner'>
    </div>
    </div>
    <div class='cap-bottom'>
      <div class='cap-left'/>
      <div class='cap-right'/>
    </div>
    </div>
  </div>

  <div class='content-cap-top cap-top'>
    <div class='cap-left'/>
    <div class='cap-right'/>
  </div>

  <div class='fauxborder-right content-fauxborder-right'/>

    <div class='tabs-outer'>
    <div class='tabs-cap-top cap-top'>
      <div class='cap-left'/>
      <div class='cap-right'/>
    </div>
    <div class='fauxborder-left tabs-fauxborder-left'>
    <div class='fauxborder-right tabs-fauxborder-right'/>
    <div class='region-inner tabs-inner'>
      <b:section class='tabs' id='crosscol' maxwidgets='1' showaddelement='yes'/>
      <b:section class='tabs' id='crosscol-overflow' showaddelement='no'/>
    </div>
    </div>
    <div class='tabs-cap-bottom cap-bottom'>
      <div class='cap-left'/>
      <div class='cap-right'/>
    </div>
    </div>

    <div class='main-cap-top cap-top'>
      <div class='cap-left'/>
      <div class='cap-right'/>
    </div>

    <div class='fauxborder-right main-fauxborder-right'/>

        <div class='fauxcolumn-outer fauxcolumn-center-outer'>
        <div class='cap-top'>
          <div class='cap-left'/>
          <div class='cap-right'/>
        </div>
        <div class='fauxborder-left'>
        <div class='fauxborder-right'/>
        <div class='fauxcolumn-inner'>
        </div>
        </div>
        <div class='cap-bottom'>
          <div class='cap-left'/>
          <div class='cap-right'/>
        </div>
        </div>

        <div class='fauxcolumn-outer fauxcolumn-left-outer'>
        <div class='cap-top'>
          <div class='cap-left'/>
          <div class='cap-right'/>
        </div>
        <div class='fauxborder-left'>
        <div class='fauxborder-right'/>
        <div class='fauxcolumn-inner'>
        </div>
        </div>
        <div class='cap-bottom'>
          <div class='cap-left'/>
          <div class='cap-right'/>
        </div>
        </div>

        <div class='fauxcolumn-outer fauxcolumn-right-outer'>
        <div class='cap-top'>
          <div class='cap-left'/>
          <div class='cap-right'/>
        </div>
        <div class='fauxborder-left'>
        <div class='fauxborder-right'/>
        <div class='fauxcolumn-inner'>
        </div>
        </div>
        <div class='cap-bottom'>
          <div class='cap-left'/>
          <div class='cap-right'/>
        </div>
        </div>

So that all that remains is:

  <div class='content'>
  <div class='content-outer'>
  <div class='fauxborder-left content-fauxborder-left'>
  <div class='content-inner'>
    <div class='main-outer'>
    <div class='fauxborder-left main-fauxborder-left'>
    <div class='region-inner main-inner'>
      <div class='columns fauxcolumns'>
        <!-- corrects IE6 width calculation -->
        <div class='columns-inner'>
        <div class='column-center-outer'>
        <div class='column-center-inner'>
          <b:section class='main' id='main' showaddelement='no'>
<b:widget id='Blog1' locked='true' title='Blog Posts' type='Blog'>

Delete the entire <footer>...</footer>

Delete footer fluff

    <div class='main-cap-bottom cap-bottom'>
      <div class='cap-left'/>
      <div class='cap-right'/>
    </div>

  <div class='content-cap-bottom cap-bottom'>
    <div class='cap-left'/>
    <div class='cap-right'/>
  </div>

So all that remains is

</b:includable>
</b:widget>
</b:section>
        </div>
        </div>

        <div class='column-left-outer'>
        <div class='column-left-inner'>
          <aside>
          <macro:include id='main-column-left-sections' name='sections'>
            <macro:param default='0' name='num' value='0'/>
            <macro:param default='sidebar-left' name='idPrefix'/>
            <macro:param default='sidebar' name='class'/>
            <macro:param default='true' name='includeBottom'/>
          </macro:include>
          </aside>
        </div>
        </div>

        <div class='column-right-outer'>
        <div class='column-right-inner'>
          <aside>
          <macro:include id='main-column-right-sections' name='sections'>
            <macro:param default='2' name='num' value='1'/>
            <macro:param default='sidebar-right' name='idPrefix'/>
            <macro:param default='sidebar' name='class'/>
            <macro:param default='true' name='includeBottom'/>
          </macro:include>
          </aside>
        </div>
        </div>

        </div>

        <div style='clear: both'/>
      <!-- columns -->
      </div>

    <!-- main -->
    </div>
    </div>
    </div>
  <!-- content -->
  </div>
  </div>
  </div>
  </div>

Simplify the top/bottom divs so all that remains is

<b:section class='main' id='main' showaddelement='no'>
<b:widget id='Blog1' locked='true' title='Blog Posts' type='Blog'>
...
</b:widget>
</b:section>

        <div class='column-left-outer'>
        <div class='column-left-inner'>
          <aside>
          <macro:include id='main-column-left-sections' name='sections'>
            <macro:param default='0' name='num' value='0'/>
            <macro:param default='sidebar-left' name='idPrefix'/>
            <macro:param default='sidebar' name='class'/>
            <macro:param default='true' name='includeBottom'/>
          </macro:include>
          </aside>
        </div>
        </div>

        <div class='column-right-outer'>
        <div class='column-right-inner'>
          <aside>
          <macro:include id='main-column-right-sections' name='sections'>
            <macro:param default='2' name='num' value='1'/>
            <macro:param default='sidebar-right' name='idPrefix'/>
            <macro:param default='sidebar' name='class'/>
            <macro:param default='true' name='includeBottom'/>
          </macro:include>
          </aside>
        </div>
        </div>

Now you have a clean content and sidebar that you can layout as you please. I add a single div to center and fixed-width them.

<!-- custom layout -->
<div class='lwide' id='layout'>
<b:section class='main' id='main' showaddelement='no'>
<b:widget id='Blog1' locked='true' title='Blog Posts' type='Blog'>
...
</b:widget>
</b:section>

        <div class='column-left-outer'>
        <div class='column-left-inner'>
          <aside>
          <macro:include id='main-column-left-sections' name='sections'>
            <macro:param default='0' name='num' value='0'/>
            <macro:param default='sidebar-left' name='idPrefix'/>
            <macro:param default='sidebar' name='class'/>
            <macro:param default='true' name='includeBottom'/>
          </macro:include>
          </aside>
        </div>
        </div>

        <div class='column-right-outer'>
        <div class='column-right-inner'>
          <aside>
          <macro:include id='main-column-right-sections' name='sections'>
            <macro:param default='2' name='num' value='1'/>
            <macro:param default='sidebar-right' name='idPrefix'/>
            <macro:param default='sidebar' name='class'/>
            <macro:param default='true' name='includeBottom'/>
          </macro:include>
          </aside>
        </div>
        </div>

</div>
<!-- custom layout -->

Just editing the template won't control your sidebar widgets. You have to do that from Blogger.

Blogger > Layout > About Me > Edit > Remove > Ok
Blogger > Layout > Blog Archive > Edit > Title: [blank] > Save

You can't remove the Header and Attribution widgets. They are auto-added to your sidebar when you delete the header/footer. Backup your template to see them. View-source to see the containing divs. They are hidden by:

/* topbar, title widget, powered-by widget, atom subscription */
#navbar, #Header1, #Attribution1, .feed-links {
 display: none;
}
{ "loggedin": false, "owner": false, "avatar": "", "render": "nothing", "trackingID": "UA-36983794-1", "description": "Tips on customizing Blogger when not using dynamic views.", "page": { "blogIds": [ 62 ] }, "domain": "holtstrom.com", "base": "\/michael", "url": "https:\/\/holtstrom.com\/michael\/", "frameworkFiles": "https:\/\/holtstrom.com\/michael\/_framework\/_files.4\/", "commonFiles": "https:\/\/holtstrom.com\/michael\/_common\/_files.3\/", "mediaFiles": "https:\/\/holtstrom.com\/michael\/media\/_files.3\/", "tmdbUrl": "http:\/\/www.themoviedb.org\/", "tmdbPoster": "http:\/\/image.tmdb.org\/t\/p\/w342" }