windhamdavid 5 years ago
parent
commit
65fce750fb
8 changed files with 446 additions and 62 deletions
  1. 42 4
      functions.php
  2. 13 10
      header.php
  3. 57 0
      inc/utils.php
  4. 14 21
      index.php
  5. 11 13
      js/init.js
  6. 192 0
      js/loop.js
  7. 27 0
      single.php
  8. 90 14
      style.css

+ 42 - 4
functions.php

@@ -4,6 +4,7 @@ if ( ! function_exists( 'dw_setup' ) ):
 function dw_setup() {
 	require( get_template_directory() . '/inc/template.php' );
 	require( get_template_directory() . '/inc/tweaks.php' );
+	require get_template_directory() . '/inc/utils.php';
 }
 endif; 
 add_action( 'after_setup_theme', 'dw_setup' );
@@ -20,17 +21,54 @@ function dw_scripts() {
 	wp_enqueue_style( 'style', get_stylesheet_uri() );
 	//wp_enqueue_style( 'style-min', get_template_directory_uri() . '/css/style.min.css');
 	wp_enqueue_style( 'boot', get_template_directory_uri() . '/css/bootstrap.css');
-	wp_enqueue_style( 'jasny', get_template_directory_uri() . '/css/jasny-bootstrap.css');
+	//wp_enqueue_style( 'jasny', get_template_directory_uri() . '/css/jasny-bootstrap.css');
 	
 	wp_deregister_script('jquery');
 	wp_enqueue_script('jquery', get_template_directory_uri() . '/js/jquery-2.1.1.min.js', array(), false, true);
-	//wp_enqueue_script( 'scripts', get_template_directory_uri() . '/js/scripts.js', 'jquery', '', true );
+	
+	wp_enqueue_script( 'scripts', get_template_directory_uri() . '/js/scripts.js', 'jquery', '', true );
 	wp_enqueue_script( 'script', get_template_directory_uri() . '/js/script.js', 'jquery', '', true );
 	wp_enqueue_script( 'init', get_template_directory_uri() . '/js/init.js', 'jquery', '', true );
+
 	if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
-		wp_enqueue_script( 'comment-reply', '', '', '', true );
-	}
+		wp_enqueue_script( 'comment-reply' );
+	} elseif ( is_home() || is_front_page() || is_archive() || is_search() ) {
+		global $wp_rewrite;
+
+		wp_enqueue_script( '_s_backbone-loop', get_template_directory_uri() . '/js/loop.js', array( 'jquery', 'backbone', 'underscore', 'wp-api'  ), '1.0', true );
+
+		$queried_object = get_queried_object();
 
+		$local = array(
+			'loopType' => 'home',
+			'queriedObject' => $queried_object,
+			'pathInfo' => array(
+				'author_permastruct' => $wp_rewrite->get_author_permastruct(),
+				'host' => preg_replace( '#^http(s)?://#i', '', untrailingslashit( get_option( 'home' ) ) ),
+				'path' => _s_backbone_get_request_path(),
+				'use_trailing_slashes' => $wp_rewrite->use_trailing_slashes,
+				'parameters' => _s_backbone_get_request_parameters(),
+			),
+		);
+
+		if ( is_category() || is_tag() || is_tax() ) {
+			$local['loopType'] = 'archive';
+			$local['taxonomy'] = get_taxonomy( $queried_object->taxonomy );
+		} elseif ( is_search() ) {
+			$local['loopType'] = 'search';
+			$local['searchQuery'] = get_search_query();
+		} elseif ( is_author() ) {
+			$local['loopType'] = 'author';
+		}
+		
+		//set the page we're on so that Backbone can load the proper state
+		if ( is_paged() ) {
+			$local['page'] = absint( get_query_var( 'paged' ) ) + 1;
+		}
+
+		wp_localize_script( '_s_backbone-loop', 'settings', $local );
+	}
+	
 }
 add_action( 'wp_enqueue_scripts', 'dw_scripts' );
 

+ 13 - 10
header.php

