Compare commits

...

6 Commits

54 changed files with 3104 additions and 1961 deletions

7
.gitignore vendored
View File

@ -15,6 +15,13 @@ mode.php
###################
# we don't need to sync these everywhere
vendor/
node_modules/
# Compiled CSS and JS #
#######################
# these will be compiled as needed
public/css/
public/js/
# Audio and video files #
#########################

65
Gruntfile.js Normal file
View File

@ -0,0 +1,65 @@
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
sass: {
dist: {
options: {
style: 'compressed'
},
files: [{
expand: true,
cwd: 'assets/sass',
src: ['**/*.sass'],
dest: 'public/css',
ext: '.css'
}]
}
},
coffee: {
options: {
sourceMap: true,
style: 'compressed'
},
files: {
expand: true,
flatten: true,
cwd: 'assets/coffee',
src: ['*.coffee'],
dest: 'public/js',
ext: '.js'
}
},
watch: {
css: {
files: ['assets/sass/**/*.sass'],
tasks: ['sass'],
options: {
atBegin: true,
spawn: false
}
},
js: {
files: ['assets/coffee/*.coffee'],
tasks: ['coffee'],
options: {
atBegin: true,
spawn: false
}
}
}
});
// Load plugins.
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-coffee');
grunt.loadNpmTasks('grunt-contrib-watch');
// Default task(s).
grunt.registerTask('default', ['sass', 'coffee']);
};

View File

@ -1,34 +0,0 @@
<?php
namespace Fieldprotocol\Music;
use Illuminate\Database\Eloquent\Model as Eloquent;
class Album extends Eloquent {
protected $table = 'albums';
protected $fillable = [
'title',
'description',
'album_art',
'release_date',
];
public function songs() {
return $this->hasMany('Fieldprotocol\Music\Song');
}
public function links() {
return $this->hasMany('Fieldprotocol\Music\StoreLink', 'album_id');
}
public function releaseDate() {
return date('F j, Y', strtotime($this->release_date));
}
public function releaseYear() {
return date('Y', strtotime($this->release_date));
}
}

View File

@ -1,22 +0,0 @@
<?php
namespace Fieldprotocol\Music;
use Illuminate\Database\Eloquent\Model as Eloquent;
class Song extends Eloquent {
protected $table = 'songs';
protected $fillable = [
'title',
'album_id',
'track_order',
'audio_file',
];
public function album() {
return $this->belongsTo('Fieldprotocol\Music\Album');
}
}

View File

@ -1,20 +0,0 @@
<?php
namespace Fieldprotocol\Music;
use Illuminate\Database\Eloquent\Model as Eloquent;
class StoreLink extends Eloquent {
protected $table = 'store_links';
protected $fillable = [
'link_name',
'link_ref',
];
public function album() {
return $this->belongsTo('Fieldprotocol\Music\Album', 'album_id');
}
}

View File

@ -1,57 +0,0 @@
<?php
namespace Fieldprotocol\User;
use Illuminate\Database\Eloquent\Model as Eloquent;
class User extends Eloquent {
protected $table = 'users';
protected $fillable = [
'id',
'username',
'first_name',
'last_name',
'email',
'posts'
];
public function getFullName() {
if (!$this->first_name || !$this->last_name) {
return null;
}
return "{$this->first_name} {$this->last_name}";
}
public function getName() {
return $this->getFullName() ?: $this->username;
}
public function getAvatarUrl($options = []) {
$size = isset($options['size']) ? $options['size'] : 45;
return 'http://www.gravatar.com/avatar/' . md5($this->email) . '?s=' . $size . '&d=identicon';
}
/*public function permissions() {
return $this->hasOne('Fieldprotocol\User\UserPermission', 'user_id');
}
public function hasPermission($permission) {
return (bool) $this->permissions->{$permission};
}
public function isAdmin() {
return $this->hasPermission('is_admin');
}
public function isEditor() {
return $this->hasPermission('is_editor');
}
public function isAuthor() {
return $this->hasPermission('is_author');
}*/
}

View File

@ -1,35 +0,0 @@
<?php
return [
'app' => [
'url' => 'https://halftoneband.com',
'hash' => [
'algo' => PASSWORD_BCRYPT,
'cost' => 10,
],
],
'db' => [
'driver' => 'mysql',
'host' => 'db.example.com',
'name' => 'db_name',
'username' => 'db_user',
'password' => 'db_secret',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
],
'auth' => [
'session' => 'user_id',
'remember' => 'user_r',
],
'twig' => [
'debug' => true,
],
'csrf' => [
'key' => 'csrf_token',
],
];

