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. This might not be the only or best
way!
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. Notes
At the end I am going to ask what you found the
most useful
Slides @ http://www.slideshare.net/pbearne
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. Changes to smoothdevscroll
swapLastToFirst: 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("swappedElem
ent"));
el.data("scrollWrapper")
.scrollLeft(el.data("scrollWrapper")
.scrollLeft() + el.ata("swappedElement")
.outerWidth(true));
el.data("getNextElementWidth", true);
el.data("enabled", true);
self._showHideHotSpots();
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. Keeping state and bookmarks
www.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. JQUERY BBQ: BACK BUTTON & QUERY
LIBRARY
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. Over riding the menu URLs
jQuery('#menu a').live('click', function(e) {
var href = this.href;
// does the clicked URL and current URL have '/collection/' in
the 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. Example hashchange function
jQuery(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. 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. Example wall click action
// add the scroll to action to wall links
jQuery('.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 onclicks
e.stopImmediatePropagation()
return false;
});
Note: no hashchange this is done in the move finished callback from
smoothDivScroll
18. Using a menu to store the order
register_nav_menu( „collection‟, 'Select the slider content
menu.');
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 and
update the div before and 4 dev‟s after so that content we
loaded on page load
foreach ( (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 post
if ($post->ID == $id) {
Next slide……
20. Collection page PHP
if ($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. Collection page PHP
}else{
if ($jsf_ajaxOnLoad > 0){ // 4 div after the loaded
content
$jsf_ajaxOnLoad -- ;
$extra_class_test =
$templateId."jsf_ajaxOnLoad ";
}else{
$extra_class_test =
$templateId."jsf_LoadViaAjax ";
}
$div_text = '<div
id="'.basename(get_permalink($id)).'" title="'.$id.'"
class="'.$extra_class_test.implode("
",get_post_class("",$id)).'" ></div>' ;
27. TinyMCE editor css
Create a editor-style.css file in your theme root
add_editor_style();
Tip: use the same style sheet in the theme
wp_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. Injecting code into the TinyMCE
editor
Server side
add_filter('default_content', 'my_editor_content');
function my_editor_content( $content ) {
$content = "If you enjoyed this post, make sure to subscribe to my
rss feed.";
return $content;
}
Client side
var jsf_ed = tinyMCE.activeEditor;
jsf_ed.selection.select(jsf_ed.getBody(), true);
window.send_to_editor(“<div>content);
29. How to add button to tinyMCE editor
// Add only in Rich Editor mode
if ( 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. How to add button to tinyMCE editor
function 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;
}
32. How to add button to full screen
editor
function 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' );
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 do
while (-1 ==
HighlightDialog.local_ed.selection.getContent().indexOf("hhh_box")) ){
tinyMCEPopup.execCommand('mceSelectNodeDepth',false,1);}
tinyMCEPopup.resizeToInnerSize();
}, Cont on next
35. How to write to TinyMCE editor
Cont. 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 all
content
tinyMCEPopup.execCommand('mceInsertRawHTM
L', false, output);
tinyMCEPopup.close(); // all done close the popup
};
// call on load function
tinyMCEPopup.onInit.add(HighlightDialog.init,
36. PopUp pages in dialogs
Used to provide extended detail
37. If is a detail page then show in a
dialog
dialog = 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. If not an AJAX call then redirect
if(!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()
}