@@ -15,20 +15,23 @@
 <?php wp_head(); ?>
 </head>
 <body>
-<header id="header">	
+<header id="header">
+		
 	<div class="navbar navbar-fixed-top" role="navigation">
-		<div class="site-title">
+		<div class="container">
+		<div class="container site-title">
 			<a href="http://davidawindham.com" title="David Windham"><img class="dw" title="David Windham" src="<?php echo get_bloginfo('template_directory');?>/img/dw.png" width="17"/></a>
 			<a href="<?php echo home_url( '/' ); ?>" class="navbar-brand navbar-right" title="David A. Windham" rel="home">David A. Windham</a>			
 		</div>
+		</div>
 		<a href="#" class="nav-toggle navbar-right" data-toggle="offcanvas" data-target=".navmenu" data-canvas="body"><span></span></a>
+	
 	</div>
 </header>
-		<nav class="navmenu navmenu-default navmenu-fixed-right offcanvas" role="complementary">
-			<ul class="nav bs-docs-sidenav">
-				<li><a href="bio">bio</a></li>
-				<li><a href="archive">archives</a></li>
-				<li><a href="contact">contact</a></li>
-			</ul>
-		</nav>
-	<div class="container">
+<nav class="navmenu navmenu-default navmenu-fixed-right offcanvas" role="complementary">
+	<ul class="nav bs-docs-sidenav">
+		<li><a href="bio">bio</a></li>
+		<li><a href="archive">archives</a></li>
+		<li><a href="contact">contact</a></li>
+	</ul>
+</nav>

+ 57 - 0
inc/utils.php

@@ -0,0 +1,57 @@
+<?php
+
+/**
+ * Build path data for current request.
+ *
+ * @return string|bool
+ */
+function _s_backbone_get_request_path() {
+	global $wp_rewrite;
+
+	if ( $wp_rewrite->using_permalinks() ) {
+		global $wp;
+
+		// If called too early, bail
+		if ( ! isset( $wp->request ) ) {
+			return false;
+		}
+
+		// Determine path for paginated version of current request
+		if ( false != preg_match( '#' . $wp_rewrite->pagination_base . '/\d+/?$#i', $wp->request ) ) {
+			$path = preg_replace( '#' . $wp_rewrite->pagination_base . '/\d+$#i', $wp_rewrite->pagination_base . '/%d', $wp->request );
+		} else {
+			$path = $wp->request . '/' . $wp_rewrite->pagination_base . '/%d';
+		}
+
+		// Slashes everywhere we need them
+		if ( 0 !== strpos( $path, '/' ) )
+			$path = '/' . $path;
+
+		$path = user_trailingslashit( $path );
+	} else {
+		// Clean up raw $_REQUEST input
+		$path = array_map( 'sanitize_text_field', $_REQUEST );
+		$path = array_filter( $path );
+
+		$path['paged'] = '%d';
+
+		$path = add_query_arg( $path, '/' );
+	}
+
+	return empty( $path ) ? false : $path;
+}
+
+/**
+ * Return query string for current request, prefixed with '?'.
+ *
+ * @return string
+ */
+function _s_backbone_get_request_parameters() {
+	$uri = $_SERVER[ 'REQUEST_URI' ];
+	$uri = preg_replace( '/^[^?]*(\?.*$)/', '$1', $uri, 1, $count );
+	if ( $count != 1 ) {
+		return '';
+	}
+
+	return $uri;
+}

+ 14 - 21
index.php

@@ -1,27 +1,20 @@
 <?php get_header(); ?>
+<?php get_template_part( 'underscore-templates' ); ?>
 	<div class="container">
 		<div id="content" role="main">