View File

@ -1,18 +0,0 @@
<?php
use Illuminate\Database\Capsule\Manager as Capsule;
$capsule = new Capsule;
$capsule->addConnection([
'driver' => $app->config->get('db.driver'),
'host' => $app->config->get('db.host'),
'database' => $app->config->get('db.name'),
'username' => $app->config->get('db.username'),
'password' => $app->config->get('db.password'),
'charset' => $app->config->get('db.charset'),
'collation' => $app->config->get('db.collation'),
'prefix' => $app->config->get('db.prefix'),
]);
$capsule->bootEloquent();

View File

@ -1,31 +0,0 @@
<?php
$authenticationCheck = function($required) use ($app) {
return function() use ($required, $app) {
if ((!$app->auth && $required) || ($app->auth && !$required)) {
if (!$app->auth && $required) {
$app->flash('global', 'Hey buddy, you need to sign in first!');
} else if ($app->auth && !$required) {
$app->flash('global', 'Woah there, why do you want to do that?');
}
$app->redirect($app->urlFor('home'));
}
};
};
$authenticated = function() use ($authenticationCheck) {
return $authenticationCheck(true);
};
$guest = function() use ($authenticationCheck) {
return $authenticationCheck(false);
};
$admin = function() use ($app) {
return function() use ($app) {
if (!$app->auth || !$app->auth->isAdmin()) {
$app->flash('global', 'You don\'t have permissions for that, man.');
$app->redirect($app->urlFor('home'));
}
};
};

View File

@ -1,15 +0,0 @@
<?php
// Main view routes
require 'routes/pages/index.php';
require 'routes/pages/about.php';
require 'routes/pages/contact.php';
require 'routes/pages/home.php';
require 'routes/pages/music.php';
require 'routes/pages/shows.php';
// API routes
require 'routes/apiv1/music.php';
// Errors
require 'routes/errors/404.php';

View File

@ -1,38 +0,0 @@
<?php
// retrieve album info
$app->get('/apiv1/music/album-info/:albumid', function($albumid) use($app) {
if (!ctype_digit($albumid)) {
echo 'Don\'t do that';
return;
}
$album = $app->album->where('id', $albumid)->first();
if ($album) {
echo json_encode($album);
} else {
$app->notFound();
}
})->name('apiv1.music.album-info');
// retrieve an album's songs
$app->get('/apiv1/music/album-songs/:albumid', function($albumid) use($app) {
if (!ctype_digit($albumid)) {
echo 'Don\'t do that';
return;
}
$album = $app->album->where('id', $albumid)->first();
if ($album) {
$json = ['songs' => $album->songs];
echo json_encode($json);
} else {
$app->notFound();
}
})->name('apiv1.music.album-songs');

View File

@ -1,5 +0,0 @@
<?php
$app->notFound(function() use ($app) {
$app->render('errors/404.twig');
});

View File

@ -1,7 +0,0 @@
<?php
$app->get('/about', function() use($app) {
$app->render('pages/about.twig');
})->name('about');

View File

@ -1,7 +0,0 @@
<?php
$app->get('/contact', function() use($app) {
$app->render('pages/contact.twig');
})->name('contact');

View File

@ -1,7 +0,0 @@
<?php
$app->get('/home', function() use($app) {
$app->render('pages/home.twig');
})->name('home');

View File

@ -1,7 +0,0 @@
<?php
$app->get('/', function() use($app) {
$app->response->redirect($app->urlFor('home'), '303');
})->name('index');

View File

@ -1,16 +0,0 @@
<?php
// music page
$app->get('/music', function() use($app) {
$albums = $app->album->all()->sortByDesc('release_date')->values()->all();
$songs = $albums[0]->songs;
$links = $albums[0]->links;
$app->render('pages/music.twig', [
'albums' => $albums,
'songs' => $songs,
'links' => $links,
]);
})->name('music');

View File

