HirshHorn theme: how I created it

2,633 views

Published on

Slides from the talk I gave at WordCamp toronto 2012 full of snippets of code and techniques I used to create the HIshHorh Sliding WordPress Theme

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
2,633
On SlideShare
0
From Embeds
0
Number of Embeds
16
Actions
Shares
0
Downloads
5
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

HirshHorn theme: how I created it

  1. 1. The HirshHorn Theme How I created itSnippets of code and techniques I used
  2. 2. Credits Client: Hirshhorn Museum and Sculpture Garden , Smithsonian, Washington, D.C. Design: Bruce Mau Design Media Agency: Art & Science (formerly Juice).  Technical director: Spencer Saunders  WordPress coding: Paul Bearne
  3. 3. This might not be the only or bestway! What you will see is how I solved the problems at the point in time (Sept 2011) when I did this project. There is a lot of WordPress code in this talk; I am assuming that you can read and understand the code! I am using code snippets so that I can get them on the slides, so not all the comments or code are shown!
  4. 4. Notes At the end I am going to ask what you found the most useful Slides @ http://www.slideshare.net/pbearne
  5. 5. Overview Demo
  6. 6. Wire frame Layout menuPrev page … Current page Next page … footer Screen
  7. 7. Viewsource<body class="single single-collection postid-1349"><div id="wrapper" class="hfeed"> <div id="header"> Standard WP menu header </div><!-- #header--> <div id="main"> <div id="container"> <div id="content"> <div class="entry-content" id="makeMeScrollable"> <div id="detail-of..." data-id="7639" title="Detail of..." class="hhh_T_6 jsf_LoadViaAjax post-7639 collection type-collection status-publish hentry" ></div> <div id="..." data-id="3734" title="...“ class="hhh_T_3 jsf_LoadViaAjax post-3734 collection type-collection status-publish hentry"></div> ...... </div> </div> </div> </div></div></body>
  8. 8. <div id="home" data-id="1349" title="Home" class="hhh_T_7 jsf_Loaded post-1349 collection type-collection status-publishhentry" <div id="page10" class="jst_BoxContanerhhh_template10"> <div class="hhh_link hhh_box13 hhh_item_1"> <a href="http://link to bio"> <img src="...." /></a> </div> <div class="hhh_box2 hhh_item_2"> <h4>Headline text</h4> <p>Random text</p> </div> <div class="hhh_videoInline hhh_box8hhh_item_3"> http://youtu.be/DeYZVBzty0w </div>
  9. 9. The scrolling plugin http://www.smoothdivscroll.com (forked version)$(document).ready(function () { $("#makeMeScrollable").smoothDivScroll({ mousewheelScrolling: "allDirections", manualContinuousScrolling: true, autoScrollingMode: "onStart" });}); Note: not all the settings I used are shown
  10. 10. Changes to smoothdevscrollswapLastToFirst: function(){ var self = this, el = this.element, o = this.options; el.data("swappedElement", el.data("scrollableArea") .children(":last").detach());el.data("scrollableArea").prepend(el.data("swappedElement")); el.data("scrollWrapper") .scrollLeft(el.data("scrollWrapper") .scrollLeft() + el.ata("swappedElement") .outerWidth(true));el.data("getNextElementWidth", true);el.data("enabled", true);self._showHideHotSpots();
  11. 11. Changes to smoothdevscroll_updateHash : function(){var self = this, el = this.element, o = this.options, allBoxContaners=[], CurrentScrollLeft, currentDivId = 0$(#makeMeScrollable.scrollableArea).children(div).each(function(index,element){allBoxContaners.push([$(element).attr(id), Math.round($(element).position().left)])});CurrentScrollLeft = $(".scrollWrapper").scrollLeft()if(allBoxContaners.length > 0){ while(allBoxContaners[currentDivId][1] < CurrentScrollLeft - ($(window).width()/2)+100 ){ currentDivId ++; } var wall = allBoxContaners[i][0] if ($.bbq.getState("collection") != wall){ $.bbq.pushState({collection : wall }); }
  12. 12. Keeping state and bookmarkswww.hirshhorn.si.edu/collection/home/#collection=home#collection=doug-aitken-2&detail=http%3A//www.hirshhorn.si.edu/bio/doug-aitken-interviews/&title=Doug+Aitken+Interviews
  13. 13. JQUERY BBQ: BACK BUTTON & QUERYLIBRARY HTTP://BENALMAN.COM/PROJECTS/JQUERY-BBQ-PLUGIN// PUSH THIS URL "STATE" ONTO THE HISTORY HASH.$.BBQ.PUSHSTATE({ URL: HREF });$(WINDOW).BIND( "HASHCHANGE", FUNCTION(E) { PUT THE ACTION CODE HERE}$(WINDOW).TRIGGER( "HASHCHANGE" );
  14. 14. Over riding the menu URLsjQuery(#menu a).live(click, function(e) { var href = this.href; // does the clicked URL and current URL have /collection/ inthe path? if (href.indexOf(/collection/) > 0 &&document.URL.indexOf(/collection/) > 0){ var clickId = href.toLowerCase().split(/); // remove any current state jQuery.bbq.removeState("wall", "title", "detail"); // and set new state jQuery.bbq.pushState({ collection: clickId }); // stop any other on-clicks e.stopImmediatePropagation(); return false; }
  15. 15. Example hashchange functionjQuery(window).bind("hashchange", function(e) { collectionURL = jQuery.bbq.getState("collection"); // try to get an title from somewhere. title = jQuery.bbq.getState("title") ? jQuery.bbq.getState("title") : jQuery(# + collectionURL).attr(title); document.title = title; if (undefined === collectionURL) { collectionURL = jQuery(.jsf_Loaded).attr(id); }jQuery("div#makeMeScrollable").smoothDivScroll("scrollToElement","id", collectionURL);}
  16. 16. Example wall fragment<div class="hhh_link hhh_box13 hhh_item_1"> <a href="http://www.hirshhorn.si.edu/collection/dark-matters/"> <img src="...." /> </a></div>
  17. 17. Example wall click action// add the scroll to action to wall linksjQuery(.hhh_link a).on(click, function(e) { var clickId = this.href.toLowerCase().split(/); var l = clickId.length if ( clickId[l-1].length > 1){ var scrollToId = clickId[l-1] }else{ var scrollToId = clickId[l-2] }jQuery("div#makeMeScrollable").smoothDivScroll("scrollToElement", "id",scrollToId);// stop any other onclickse.stopImmediatePropagation()return false;}); Note: no hashchange this is done in the move finished callback from smoothDivScroll
  18. 18. Using a menu to store the orderregister_nav_menu( „collection‟, Select the slider contentmenu.);
  19. 19. Collection page PHP// get the menu object for theme menu location “collection”$menu_items =wp_get_nav_menu_items($locations[collection;]);// loop the menu object again to insert the current page andupdate the div before and 4 dev‟s after so that content weloaded on page loadforeach ( (array) $menu_items as $key => $menu_item ) { $title = $menu_item->title; $url = $menu_item->url; $id = $menu_item->object_id; $templateId= hhh_T_.get_post_meta($id, hhh_template_Id,true). ; $slug = basename(get_permalink($id));// is this post in the menu the current postif ($post->ID == $id) { Next slide……
  20. 20. Collection page PHPif ($post->ID == $id) { //check it not a single post to handle preview if(count($array_of_divs)>0){ $last_id = $array_of_divs[count($array_of_divs)-1][0]; $div_text = <div id=".basename(get_permalink($last_id))." title=".$last_id." class=".$templateId.implode(" ",get_post_class("jsf_ajaxOnLoad",$last_id))." ></div> ; array_pop($array_of_divs); // remove the last empty div array_push( $array_of_divs , array($last_id , $div_text) ); // add it back in with extra class "jsf_ajaxOnLoad" } // load the content into a div $div_text = <div id=".basename(get_permalink($id))." title=".$id."class=".$templateId.jsf_Loaded .implode(" ",get_post_class("",$id)).">.get_the_content().</div> ; $jsf_ajaxOnLoad = 5;}else{
  21. 21. Collection page PHP}else{ if ($jsf_ajaxOnLoad > 0){ // 4 div after the loadedcontent $jsf_ajaxOnLoad -- ; $extra_class_test =$templateId."jsf_ajaxOnLoad "; }else{ $extra_class_test =$templateId."jsf_LoadViaAjax "; } $div_text = <divid=".basename(get_permalink($id))." title=".$id."class=".$extra_class_test.implode("",get_post_class("",$id))." ></div> ;
  22. 22. Collection page PHP<div class="entry-content" id="makeMeScrollable"> <?php foreach ( (array)$array_of_divs as $jsf_div){ echo($jsf_div[1]); } ?></div><!-- .entry-content -->
  23. 23. Now to call AJAX in WordPressURL: /wp-admin/admin-ajax.php?action=show_content_ajax_calladd_action(wp_ajax_show_content_ajax_call,array( $this, jsf_show_content_ajax));add_action(wp_ajax_nopriv_show_content_ajax_call, array( $this, jsf_show_content_ajax));
  24. 24. Content fetch AJAX PHP functionfunction jsf_show_content_ajax($id){ $postID = $_POST[postID]; $content_post = get_post($postID); $content = $content_post->post_content; $content = apply_filters(the_content, $content); $jsonpost = array(); $jsonpost["id"] = $postID; $jsonpost["slug"] = basename(get_permalink($postID) $jsonpost["content"] = str_replace(]]>, ]]>, $content); header( Content-Type: application/json ); echo json_encode($jsonpost);; exit;}
  25. 25. Content fetch AJAX functionscrollerRightLimitReached: function() { $("div#makeMeScrollable").smoothDivScroll("swapFirstToLast"); if($(#makeMeScrollable .scrollableArea).children(":last").html().length <= 1){ var id = $(#makeMeScrollable .scrollableArea).children(":last").attr("id") $.ajax({ url:"/wp-admin/admin-ajax.php", type:POST, dataType: json, data:action=show_content_ajax_call&postID=+$(#+id).attr("title")+&t=3&slu+ id, success:function(results){// load into div $(# + results[slug]).html(results[content]); $(# + results[slug]+ .jst_BoxContaner).hide().fadeIn();; $(# + results[slug]).removeClass(jsf_ajaxOnLoad); } }) }}
  26. 26. Custom content in TinyMCE
  27. 27. TinyMCE editor cssCreate a editor-style.css file in your theme rootadd_editor_style();Tip: use the same style sheet in the themewp_register_style(jsf_BoxStyles, get_stylesheet_directory_uri()./editor-style.css);wp_enqueue_style( jsf_BoxStyles)http://codex.wordpress.org/Function_Reference/add_editor_style
  28. 28. Injecting code into the TinyMCEeditor Server sideadd_filter(default_content, my_editor_content);function my_editor_content( $content ) { $content = "If you enjoyed this post, make sure to subscribe to myrss feed."; return $content;} Client sidevar jsf_ed = tinyMCE.activeEditor;jsf_ed.selection.select(jsf_ed.getBody(), true);window.send_to_editor(“<div>content);
  29. 29. How to add button to tinyMCE editor// Add only in Rich Editor modeif ( get_user_option(rich_editing) == true) { add_filter("mce_external_plugins","add_hhh_custom_tinymce_plugin"); add_filter(mce_buttons, register_hhh_custom_button);}
  30. 30. How to add button to tinyMCE editorfunction register_hhh_custom_button($buttons) { array_push($buttons, "|", "hhh_highlight"); return $buttons;}function add_hhh_custom_tinymce_plugin($plugin_array){ $plugin_array[hhh_highlight] =get_stylesheet_directory_uri()./mce/editor_plugin.js; return $plugin_array;}
  31. 31. editor_plugin.js(function() { tinymce.create(tinymce.plugins.hhh_highlightPlugin, { init : function(ed, url) { ed.addCommand(mceHighlight, function() { ed.windowManager.open({ file : url + /set_behavior.htm, width : 400,height : 600 ,inline : 1 }, {plugin_url : url}); }); ed.addButton(hhh_highlight, {title : Highlight, cmd : mceHighlight, image:url + /hhhicon.gif }); }, getInfo : function() {return {longname : Set Behavior,author : PaulBearne,authorurl : http://www.bearne.ca,infourl :http://www.thejuiceagency.com,version : tinymce.majorVersion + "." +tinymce.minorVersion }; } });tinymce.PluginManager.add(hhh_highlight, tinymce.plugins.hhh_highlightPlugin);})();
  32. 32. How to add button to full screeneditorfunction hhh_fullscreen_buttons($buttons){ $buttons[] = separator; // add a separator $buttons[hhh_highlight] = array( title => __(Highlighter), // Title of the button onclick =>"tinyMCE.execCommand(mceHighlight);", both =>false// Show on visual AND html mode ); return $buttons;}add_filter( wp_fullscreen_buttons,hhh_fullscreen_buttons );
  33. 33. Slides @ http://www.slideshare.net/pbearne
  34. 34. How to read from TinyMCE editor<script type="text/javascript" src="/wp-admin/load-scripts.php?c=1&load=jquery &ver=XXXX"></script><script type="text/javascript" src="/wp-includes/js/tinymce/tiny_mce_popup.js?v=3211"></script>var HighlightDialog = { local_ed : ed, init : function(ed) { HighlightDialog.local_ed = ed; if (jQuery.trim( HighlightDialog.local_ed.selection.getContent()).length < 1){ tinyMCEPopup.execCommand(mceSelectNodeDepth,false,0);} // if we did get with above if lets walk out untill we dowhile (-1 ==HighlightDialog.local_ed.selection.getContent().indexOf("hhh_box")) ){ tinyMCEPopup.execCommand(mceSelectNodeDepth,false,1);}tinyMCEPopup.resizeToInnerSize();}, Cont on next
  35. 35. How to write to TinyMCE editorCont. from last slide..insert : function insertHighlightSection(ed) { // get selected text output =HighlightDialog.local_ed.selection.getContent();….. Change it as needed …………… // write the value back to the editor replace allcontent tinyMCEPopup.execCommand(mceInsertRawHTML, false, output); tinyMCEPopup.close(); // all done close the popup};// call on load function tinyMCEPopup.onInit.add(HighlightDialog.init,
  36. 36. PopUp pages in dialogs Used to provide extended detail
  37. 37. If is a detail page then show in adialogdialog = jQuery(<div class="hhh_dialog" id="dialog“style="display:hidden"></div>).appendTo(body);dialog.load( jQuery.bbq.getState("detail"),{}, function(responseText, textStatus, XMLHttpRequest) { dialog.dialog({ modal: true,height: 720,width: 1050,position: top,closeText: X , open: function(event, ui) {jQuery("div#makeMeScrollable").smoothDivScroll("scrollToElement", "id", jQuery.bbq.getState("collection") ); }, close: function(event, ui) { jQuery.bbq.removeState("detail"); }, });
  38. 38. If not an AJAX call then redirectif(!empty($_SERVER[HTTP_X_REQUESTED_WITH]) &&strtolower($_SERVER[HTTP_X_REQUESTED_WITH]) ==xmlhttprequest) { $ajaxcall = true;}if(!$ajaxcall){ $hhh_rediect_url =get_post_meta(get_the_ID(),_hhh_rediect_url,TRUE); if (strlen($hhh_rediect_url) > 0){ $hhh_rediect_url .= #detail=. get_permalink(); ?><script type="text/javascript">/* <![CDATA[ */ window.location = "<?php echo$hhh_rediect_url ?>" /* ]]> */</script><?php }}else{ the_post()}
  39. 39. The links Slides @ http://www.slideshare.net/pbearne @pbearne pbearne@gmail.com

×