-			<?php if ( have_posts() ) while ( have_posts() ) : the_post(); ?>
-			<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
-				<div class="entry-content">
-					<div class="date">
-						<?php the_date('M j, Y g:i a '); ?>		
-						<div class="meta">
-							<?php dw_posted_at(); ?>
-							<p><small><?php edit_post_link('Edit');?></small><p>
-						</div>
-					</div>
-					<h2 class="entry-title"><a href="<?php the_permalink(); ?>" title="<?php printf( esc_attr__( 'Permalink to %s', 'daw' ), the_title_attribute( 'echo=0' ) ); ?>" rel="bookmark"><?php the_title(); ?></a></h2>
-					<?php the_content(); ?>
-					<?php comments_template( '', true ); ?>
-					<div class="clear">&nbsp;</div>
-					<div id="nav-below" class="navigation">
-						<div class="nav-previous"><?php previous_post_link( '%link', '<span class="meta-nav">' . _x( '&larr;', 'Previous post link', 'daw' ) . '</span> %title' ); ?></div>
-						<div class="nav-next"><?php next_post_link( '%link', '%title <span class="meta-nav">' . _x( '&rarr;', 'Next post link', 'daw' ) . '</span>' ); ?></div>
-					</div>
-				</div>
-			</div>
-			<?php endwhile; ?>
+			<?php if ( have_posts() ) : ?>
+
+				<?php while ( have_posts() ) : the_post(); ?>
+
+					<?php get_template_part( 'content' ); ?>
+
+				<?php endwhile; ?>
+
+			<?php else : ?>
+
+				<?php get_template_part( 'content', 'none' ); ?>
+
+			<?php endif; ?>
 		</div>
 	</div>
 <?php get_footer(); ?>

+ 11 - 13
js/init.js