@ -1,32 +0,0 @@
<?php
$app->get('/shows', function() use($app) {
$shows = json_decode(file_get_contents('http://api.bandsintown.com/artists/HALFtone/events.json?api_version=2.0&app_id=shows_halftoneband.com'));
foreach ($shows as $show) {
$show->date = date('M dS', strtotime($show->datetime));
$show->day = date('D', strtotime($show->datetime));
$show->time = date('H:i', strtotime($show->datetime));
}
$app->render('pages/shows.twig', [
'shows' => $shows,
]);
})->name('shows');
$app->get('/shows/json', function() use($app) {
$shows = json_decode(file_get_contents('http://api.bandsintown.com/artists/HALFtone/events.json?api_version=2.0&app_id=shows_halftoneband.com'));
foreach ($shows as $show) {
$show->date = date('M dS', strtotime($show->datetime));
$show->day = date('D', strtotime($show->datetime));
$show->time = date('H:i', strtotime($show->datetime));
print_r($show);
echo '<br /><br />';
}
die();
})->name('shows.json');

View File

@ -1,73 +0,0 @@
<?php
// Slim deps
use Slim\Slim;
use Slim\Views\Twig;
use Slim\Views\TwigExtension;
// Config struff
use Noodlehaus\Config;
// Our dependencies
use Fieldprotocol\Music\Album;
use Fieldprotocol\Music\Song;
// Let's get this session started
session_cache_limiter(false);
session_start();
// For now, display some errors
ini_set('display_errors', 'On');
// The app's root directory
define('INC_ROOT', dirname(__DIR__));
// Autoload our stuff >:D
require INC_ROOT . '/vendor/autoload.php';
// Time to create our app
$app = new Slim([
'mode' => trim(file_get_contents(INC_ROOT . '/mode.php')),
'view' => new Twig(),
'templates.path' => INC_ROOT . '/app/views'
]);
// Run some crap before the middleware
//$app->add(new BeforeMiddleware);
//$app->add(new CSRFMiddleware);
$app->configureMode($app->config('mode'), function() use ($app) {
$app->config = Config::load(INC_ROOT . "/app/config/{$app->mode}.php");
});
// Database configs
require 'database.php';
// Filters
require 'filters.php';
// Routes configs
require 'routes.php';
//$app->auth = false;
// Album singleton
$app->container->set('album', function() {
return new Album;
});
// Song singleton
$app->container->set('song', function() {
return new Song;
});
// Slappin' some hoes with our views
$view = $app->view();
$view->parserOptions = [
'debug' => $app->config->get('twig.debug')
];
$view->setTemplatesDirectory('../app/views');
$view->parserExtensions = [
new TwigExtension()
];
// Run Slim
$app->run();

View File

