Skip to content

Commit

Permalink
Make the theme inherit base, but use the bootstrap3-like gallery
Browse files Browse the repository at this point in the history
  • Loading branch information
Roberto Alsina committed May 2, 2017
1 parent 37644d0 commit 9edb62b
Show file tree
Hide file tree
Showing 5 changed files with 371 additions and 8 deletions.
11 changes: 11 additions & 0 deletions v7/maupassant/assets/css/style.css
Expand Up @@ -495,3 +495,14 @@ a.back_to_top:hover span {
.doc_comments {
margin-top: 0 !important
}

.postpromonav {
border-bottom: 0;
border-top: 0;
margin-top: 1em;
padding: .5em 0;
}

.image-block {
display: inline;
}
271 changes: 271 additions & 0 deletions v7/maupassant/assets/js/flowr.plugin.js
@@ -0,0 +1,271 @@
/**
* Flowr.js - Simple jQuery plugin to emulate Flickr's justified view
* For usage information refer to http://github.com/kalyan02/flowr-js
*
*
* @author: Kalyan Chakravarthy (http://KalyanChakravarthy.net)
* @version: v0.1
*/
(function($) {
//$("#container2").css( 'border', '1px solid #ccc');
$.fn.flowr = function(options) {

$this = this;
var ROW_CLASS_NAME = 'flowr-row'; // Class name for the row of flowy
var MAX_LAST_ROW_GAP = 25; // If the width of last row is lesser than max-width, recalculation is needed
var NO_COPY_FIELDS = ['complete', 'data', 'responsive']; // these attributes will not be carried forward for append related calls
var DEFAULTS = {
'data': [],
'padding': 5, // whats the padding between flowy items
'height': 240, // Minimum height an image row should take
'render': null, // callback function to get the tag
'append': false, // TODO
'widthAttr': 'width', // a custom data structure can specify which attribute refers to height/width
'heightAttr': 'height',
'maxScale': 1.5, // In case there is only 1 elment in last row
'maxWidth': this.width() - 1, // 1px is just for offset
'itemWidth': null, // callback function for width
'itemHeight': null, // callback function for height
'complete': null, // complete callback
'rowClassName': ROW_CLASS_NAME,
'rows': -1, // Maximum number of rows to render. -1 for no limit.
'responsive': true // make content responsive
};
var settings = $.extend(DEFAULTS, options);

// If data is being appended, we already have settings
// If we already have settings, retrieve them
if (settings.append && $this.data('lastSettings')) {
lastSettings = $this.data('lastSettings');

// Copy over the settings from previous init
for (attr in DEFAULTS) {
if (NO_COPY_FIELDS.indexOf(attr) < 0 && settings[attr] == DEFAULTS[attr]) {
settings[attr] = lastSettings[attr];
}
}

// Check if we have an incomplete last row
lastRow = $this.data('lastRow');
if (lastRow.data.length > 0 && settings.maxWidth - lastRow.width > MAX_LAST_ROW_GAP) {
// Prepend the incomplete row to newly loaded data and redraw
lastRowData = lastSettings.data.slice(lastSettings.data.length - lastRow.data.length - 1);
settings.data = lastRowData.concat(settings.data);

// Remove the incomplete row
// TODO: Don't reload this stuff later. Reattach to new row.
$('.' + settings.rowClassName + ':last', $this).detach();
} else {
// console.log( lastRow.data.length );
// console.log( lastRow.width );
}
}

// only on the first initial call
if (!settings.responsive && !settings.append)
$this.width($this.width());

// Basic sanity checks
if (!(settings.data instanceof Array))
return;

if (typeof(settings.padding) != 'number')
settings.padding = parseInt(settings.padding);

if (typeof(settings.itemWidth) != 'function') {
settings.itemWidth = function(data) {
return data[settings.widthAttr];
}
}

if (typeof(settings.itemHeight) != 'function') {
settings.itemHeight = function(data) {
return data[settings.heightAttr];
}
}

// A standalone utility to calculate the item widths for a particular row
// Returns rowWidth: width occupied & data : the items in the new row
var utils = {
getNextRow: function(data, settings) {
var itemIndex = 0;
var itemsLength = data.length;
var lineItems = [];
var lineWidth = 0;
var maxWidth = settings.maxWidth;
var paddingSize = settings.padding;

// console.log( 'maxItems=' + data.length );

requiredPadding = function() {
var extraPads = arguments.length == 1 ? arguments[0] : 0;
return (lineItems.length - 1 + extraPads) * settings.padding;
}

while (lineWidth + requiredPadding() < settings.maxWidth && (itemIndex < itemsLength)) {
var itemData = data[itemIndex];
var itemWidth = settings.itemWidth.call($this, itemData);
var itemHeight = settings.itemHeight.call($this, itemData);

var minHeight = settings.height;
var minWidth = Math.floor(itemWidth * settings.height / itemHeight);


if (minWidth > settings.maxWidth) {
// very short+wide images like panoramas
// show them even if ugly, as wide as possible
minWidth = settings.maxWidth - 1 - requiredPadding(1);
minHeight = settings.height * minHeight / minWidth;
}
var newLineWidth = lineWidth + minWidth;

// console.log( 'lineWidth = ' + lineWidth );
// console.log( 'newLineWidth = ' + newLineWidth );
if (newLineWidth < settings.maxWidth) {
lineItems.push({
'height': minHeight,
'width': minWidth,
'itemData': itemData
});

lineWidth += minWidth;
itemIndex++;
} else {
// We'd have exceeded width. So break off to scale.
// console.log( 'breaking off = ' + itemIndex );
// console.log( 'leave off size = ' + lineItems.length );
break;
}
} //while

// Scale the size to max width
testWidth = 0;
if (lineWidth < settings.maxWidth) {
var fullScaleWidth = settings.maxWidth - requiredPadding() - 10;
var currScaleWidth = lineWidth;
var scaleFactor = fullScaleWidth / currScaleWidth;
if (scaleFactor > settings.maxScale)
scaleFactor = 1;

var newHeight = Math.round(settings.height * scaleFactor);
for (i = 0; i < lineItems.length; i++) {
var lineItem = lineItems[i];
lineItem.width = Math.floor(lineItem.width * scaleFactor);
lineItem.height = newHeight;

testWidth += lineItem.width;
}
}

return {
data: lineItems,
width: testWidth + requiredPadding()
};
}, //getNextRow
reorderContent: function() {
/*
TODO: optimize for faster resizing by reusing dom objects instead of killing the dom
*/
var _initialWidth = $this.data('width');
var _newWidth = $this.width();
var _change = _initialWidth - _newWidth;

if (_initialWidth != _newWidth) {
$this.html('');
var _settings = $this.data('lastSettings');
_settings.data = $this.data('data');
_settings.maxWidth = $this.width() - 1;
$this.flowr(_settings);
}
}
} //utils

// If the responsive var is set to true then listen for resize method
// and prevent resizing from happening twice if responsive is set again during append phase!
if (settings.responsive && !$this.data('__responsive')) {
$(window).resize(function() {
initialWidth = $this.data('width');
newWidth = $this.width();

//initiate resize
if (initialWidth != newWidth) {
var task_id = $this.data('task_id');
if (task_id) {
task_id = clearTimeout(task_id);
task_id = null;
}
task_id = setTimeout(utils.reorderContent, 80);
$this.data('task_id', task_id);
}
});
$this.data('__responsive', true);
}


return this.each(function() {

// Get a copy of original data. 1 level deep copy is sufficient.
var data = settings.data.slice(0);
var rowData = null;
var currentRow = 0;
var currentItem = 0;

// Store all the data
var allData = [];
for (i = 0; i < data.length; i++) {
allData.push(data[i]);
}
$this.data('data', allData);

// While we have a new row
while ((rowData = utils.getNextRow(data, settings)) != null && rowData.data.length > 0) {
if (settings.rows > 0 && currentRow >= settings.rows)
break;
// remove the number of elements in the new row from the top of data stack
data.splice(0, rowData.data.length);

// Create a new row div, add class, append the htmls and insert the flowy items
var $row = $('<div>').addClass(settings.rowClassName);
var slack = $this[0].clientWidth - rowData.width - 2 * settings.padding
for (i = 0; i < rowData.data.length; i++) {
var displayData = rowData.data[i];
// Get the HTML object from custom render function passed as argument
var displayObject = settings.render.call($this, displayData);
displayObject = $(displayObject);
extraw = Math.floor(slack/rowData.data.length)
if (i == 0) {
extraw += slack % rowData.data.length
}
// Set some basic stuff
displayObject
.css('width', displayData.width + extraw)
.css('height', displayData.height)
.css('margin-bottom', settings.padding + "px")
.css('margin-left', i == 0 ? '0' : settings.padding + "px"); //TODO:Refactor
$row.append(displayObject);

currentItem++;
}
$this.append($row);
// console.log ( "I> rowData.data.length="+rowData.data.length +" rowData.width="+rowData.width );

currentRow++;
$this.data('lastRow', rowData);
}
// store the current state of settings and the items in last row
// we'll need this info when we append more items
$this.data('lastSettings', settings);

// onComplete callback
// pass back info about list of rows and items rendered
if (typeof(settings.complete) == 'function') {
var completeData = {
renderedRows: currentRow,
renderedItems: currentItem
}
settings.complete.call($this, completeData);
}
});
};

})(jQuery);
1 change: 1 addition & 0 deletions v7/maupassant/templates/base_helper.tmpl
Expand Up @@ -104,6 +104,7 @@ lang="${lang}">


<%def name="html_stylesheets()">
<link href="/assets/css/theme.css" type="text/css" rel="stylesheet"/>
<link href="/assets/css/pure.css" type="text/css" rel="stylesheet"/>
<link href="/assets/css/style.css" type="text/css" rel="stylesheet"/>
% if needs_ipython_css:
Expand Down
74 changes: 74 additions & 0 deletions v7/maupassant/templates/gallery.tmpl
@@ -0,0 +1,74 @@
## -*- coding: utf-8 -*-
<%inherit file="base.tmpl"/>
<%namespace name="comments" file="comments_helper.tmpl"/>
<%namespace name="ui" file="crumbs.tmpl" import="bar"/>
<%block name="sourcelink"></%block>

<%block name="content">
${ui.bar(crumbs)}
%if title:
<h1>${title|h}</h1>
%endif
%if post:
<p>
${post.text()}
</p>
%endif
%if folders:
<ul>
% for folder, ftitle in folders:
<li><a href="${folder}"><i class="glyphicon glyphicon-folder-open"></i>&nbsp;${ftitle|h}</a></li>
% endfor
</ul>
%endif

<div id="gallery_container"></div>
%if site_has_comments and enable_comments:
${comments.comment_form(None, permalink, title)}
%endif
</%block>

<%block name="extra_head">
${parent.extra_head()}
<link rel="alternate" type="application/rss+xml" title="RSS" href="rss.xml">
</%block>

<%block name="extra_js">
<script src="/assets/js/flowr.plugin.js"></script>
<script>
jsonContent = ${photo_array_json};
$("#gallery_container").flowr({
data : jsonContent,
height : ${thumbnail_size}*.6,
padding: 5,
rows: -1,
render : function(params) {
// Just return a div, string or a dom object, anything works fine
img = $("<img />").attr({
'src': params.itemData.url_thumb,
'width' : params.width,
'height' : params.height
}).css('max-width', '100%');
link = $( "<a></a>").attr({
'href': params.itemData.url,
'class': 'image-reference'
});
div = $("<div />").addClass('image-block').attr({
'title': params.itemData.title
});
link.append(img);
div.append(link);
return div;
},
itemWidth : function(data) { return data.size.w; },
itemHeight : function(data) { return data.size.h; },
complete : function(params) {
if( jsonContent.length > params.renderedItems ) {
nextRenderList = jsonContent.slice( params.renderedItems );
}
}
});
$("a.image-reference").colorbox({rel:"gal", maxWidth:"100%",maxHeight:"100%",scalePhotos:true});
$('a.image-reference[href="'+window.location.hash.substring(1,1000)+'"]').click();
</script>
</%block>

0 comments on commit 9edb62b

Please sign in to comment.