@@ -1,13 +1,11 @@
 jQuery(document).ready(function($) {
 
-$( '.nav-toggle' ).on( 'click', function() {
+$('.nav-toggle').on( 'click', function() {
 	$( this ).toggleClass( 'active' );
 });
 	
 var headerHeight = $('.navbar').height();
-$(window).on('scroll', {
-	previousTop: 0
-},
+$(window).on('scroll', { previousTop: 0 },
 function() {
     var currentTop = $(window).scrollTop();
     if (currentTop < this.previousTop) {
@@ -25,15 +23,15 @@ function() {
 
 var commentsDiv = $('#comments');
 	if (commentsDiv.length) {
-	$(commentsDiv).hide();
-	$('.toggle-comments').on('click', function(e) {
-		e.preventDefault();
-		$(commentsDiv).toggle('slow', function() {
-			var anchor = $('.toggle-comments');
-			var anchorText = anchor.text() === 'Hide Comments' ? 'Show Comments' : 'Hide Comments';
-			$(anchor).text(anchorText);
+		$(commentsDiv).hide();
+		$('.toggle-comments').on('click', function(e) {
+			e.preventDefault();
+			$(commentsDiv).toggle('slow', function() {
+				var anchor = $('.toggle-comments');
+				var anchorText = anchor.text() === 'Hide Comments' ? 'Show Comments' : 'Hide Comments';
+				$(anchor).text(anchorText);
+			});
 		});
-	});
-}
+	}
 
 });

+ 192 - 0
js/loop.js

@@ -0,0 +1,192 @@
+( function( $, Backbone, _, settings, undefined ) {
+	'use strict';
+
+	var document = window.document;
+
+	var $postContainer = $( document.getElementById( 'main' ) );
+	var moreButtonTemplate = document.getElementById( 'more-button-template' );
+	var contentTemplate = document.getElementById( 'content-template' );
+
+	// Abort completely if we don't have this stuff
+	if ( ! $postContainer || ! moreButtonTemplate || ! contentTemplate ) {
+		return false;
+	}
+
+	var $moreButton = $( _.template( moreButtonTemplate.innerHTML )() );
+	var postTemplate = _.template( contentTemplate.innerHTML );
+
+	var origURL = window.location.href;
+	var offset = 1;
+	var page = 1;
+	var timer;
+
+	var posts = new wp.api.collections.Posts();
+	var options = {
+		data: {
+			page: settings.page || 2
+		}
+	};
+
+	if ( 'archive' === settings.loopType ) {
+		options.data.filter = {};
+		options.data.filter[settings.taxonomy['query_var']] = settings.queriedObject.slug;
+
+	} else if ( 'search' === settings.loopType ) {
+		options.data.filter = {
+			s: settings.searchQuery
+		};
+	} else if ( 'author' === settings.loopType ) {
+		options.data.filter = {
+			author: settings.queriedObject.data.ID
+		};
+	}
+
+	/**
+	 * Update current url using HTML5 history API
+	 *
+	 * @param {Number} pageNum
+	 */
+	function updateURL( pageNum ) {
+		var offset = offset > 0 ? offset - 1 : 0;
+		var pageSlug = ( -1 === pageNum ) ? origURL : window.location.protocol + '//' + settings.pathInfo.host + settings.pathInfo.path.replace( /%d/, pageNum + offset ) + settings.pathInfo.parameters;
+
+		if ( window.location.href !== pageSlug ) {
+			history.pushState( null, null, pageSlug );
+		}
+	}
+
+	/**
+	 * Determine URL for pushing new history. Props to Automattic's Jetpack plugin
+	 * for much of this code.
+	 */
+	function determineURL() {
+		var windowTop = $( window ).scrollTop();
+		var windowBottom = windowTop + $( window ).height();
+		var windowSize = $( window ).height();
+		var setsInView = [];
+		var pageNum = false;
+
+		$postContainer.find( '.post-set' ).each( function() {
+			var $currentSet = $( this );
+
+			var setTop = $currentSet.offset().top;
+			var setHeight = $currentSet.outerHeight( false );
+			var setBottom = setTop + setHeight;
+			var setPageNum = parseInt( $currentSet.attr( 'data-page-num' ) );
+
+			if ( 0 === setHeight ) {
+				$( '> *', this ).each( function() {
+					setHeight += $currentSet.outerHeight( false );
+				});
+			}
+
+			if ( setTop < windowTop && setBottom > windowBottom ) { // top of set is above window, bottom is below
+				setsInView.push( { 'id': $currentSet.attr( 'id' ), 'top': setTop, 'bottom': setBottom, 'pageNum': setPageNum } );
+			} else if( setTop > windowTop && setTop < windowBottom ) { // top of set is between top (gt) and bottom (lt)
+				setsInView.push( { 'id': $currentSet.attr( 'id' ), 'top': setTop, 'bottom': setBottom, 'pageNum': setPageNum } );
+			} else if( setBottom > windowTop && setBottom < windowBottom ) { // bottom of set is between top (gt) and bottom (lt)
+				setsInView.push( { 'id': $currentSet.attr( 'id' ), 'top': setTop, 'bottom': setBottom, 'pageNum': setPageNum } );
+			}
+
+		});
+
+		// Parse number of sets found in view in an attempt to update the URL to match the set that comprises the majority of the window.
+		if ( 0 === setsInView.length ) {
+			pageNum = -1;
+		} else if ( 1 === setsInView.length ) {
+			var setData = setsInView.pop();
+
+			// If the first set of IS posts is in the same view as the posts loaded in the template by WordPress, determine how much of the view is comprised of IS-loaded posts
+			if ( ( ( windowBottom - setData.top ) / windowSize ) < 0.5 ) {
+				pageNum = -1;
+			} else {
+				pageNum = setData.pageNum;
+			}
+		} else {
+			var majorityPercentageInView = 0;
+
+			// Identify the IS set that comprises the majority of the current window and set the URL to it.
+			$.each( setsInView, function( i, setData ) {
+				var topInView = 0;
+				var bottomInView = 0;
+				var percentOfView = 0;
+
+				// Figure percentage of view the current set represents
+				if ( setData.top > windowTop && setData.top < windowBottom ) {
+					topInView = ( windowBottom - setData.top ) / windowSize;
+				}
+
+				if ( setData.bottom > windowTop && setData.bottom < windowBottom ) {
+					bottomInView = ( setData.bottom - windowTop ) / windowSize;
+				}
+
+				// Figure out largest percentage of view for current set
+				if ( topInView >= bottomInView ) {
+					percentOfView = topInView;
+				} else if ( bottomInView >= topInView ) {
+					percentOfView = bottomInView;
+				}
+
+				// Does current set's percentage of view supplant the largest previously-found set?
+				if ( percentOfView > majorityPercentageInView ) {
+					pageNum = setData.pageNum;
+					majorityPercentageInView = percentOfView;
+				}
+			} );
+		}
+
+		// We do this last check in case something bad happened
+		if ( 'number' == typeof pageNum ) {
+			updateURL( pageNum );
+		}
+	}
+
+	/**
+	 * Setup scroll listeners for changing history
+	 */
+	function setupScrollListener() {
+		$( window ).on( 'scroll', function() {
+
+			clearTimeout( timer );
+			timer = setTimeout( determineURL , 100 );
+		});
+	}
+
+	/**
+	 * Grab more posts if more button is clicked and append them to loop
+	 */
+	function setupMoreListener() {
+		$postContainer.on( 'click', '.more-button', function( event ) {
+			event.preventDefault();
+
+			$moreButton.hide();
+
+			var $setContainer = $( '<div data-page-num="' + posts.state.currentPage + '" class="post-set"></div>' );
+			posts.each( function( model ) {
+				$setContainer.append( postTemplate( { post: model.attributes, settings: settings } ) );
+			});
+
+			$postContainer.append( $setContainer );
+
+			if ( posts.hasMore() ) {
+				posts.more().done( function() {
+					$moreButton.appendTo( $postContainer).show();
+				} );
+			}
+		});
+	};
+
+	/**
+	 * Initial posts fetch
+	 */
+	posts.fetch( options ).done( function() {
+
+		if ( posts.length > 0 ) {
+			$postContainer.append( $moreButton );
+
+			setupMoreListener();
+			setupScrollListener();
+		}
+	});
+
+})( jQuery, Backbone, _, settings );

+ 27 - 0
single.php

@@ -0,0 +1,27 @@
+<?php get_header(); ?>
+	<div class="container">
+		<div id="content" role="main">
+			<?php if ( have_posts() ) while ( have_posts() ) : the_post(); ?>
+			<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
+				<div class="entry-content">
+					<div class="date">
+						<?php the_date('M j, Y g:i a '); ?>		
+						<div class="meta">
+							<?php dw_posted_at(); ?>
+							<p><small><?php edit_post_link('Edit');?></small><p>
+						</div>
+					</div>
+					<h2 class="entry-title"><a href="<?php the_permalink(); ?>" title="<?php printf( esc_attr__( 'Permalink to %s', 'daw' ), the_title_attribute( 'echo=0' ) ); ?>" rel="bookmark"><?php the_title(); ?></a></h2>
+					<?php the_content(); ?>
+					<?php comments_template( '', true ); ?>
+					<div class="clear">&nbsp;</div>
+					<div id="nav-below" class="navigation">
+						<div class="nav-previous"><?php previous_post_link( '%link', '<span class="meta-nav">' . _x( '&larr;', 'Previous post link', 'daw' ) . '</span> %title' ); ?></div>
+						<div class="nav-next"><?php next_post_link( '%link', '%title <span class="meta-nav">' . _x( '&rarr;', 'Next post link', 'daw' ) . '</span>' ); ?></div>
+					</div>
+				</div>
+			</div>
+			<?php endwhile; ?>
+		</div>
+	</div>
+<?php get_footer(); ?>

+ 90 - 14
style.css

@@ -35,6 +35,70 @@ body { background: rgba(242,242,242,.7) }
 body,input,textarea {color: #666;font-size: 12px;line-height: 18px;}
 
 
+/*====== Grid ======*/
+.container {
+  padding-right: 15px;
+  padding-left: 15px;
+  margin-right: auto;
+  margin-left: auto;
+}
+@media (min-width: 768px) {
+  .container {
+    width: 750px;
+  }
+}
+@media (min-width: 992px) {
+  .container {
+    width: 970px;
+  }
+}
+@media (min-width: 1200px) {
+  .container {
+    width: 1170px;
+  }
+}
+
+.column, .columns {
+    float: left;
+    display: inline-block;
+    padding: 0 30px;
+    margin-bottom: 30px;
+    margin: 0 auto;
+    -webkit-box-sizing: border-box;
+       -moz-box-sizing: border-box;
+            box-sizing: border-box;
+}
+
+.eight.columns     { width: 100%;  }
+.seven.columns     { width: 87.5%; }
+.six.columns       { width: 75%;   }
+.five.columns      { width: 62.5%; }
+.four.columns      { width: 50%;   }
+.three.columns     { width: 37.5%; }
+.two.columns       { width: 25%;   }
+.one.column        { width: 12.5%; }
+
+.one-third.column  { width: 33.33%;}
+.two-thirds.column { width: 66.66%;}
+
+@media only screen and (max-width: 479px) {
+    .eight.columns,
+    .seven.columns,
+    .six.columns,
+    .five.columns,
+    .four.columns,
+    .three.columns,
+    .two.columns,
+    .one.column,
+    .one-third.column,
+    .two-thirds.column
+    { 
+        width: 100%;
+        margin-bottom: 20px;
+    }
+}
+
+
 /*====== Type ======*/
 
 body {font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 14px;line-height: 1.42857143;}
@@ -43,7 +107,7 @@ input,button,select,textarea {font-family: inherit;font-size: inherit;line-heigh
     font-size: 16px;
 }
 .container {
-	background: #fff;
+
 }
 
 /*===== Structure =====*/
@@ -54,8 +118,6 @@ input,button,select,textarea {font-family: inherit;font-size: inherit;line-heigh
 
 
 /*===== Header =====*/
-
-
 .site-title {
 	float: right;
 	padding: 15px 0;
@@ -83,7 +145,6 @@ img.dw {
 .navbar {
   background-color: rgba(237, 237, 237, 0.7);
 }
-
 .navbar {
   -webkit-transition: background-color 0.3s;
   -moz-transition: background-color 0.3s;
@@ -113,6 +174,21 @@ img.dw {
   transform: translate3d(0, 100%, 0);
 }
 
+
+
+
+
+.offcanvas {
+  display: none;
+}
+.offcanvas.in {
+  display: block;
+}
+.canvas-sliding {
+  -webkit-transition: .25s ease-in-out;
+  transition: .25s ease-in-out;
+}
+
 .navmenu,
 .navbar-offcanvas {
   width: 120px;
@@ -191,6 +267,10 @@ img.dw {
 
 /*===== Content =====*/
 
+.post {
+	background: #ffffff;
+}
+
 
 #content {
 	margin-bottom: 36px;
@@ -660,7 +740,7 @@ li.comment.thread-odd {
 	float: right;
 }
 
-/* Comment form */
+/*====== Comment form ======*/
 #respond {
 	margin-top: 10px;
 }
@@ -721,8 +801,7 @@ img.avatar {
 
 
 
-/* =Gallery listing
--------------------------------------------------------------- */
+/*===== Gallery =====*/
 
 .category-gallery .size-thumbnail img {
 	border: 10px solid #f1f1f1;
@@ -738,8 +817,7 @@ img.avatar {
 }
 
 
-/* =Attachment pages
--------------------------------------------------------------- */
+/*===== Attachments =====*/
 .single-attachment .hentry {
 	margin: 0px;
 }
@@ -779,8 +857,7 @@ img.avatar {
 }
 
 
-/* =Images
--------------------------------------------------------------- */
+/*===== Images ======*/
 
 .img-responsive {
   display: block;
@@ -886,14 +963,13 @@ img.avatar {
 #content .gallery br+br {
 	display: none;
 }
-#content .attachment img { /* single attachment images should be centered */
+#content .attachment img { 
 	display: block;
 	margin: 0 auto;
 }
 
 
-/* =Navigation
--------------------------------------------------------------- */
+/*====== Pagination =====*/
 
 .navigation {
 	color: #888;