@ -6,6 +6,7 @@
img
+position(absolute, 0 null null 0)
+size(100% 480px)
background: #212121
/*+filter(blur(2px))
.about-band

3
bin/php-run.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/sh
php -S localhost:8080 -t public public/index.php

23
composer.json Executable file → Normal file
View File

@ -1,15 +1,24 @@
{
"name": "halftone/website",
"description": "HalfTone website",
"type": "project",
"license": "BSD-2-Clause",
"autoload": {
"psr-4": {
"Fieldprotocol\\": "app/Fieldprotocol"
"Halftone\\Website\\": "src/"
}
},
"authors": [
{
"name": "Gregory Ballantine",
"email": "gballantine@metaunix.net"
}
],
"minimum-stability": "stable",
"require": {
"slim/slim": "^2.6",
"slim/views": "^0.1.3",
"twig/twig": "^1.18",
"illuminate/database": "^5.0",
"hassankhan/config": "^0.8.2",
"alexgarrett/violin": "^2.2"
"slim/slim": "^4.11",
"slim/psr7": "^1.6",
"slim/twig-view": "^3.3",
"php-di/php-di": "^7.0"
}
}

1596
composer.lock generated Executable file → Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

1741
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

30
package.json Normal file
View File

@ -0,0 +1,30 @@
{
"name": "halftone-website",
"version": "1.0.0",
"description": "HalfTone website",
"main": "index.js",
"scripts": {
"grunt": "grunt",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "https://git.metaunix.net/HalfTone/website.git"
},
"keywords": [
"halftone",
"music",
"website",
"rock"
],
"author": "Gregory Ballantine <gballantine@metaunix.net>",
"license": "BSD-2-Clause",
"devDependencies": {
"grunt": "^1.6.1",
"grunt-cli": "^1.4.3",
"grunt-contrib-coffee": "^2.1.0",
"grunt-contrib-sass": "^2.0.0",
"grunt-contrib-watch": "^1.1.0",
"sass": "^1.62.1"
}
}

729
public/css/main.css Executable file → Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 663 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

After

Width:  |  Height:  |  Size: 1.6 MiB

BIN
public/img/about/jake.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 660 KiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 295 KiB

View File

@ -1,3 +1,23 @@
<?php
require '../app/start.php';
// if we're looking for static files in dev, return false so they can be served.
if (PHP_SAPI == 'cli-server') {
$url = parse_url($_SERVER['REQUEST_URI']);
$file = __DIR__ . $url['path'];
// check the file types, only serve standard files
if (preg_match('/\.(?:png|js|jpg|jpeg|gif|css)$/', $file)) {
// does the file exist? If so, return it
if (is_file($file))
return false;
// file does not exist. return a 404
header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found');
printf('"%s" does not exist', $_SERVER['REQUEST_URI']);
return false;
}
}
require_once __DIR__ . '/../src/start.php';
$app->run();

View File

@ -1,11 +0,0 @@
(function() {
$(function() {
$.get('https://api.bandsintown.com/artists/Skrillex/events.json?', {
'api_version': '2.0',
'app_id': 'shows_halftoneband.com'
}, function(data) {
alert(data);
});
});
}).call(this);

View File

@ -1,6 +0,0 @@
(function() {
$(document).ready(function() {
return console.log('Hey there, lad!');
});
}).call(this);

View File

@ -1,18 +0,0 @@
(function() {
(function($) {
$.fn.alert = function() {
return this.each(function() {
var self;
self = $(this);
self.on('click', '.close-button', function(e) {
e.preventDefault();
self.addClass('close');
});
self.on('transitionEnd webkitTransitionEnd oTransitionEnd', function() {
self.remove();
});
});
};
})(jQuery);
}).call(this);

View File

@ -1,22 +0,0 @@
(function() {
$(function() {
var awesomeInput, checkInput;
awesomeInput = '.awesome-form .input-group input';
checkInput = function(elem) {
var text_val;
text_val = $(elem).val();
if (text_val === '') {
$(elem).removeClass('has-value');
} else {
$(elem).addClass('has-value');
}
};
$(awesomeInput).focusout(function() {
checkInput(this);
});
$(awesomeInput).on('change', function() {
checkInput(this);
});
});
}).call(this);

View File

@ -1,53 +0,0 @@
(function($){
$.fn.musicPlayer = function(opt) {
var settings, player, getVolume, setVolume, isPlaying, play, pause, getTime, setTime;
settings = $.extend({
'audio': '#music-player',
'volume': .5,
'startTime': 0
}, opt);
player = $(settings.player);
getVolume = function() {
return player.prop('volume');
}
setVolume = function(volume) {
player.prop('volume', volume);
};
isPlaying = function() {
return !player.prop('paused');
};
play = function() {
if (!isPlaying()) {
player.trigger('play');
}
};
pause = function() {
if (isPlaying()) {
player.trigger('pause');
}
};
getTime = function() {
return player.prop('currentTime');
};
setTime = function(time) {
player.prop('currentTime', time);
};
// Default actions
setVolume(settings.volume);
setTime(setTime.startTime);
};
})(jQuery);

View File

@ -1,158 +0,0 @@
var player = '';
$(document).ready(function() {
player = $('#music-player').get(0);
// set the player's volume to 0.5 by default
player.volume = 0.5;
// on music track click
$('.now-playing-list').on('click', '.music-track', function() {
// change selected track
changeSelectedTrack(this);
});
// on album art click
$('.music-album').on('click', '.thumbnail', function() {
// change selected album
changeSelectedAlbum(this);
});
// on track end
$(player).on('ended', function() {
// find selected track
changeSelectedTrack($('.music-track.selected').next().get(0));
});
});
function changeSelectedAlbum(albumElem) {
var oldSelected = $('.music-album.selected');
var newSelected = $(albumElem).parent();
if (oldSelected.data('albumid') != newSelected.data('albumid')) {
// remove selected class from the old element and add it to the new one
oldSelected.removeClass('selected');
newSelected.addClass('selected');
// change album info
getAlbumInfo(albumElem);
// change available songs
getAlbumSongs(albumElem);
}
}
function getAlbumInfo(albumElem) {
albumElem = $(albumElem).parent();
$.get('/apiv1/music/album-info/' + albumElem.data('albumid'), function(data) {
var json = $.parseJSON(data);
// change album artwork
$('#album-artwork').attr('src', json.album_art);
// change album title
$('#album-title').text(json.title);
// change album release date
$('#album-release span').text(formatReleaseDate(json.release_date));
// change album description
$('#album-description').text(json.description);
});
}
function formatReleaseDate(d) {
var monthNames = [
"January", "February", "March",
"April", "May", "June", "July",
"August", "September", "October",
"November", "December"
];
var date = new Date(d);
var day = date.getDate();
var monthIndex = date.getMonth();
var year = date.getFullYear();
return monthNames[monthIndex] + ' ' + day + ', ' + year;
}
function getAlbumSongs(albumElem) {
albumElem = $(albumElem).parent();
$.get('/apiv1/music/album-songs/' + albumElem.data('albumid'), function(data) {
var json = $.parseJSON(data);
var playlist = $('.now-playing-list');
playlist.empty();
for (var i = 0; i < json.songs.length; i++) {
var song = json.songs[i];
var songElem = $('<li></li>')
.addClass('music-track')
.attr('data-trackid', song.id)
.attr('data-title', song.title)
.attr('data-album', song.album_id)
.attr('data-order', song.track_order)
.attr('data-path', song.audio_file);
if (i === 0) {
songElem.addClass('selected');
}
songElem.html('<span>' + song.track_order + '. ' + song.title + '</span>');
playlist.append(songElem);
}
changeAudioSources(playlist.find('.selected'), false);
});
}
function changeSelectedTrack(trackElem) {
var oldSelected = $('.now-playing-list .music-track.selected');
var newSelected = $(trackElem);
if (oldSelected.data('trackid') != newSelected.data('trackid')) {
// remove selected class from the old element and add it to the new one
oldSelected.removeClass('selected');
newSelected.addClass('selected');
// now change the audio sources
changeAudioSources(trackElem, true);
}
}
function changeAudioSources(trackElem, autoplay) {
trackElem = $(trackElem);
var playerSources = $('#music-player source');
if (autoplay === null) {
autoplay = false;
}
// retrieve audio file path from selected element
var audioFilePath = trackElem.data('path');
// loop through the audio player source elements
playerSources.each(function() {
// jQuery-ize the element
source = $(this);
if (source.attr('type') == 'audio/ogg') {
// OGG source file
source.attr('src', audioFilePath + '.ogg');
} else if (source.attr('type') == 'audio/mpeg') {
// MP3 source file
source.attr('src', audioFilePath + '.mp3');
}
});
// change track title
$('#track-title').text(trackElem.data('title'));
// reload music player
player.load();
if (autoplay) {
// start playing new song
player.play();
}
}

View File

@ -0,0 +1,19 @@
<?php
namespace Halftone\Website\Controllers;
use Psr\Container\ContainerInterface;
class Controller {
protected $container;
public function __construct(ContainerInterface $container) {
$this->container = $container;
}
public function get(string $name) {
return $this->container->get($name);
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace Halftone\Website\Controllers;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Views\Twig;
class HomeController extends Controller {
public function getIndex(Request $request, Response $response): Response {
$view = Twig::fromRequest($request);
return $view->render($response, 'pages/home.twig', []);
}
public function getAbout(Request $request, Response $response): Response {
$view = Twig::fromRequest($request);
return $view->render($response, 'pages/about.twig', []);
}
public function getContact(Request $request, Response $response): Response {
$view = Twig::fromRequest($request);
return $view->render($response, 'pages/contact.twig', []);
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace Halftone\Website\Controllers;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Views\Twig;
class MusicController extends Controller {
public function getIndex(Request $request, Response $response): Response {
$view = Twig::fromRequest($request);
return $view->render($response, 'pages/music.twig', []);
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace Halftone\Website\Controllers;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Views\Twig;
class ShowsController extends Controller {
public function getIndex(Request $request, Response $response): Response {
$view = Twig::fromRequest($request);
return $view->render($response, 'pages/shows.twig', []);
}
}

16
src/routes.php Executable file
View File

@ -0,0 +1,16 @@
<?php
// index GET route - this page should welcome the user
$app->get('/', '\\Halftone\\Website\\Controllers\\HomeController:getIndex')->setName('home');
// about GET route - display information about the band!
$app->get('/about', '\\Halftone\\Website\\Controllers\\HomeController:getAbout')->setName('about');
// contact GET route - display the band's contact info
$app->get('/contact', '\\Halftone\\Website\\Controllers\\HomeController:getContact')->setName('contact');
// music routes group
$app->get('/music', '\\Halftone\\Website\\Controllers\\MusicController:getIndex')->setName('music.index');
// shows routes group
$app->get('/shows', '\\Halftone\\Website\\Controllers\\ShowsController:getIndex')->setName('shows.index');

31
src/start.php Executable file
View File

@ -0,0 +1,31 @@
<?php
use DI\Container;
use Slim\Factory\AppFactory;
use Slim\Views\Twig;
use Slim\Views\TwigMiddleware;
require __DIR__ . '/../vendor/autoload.php';
// Let's get this session started
session_cache_limiter(false);
session_start();
// For now, display some errors
ini_set('display_errors', 'On');
// Create new container object
$container = new Container();
// Set container to create App with on AppFactory
AppFactory::setContainer($container);
$app = AppFactory::create();
// Create Twig
$twig = Twig::create(__DIR__ . '/../views', ['cache' => false]);
// Add Twig-View Middleware
$app->add(TwigMiddleware::create($app, $twig));
// Database configs
//require 'database.php';
// Routes configs
require 'routes.php';

View File

@ -5,7 +5,7 @@
{% block content %}
<header id="about-header" class="row shadow-1">
<div class="col-xs-12">
<img class="img-responsive" src="/img/about/halftone.jpg" alt="halftone">
<img id="about-header-image" class="img-responsive" src="/img/logo-white.png" alt="halftone">
</div>
<div class="about-band col-xs-12">
<h2>About the Band</h2><br/>
@ -43,24 +43,12 @@
<div class="caption">
<h3>Wyatt Hamilton</h3>
<hr />
<h4>Lead vocals/Guitar</h4>
<h4>Lead Vocals/Guitar</h4>
<p>World's "okay-est" guitarist... and we're using "okay" loosely.</p>
</div>
<a href="#"></a>
</div>
</section>
<section class="col-md-6 col-xs-12">
<div class="thumbnail shadow-1">
<img src="img/about/andrew.jpg" alt="Andrew Hall">
<div class="caption">
<h3>Andrew Hall</h3>
<hr />
<h4>Bass Guitar</h4>
<p>Ginger, enough said.</p>
</div>
<a href="#"></a>
</div>
</section>
<section class="col-md-6 col-xs-12">
<div class="thumbnail shadow-1">
<img src="img/about/greg.jpg" alt="Gregory Ballantine">
@ -73,14 +61,14 @@
<a href="#"></a>
</div>
</section>
<section class="col-md-6 col-xs-12">
<section class="col-md-6 col-md-offset-3 col-xs-12">
<div class="thumbnail shadow-1">
<img src="img/about/zakk.jpg" alt="Zakk Vigneri">
<img src="img/about/jake.jpg" alt="Jake the Snake!">
<div class="caption">
<h3>Zakk Vigneri</h3>
<h3>Jake Lahoff</h3>
<hr />
<h4>Lead guitar/Backing vocals</h4>
<p>The Amateur Hour champion!</p>
<h4>Bass Guitar/Backing Vocals</h4>
<p>Taking the bass to the mainstream!</p>
</div>
<a href="#"></a>
</div>

View File

@ -20,19 +20,19 @@
<div class="collapse navbar-collapse" id="navbar-collapse">
<ul class="nav navbar-nav">
<li class="nav_item">
<a href="{{ urlFor('home') }}">Home</a>
<a href="{{ url_for('home') }}">Home</a>
</li>
<li class="nav_item">
<a href="{{ urlFor('about') }}">About</a>
<a href="{{ url_for('about') }}">About</a>
</li>
<li class="nav_item">
<a href="{{ urlFor('shows') }}">Shows</a>
<a href="{{ url_for('shows.index') }}">Shows</a>
</li>
<li class="nav_item">
<a href="{{ urlFor('music') }}">Music</a>
<a href="{{ url_for('music.index') }}">Music</a>
</li>
<li class="nav_item">
<a href="{{ urlFor('contact') }}">Contact</a>
<a href="{{ url_for('contact') }}">Contact</a>
</li>
</ul>
</div>