Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f08081a129 | |||
| 8c4754ae8d | |||
| fccaa6a326 | |||
| 3073231d38 | |||
| 0d522e1cd1 |
@@ -1,4 +1,3 @@
|
|||||||
mode:regex
|
wwwroot/*
|
||||||
^_dist/
|
nbproject/*
|
||||||
^sites/[^/]+/data/
|
data/*
|
||||||
^sites/[^/]+/wwwroot/
|
|
||||||
16
TODO.txt
@@ -1,16 +0,0 @@
|
|||||||
|
|
||||||
- Support project redirection (e.g. `code.ivysaur.me` was renamed to `codesite`, breaking links)
|
|
||||||
|
|
||||||
- If no projects have any images, don't generate spritesheet
|
|
||||||
|
|
||||||
- Move tag javascript and no-image image out of per-site configuration
|
|
||||||
|
|
||||||
- Merge "written in" and "tags"
|
|
||||||
|
|
||||||
- Per-project directories, to prevent overwriting files (e.g. 'screenshot.jpg')
|
|
||||||
|
|
||||||
- Cache recent changes somehow
|
|
||||||
|
|
||||||
- RSS for recent changes
|
|
||||||
|
|
||||||
- RSS for all projects
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
A static site generator for a portfolio website.
|
|
||||||
|
|
||||||
The scripts used to generate the code.ivysaur.me website.
|
|
||||||
|
|
||||||
Written in PHP, Bash
|
|
||||||
|
|
||||||
=FEATURES=
|
|
||||||
|
|
||||||
- Generates static website, minimising server load and decreasing attack surface compared to dynamic server-side PHP
|
|
||||||
- Automatic thumbnailing and sprite sheet generation
|
|
||||||
- Download file attachments per-project
|
|
||||||
- One-click rebuild, one-click deploy
|
|
||||||
- Parallel generation
|
|
||||||
|
|
||||||
=CHANGELOG=
|
|
||||||
|
|
||||||
2015-04-05: r64
|
|
||||||
- Feature: Support sorting projects
|
|
||||||
|
|
||||||
2015-04-04: r54
|
|
||||||
- Feature: Support multiple code sites
|
|
||||||
- Fix an issue with parallel builds on some versions of windows
|
|
||||||
- Fix an issue corrupting URL links with multiple parameters
|
|
||||||
- Fix a cosmetic issue with page overflow
|
|
||||||
- Fix a cosmetic issue with whitespace on code elements
|
|
||||||
|
|
||||||
2014-07-02: r39
|
|
||||||
- Feature: Tags
|
|
||||||
- Feature: Generate pages in parallel
|
|
||||||
- Enhancement: Support raw HTML sections in page content
|
|
||||||
- Fix an issue with URLs containing spaces
|
|
||||||
- Fix a cosmetic issue with image thumbnail backgrounds
|
|
||||||
- Fix a cosmetic issue with download sort order
|
|
||||||
- Fix a cosmetic issue with page layout
|
|
||||||
|
|
||||||
2013-09-28: r13
|
|
||||||
- Initial public source code release
|
|
||||||
|
|
||||||
2013-09-21: r3
|
|
||||||
- Initial deployment
|
|
||||||
3
deploy.cmd
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
@echo off
|
||||||
|
|
||||||
|
start C:\path\to\cygwin\bin\mintty.exe /bin/bash -l -c "rsync -avz -e ""ssh -i /cygdrive/c/path/to/deploy_key"" --progress /cygdrive/c/path/to/code/wwwroot www-data@your-web-server:/var/www/path/to/code-site/"
|
||||||
16
deploy.sh
@@ -1,16 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
LOCALDIR=/cygdrive/c/www/m6/code/sites/code.ivysaur.me/wwwroot
|
|
||||||
|
|
||||||
chmod -R 644 "$LOCALDIR"
|
|
||||||
chmod -R a+X "$LOCALDIR"
|
|
||||||
|
|
||||||
rsync --delete -avz -e "ssh -i /cygdrive/c/www/ms1_deploy_key -p 2222" --progress \
|
|
||||||
"$LOCALDIR" \
|
|
||||||
www-data@ms1.ivysaur.me:~/code.ivysaur.me/
|
|
||||||
|
|
||||||
# n.b. set chmod -R a+rX remote side?
|
|
||||||
|
|
||||||
read -p "Press any key to continue..."
|
|
||||||
8
homepage_blurb.htm
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
<p>
|
||||||
|
Homepage blurb goes here.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>PROJECTS</strong>
|
||||||
|
</p>
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
tar cJvf "codesite-$(date +%s).tar.xz" \
|
|
||||||
rebuild.php rebuild.sh sites/codesite.example.com static_global \
|
|
||||||
--owner=0 --group=0
|
|
||||||
|
|
||||||
read -p "Press any key to continue..."
|
|
||||||
3
rebuild.cmd
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
@echo off
|
||||||
|
C:\path\to\php_54\php.exe rebuild.php
|
||||||
|
pause
|
||||||
107
rebuild.php
@@ -3,6 +3,16 @@
|
|||||||
// Code-hosting website
|
// Code-hosting website
|
||||||
// ````````````````````
|
// ````````````````````
|
||||||
|
|
||||||
|
// CONFIGURATION
|
||||||
|
// `````````````
|
||||||
|
|
||||||
|
define('BASEDIR', __DIR__.'\\');
|
||||||
|
define('SITE_TITLE', 'codesite');
|
||||||
|
define('PAGE_THUMB_W', 60);
|
||||||
|
define('PAGE_THUMB_H', 60);
|
||||||
|
define('INDEX_THUMB_W', 90);
|
||||||
|
define('INDEX_THUMB_H', 32); // recommend a multiple of the jpg iDCT block size
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a thumbnail of an image. It overscales, centers, and crops to fit the
|
* Create a thumbnail of an image. It overscales, centers, and crops to fit the
|
||||||
* target dimensions.
|
* target dimensions.
|
||||||
@@ -87,6 +97,23 @@ function hesc($sz) {
|
|||||||
|
|
||||||
function text2html($sz) {
|
function text2html($sz) {
|
||||||
|
|
||||||
|
$sectionFmt = function($sz) {
|
||||||
|
$base = hesc($sz);
|
||||||
|
|
||||||
|
$base = preg_replace('~=+(.+)=+~', '<strong>\\1</strong>', $base);
|
||||||
|
$base = preg_replace('~(https?://[^ \\r\\n\\t]+)~i', '<a href="\\1">\\1</a>', $base);
|
||||||
|
|
||||||
|
$btparts = explode('`', $base);
|
||||||
|
if (count($btparts) > 1 && (count($btparts) % 2)) {
|
||||||
|
for ($i = 1, $e = count($btparts); $i < $e; $i += 2) {
|
||||||
|
$btparts[$i] = '<span class="code">'.$btparts[$i].'</span>';
|
||||||
|
}
|
||||||
|
$base = implode('', $btparts);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nl2br($base);
|
||||||
|
};
|
||||||
|
|
||||||
$identity = function($sz) {
|
$identity = function($sz) {
|
||||||
return $sz;
|
return $sz;
|
||||||
};
|
};
|
||||||
@@ -111,22 +138,6 @@ function text2html($sz) {
|
|||||||
return implode($join, $ret);
|
return implode($join, $ret);
|
||||||
};
|
};
|
||||||
|
|
||||||
$sectionFmt = function($sz) use($oddEven, $identity) {
|
|
||||||
$base = hesc($sz);
|
|
||||||
|
|
||||||
$base = preg_replace('~^=+(.+)=+~m', '<strong>\\1</strong>', $base);
|
|
||||||
$base = preg_replace('~(https?://[^ \\r\\n\\t]+)~i', '<a href="\\1">\\1</a>', $base);
|
|
||||||
|
|
||||||
$btparts = explode('`', $base);
|
|
||||||
if (count($btparts) > 1 && (count($btparts) % 2)) {
|
|
||||||
for ($i = 1, $e = count($btparts); $i < $e; $i += 2) {
|
|
||||||
$btparts[$i] = '<span class="code">'.$btparts[$i].'</span>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $oddEven($btparts, $identity, 'nl2br');
|
|
||||||
};
|
|
||||||
|
|
||||||
$htmlSections = $splitInside('<html>', '</html>', $sz);
|
$htmlSections = $splitInside('<html>', '</html>', $sz);
|
||||||
return $oddEven($htmlSections, $identity, $sectionFmt);
|
return $oddEven($htmlSections, $identity, $sectionFmt);
|
||||||
}
|
}
|
||||||
@@ -151,7 +162,6 @@ class CProject {
|
|||||||
public $projname;
|
public $projname;
|
||||||
public $shortdesc = '(no description)';
|
public $shortdesc = '(no description)';
|
||||||
public $subtag = '';
|
public $subtag = '';
|
||||||
public $lastupdate = 0;
|
|
||||||
private $longdesc = '';
|
private $longdesc = '';
|
||||||
private $images = array();
|
private $images = array();
|
||||||
private $downloads = array();
|
private $downloads = array();
|
||||||
@@ -170,8 +180,6 @@ class CProject {
|
|||||||
if ($file[0] == '.') continue;
|
if ($file[0] == '.') continue;
|
||||||
|
|
||||||
if ($file == 'README.txt') {
|
if ($file == 'README.txt') {
|
||||||
$this->lastupdate = max($this->lastupdate, filectime($this->dir.$file)); // don't count README updates
|
|
||||||
|
|
||||||
$this->longdesc = file_get_contents($this->dir.'README.txt');
|
$this->longdesc = file_get_contents($this->dir.'README.txt');
|
||||||
$matches = array();
|
$matches = array();
|
||||||
if (preg_match('~Written in ([^\\r\\n]+)~', $this->longdesc, $matches)) {
|
if (preg_match('~Written in ([^\\r\\n]+)~', $this->longdesc, $matches)) {
|
||||||
@@ -188,12 +196,6 @@ class CProject {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->lastupdate = max(
|
|
||||||
$this->lastupdate,
|
|
||||||
filemtime($this->dir.$file),
|
|
||||||
filectime($this->dir.$file)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (is_image($file)) {
|
if (is_image($file)) {
|
||||||
$this->images[] = $file;
|
$this->images[] = $file;
|
||||||
} else {
|
} else {
|
||||||
@@ -209,7 +211,7 @@ class CProject {
|
|||||||
if (count($this->images)) {
|
if (count($this->images)) {
|
||||||
|
|
||||||
$this->homeimage = mkthumbnail(
|
$this->homeimage = mkthumbnail(
|
||||||
$this->dir.$this->images[0],
|
$this->dir.$this->images[0], //BASEDIR.'wwwroot/srv/'.$this->projname.'_0.'.str_ext($this->images[0]),
|
||||||
null, // raw handle
|
null, // raw handle
|
||||||
INDEX_THUMB_W, INDEX_THUMB_H
|
INDEX_THUMB_W, INDEX_THUMB_H
|
||||||
);
|
);
|
||||||
@@ -262,7 +264,7 @@ class CProject {
|
|||||||
|
|
||||||
<p><?=text2html($this->longdesc)?></p>
|
<p><?=text2html($this->longdesc)?></p>
|
||||||
|
|
||||||
<?=file_get_contents(BASEDIR.'/footer.htm')?>
|
<?=file_get_contents(__DIR__.'/footer.htm')?>
|
||||||
|
|
||||||
<?php if (count($this->downloads)) { ?>
|
<?php if (count($this->downloads)) { ?>
|
||||||
|
|
||||||
@@ -287,9 +289,6 @@ class CProject {
|
|||||||
<a href="srv/<?=hesc(urlencode($this->projname))?>_<?=$idx?>.<?=str_ext($origname)?>"><img src="srv/<?=hesc(urlencode($this->projname))?>_<?=$idx?>_thumb.jpg" class="thumbimage"></a>
|
<a href="srv/<?=hesc(urlencode($this->projname))?>_<?=$idx?>.<?=str_ext($origname)?>"><img src="srv/<?=hesc(urlencode($this->projname))?>_<?=$idx?>_thumb.jpg" class="thumbimage"></a>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="clear:both;"></div>
|
|
||||||
|
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -316,7 +315,7 @@ function template($title, $content) {
|
|||||||
<body>
|
<body>
|
||||||
<div id="container">
|
<div id="container">
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<?=file_get_contents(BASEDIR.'/header.htm')?>
|
<?=file_get_contents(__DIR__.'/header.htm')?>
|
||||||
<?=$content?>
|
<?=$content?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -369,8 +368,6 @@ function buildcommon() {
|
|||||||
$handles = array();
|
$handles = array();
|
||||||
$handle_lookup = array();
|
$handle_lookup = array();
|
||||||
|
|
||||||
$alphasort = [];
|
|
||||||
|
|
||||||
foreach($projects as $dirname => $projectname) {
|
foreach($projects as $dirname => $projectname) {
|
||||||
|
|
||||||
$pr = new CProject($dirname, $projectname);
|
$pr = new CProject($dirname, $projectname);
|
||||||
@@ -384,18 +381,6 @@ function buildcommon() {
|
|||||||
$handle_lookup[$projectname] = count($handles);
|
$handle_lookup[$projectname] = count($handles);
|
||||||
$handles[] = $pr->homeimage;
|
$handles[] = $pr->homeimage;
|
||||||
}
|
}
|
||||||
|
|
||||||
$alphasort[] = [$pr->projname, count($plist)-1];
|
|
||||||
}
|
|
||||||
|
|
||||||
usort($alphasort, function($a, $b) {
|
|
||||||
return strcasecmp($a[0], $b[0]);
|
|
||||||
});
|
|
||||||
|
|
||||||
$alphaidx = [];
|
|
||||||
|
|
||||||
foreach($alphasort as $a) {
|
|
||||||
$alphaidx[ $a[1] ] = count($alphaidx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build homepage spritesheet
|
// Build homepage spritesheet
|
||||||
@@ -414,13 +399,9 @@ function buildcommon() {
|
|||||||
<!-- }} -->
|
<!-- }} -->
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
|
||||||
<table id="projtable-main" class="projtable">
|
<table class="projtable">
|
||||||
<?php foreach ($plist as $i => $pr) { ?>
|
<?php foreach ($plist as $pr) { ?>
|
||||||
<tr class="<?=$pr->getClassAttr()?>"
|
<tr class="<?=$pr->getClassAttr()?>">
|
||||||
data-sort-mt="-<?=$pr->lastupdate?>"
|
|
||||||
data-sort-ct="<?=$i?>"
|
|
||||||
data-sort-al="<?=$alphaidx[$i]?>"
|
|
||||||
>
|
|
||||||
<td>
|
<td>
|
||||||
<a href="<?=hesc(urlencode($pr->projname))?>.html"><?=(is_null($handle_lookup[$pr->projname]) ? '<div class="no-image"></div>' : '<div class="homeimage homeimage-sprite" style="background-position:0 -'.($handle_lookup[$pr->projname]*INDEX_THUMB_H).'px"></div>')?></a>
|
<a href="<?=hesc(urlencode($pr->projname))?>.html"><?=(is_null($handle_lookup[$pr->projname]) ? '<div class="no-image"></div>' : '<div class="homeimage homeimage-sprite" style="background-position:0 -'.($handle_lookup[$pr->projname]*INDEX_THUMB_H).'px"></div>')?></a>
|
||||||
</td>
|
</td>
|
||||||
@@ -453,31 +434,9 @@ function buildcommon() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function main($args) {
|
function main($args) {
|
||||||
$basedir = './';
|
|
||||||
$total = $args[0];
|
$total = $args[0];
|
||||||
$pos = $args[1];
|
$pos = $args[1];
|
||||||
|
|
||||||
// Parse configuration
|
|
||||||
|
|
||||||
$config = @parse_ini_file(
|
|
||||||
$basedir . 'config.ini',
|
|
||||||
true,
|
|
||||||
INI_SCANNER_RAW
|
|
||||||
);
|
|
||||||
|
|
||||||
if ($config === false) {
|
|
||||||
die("[FATAL] Couldn't load '${basedir}/config.ini'!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
define('BASEDIR', $basedir);
|
|
||||||
define('SITE_TITLE', trim($config['codesite']['title']));
|
|
||||||
define('PAGE_THUMB_W', intval($config['codesite']['page_thumb_w']));
|
|
||||||
define('PAGE_THUMB_H', intval($config['codesite']['page_thumb_h']));
|
|
||||||
define('INDEX_THUMB_W', intval($config['codesite']['index_thumb_w']));
|
|
||||||
define('INDEX_THUMB_H', intval($config['codesite']['index_thumb_h']));
|
|
||||||
|
|
||||||
// Perform build tasks
|
|
||||||
|
|
||||||
if ($pos == 0) {
|
if ($pos == 0) {
|
||||||
buildcommon();
|
buildcommon();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
61
rebuild.sh
@@ -1,61 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -eu
|
|
||||||
PHP=/cygdrive/c/bin/php/php.exe
|
|
||||||
THREADS=4
|
|
||||||
|
|
||||||
buildsite() {
|
|
||||||
|
|
||||||
local basedir="$(realpath .)"
|
|
||||||
local rebuild="${basedir}/rebuild.php"
|
|
||||||
|
|
||||||
if [[ "$(uname -o)" == "Cygwin" ]] ; then
|
|
||||||
rebuild="$(cygpath -w "$rebuild")"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Site: ${1}"
|
|
||||||
|
|
||||||
pushd "$1" >/dev/null
|
|
||||||
|
|
||||||
echo "Cleaning target directory..."
|
|
||||||
|
|
||||||
if [[ -d wwwroot ]] ; then
|
|
||||||
rm -r wwwroot
|
|
||||||
fi
|
|
||||||
|
|
||||||
mkdir -p wwwroot/srv
|
|
||||||
|
|
||||||
if [[ ! -d static ]] ; then
|
|
||||||
mkdir static
|
|
||||||
fi
|
|
||||||
cp "${basedir}/static_global/"* wwwroot || true
|
|
||||||
cp static/* wwwroot || true
|
|
||||||
|
|
||||||
for htm in footer header homepage_blurb ; do
|
|
||||||
if [[ ! -f "${htm}.htm" ]] ; then
|
|
||||||
touch "${htm}.htm"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "Building pages..."
|
|
||||||
|
|
||||||
for i in $(seq 0 "$THREADS") ; do
|
|
||||||
$PHP "$rebuild" "$THREADS" "$i" &
|
|
||||||
done
|
|
||||||
wait
|
|
||||||
|
|
||||||
echo "Site: ${1} finished."
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
popd >/dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
main() {
|
|
||||||
for site in sites/* ; do
|
|
||||||
buildsite "$site"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
main "$@"
|
|
||||||
|
|
||||||
read -p "Press any key to continue..."
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
[codesite]
|
|
||||||
title=code.ivysaur.me
|
|
||||||
page_thumb_w=60
|
|
||||||
page_thumb_h=60
|
|
||||||
index_thumb_w=90
|
|
||||||
index_thumb_h=32
|
|
||||||
|
|
||||||
; n.b. Recommend a multiple of the JPEG iDCT block size for index_thumb_h
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<p>
|
|
||||||
<strong>CONTACT</strong>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
For bug reports, feature requests, or if you need any help, please
|
|
||||||
<a
|
|
||||||
href="http://www.google.com/recaptcha/mailhide/d?k=01GuAWzMc9JjSdooo-2KCMQA==&c=kgR3dBrP39yhPIy8FvLFbuBLmWqorQBDc_Zjbw6NAmU="
|
|
||||||
onclick="window.open('http://www.google.com/recaptcha/mailhide/d?k\07501GuAWzMc9JjSdooo-2KCMQA\75\75\46c\75kgR3dBrP39yhPIy8FvLFbuBLmWqorQBDc_Zjbw6NAmU\075', '', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=500,height=300'); return false;"
|
|
||||||
title="Reveal this e-mail address"
|
|
||||||
>click here</a> to email me.
|
|
||||||
</p>
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
<h1><a href="index.html"><div id="ivylogo"></div>code.ivysaur.me</a></h1>
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
|
|
||||||
<p>
|
|
||||||
It's said that if you're not disgusted by code you wrote six months ago, you've stopped learning.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<strong>OVERVIEW</strong>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
This page contains several assorted spare-time projects, which no longer have any relation. They are listed in roughly chronological order (newest first). <strong>Unless specified otherwise</strong>, you may feel free to use and modify both the binaries and any source code, for any purpose, on the general condition you do not misrepresent who the author is (BSD license).
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Some of these projects formerly appeared on Google Code <a href="https://code.google.com/p/mappy/">here</a>, but were moved following the discontinuation of the Google Code binary download system.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<select id="sortorder" style="float:right;">
|
|
||||||
<option value="a">Youngest project first</option>
|
|
||||||
<option value="b">Recent updates first</option>
|
|
||||||
<option value="c">Alphabetical</option>
|
|
||||||
</select>
|
|
||||||
|
|
||||||
<strong>PROJECTS</strong>
|
|
||||||
</p>
|
|
||||||
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
@@ -1,173 +0,0 @@
|
|||||||
/* style.css */
|
|
||||||
|
|
||||||
html {
|
|
||||||
overflow-y:scroll; /* always display scrollbar to prevent horizontal lurch */
|
|
||||||
}
|
|
||||||
img {
|
|
||||||
border:0;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color:black;
|
|
||||||
text-decoration:underline;
|
|
||||||
}
|
|
||||||
a:hover {
|
|
||||||
color:blue;
|
|
||||||
cursor:pointer;
|
|
||||||
}
|
|
||||||
h1 a {
|
|
||||||
text-decoration:none;
|
|
||||||
}
|
|
||||||
h1 a:hover {
|
|
||||||
color:black;
|
|
||||||
}
|
|
||||||
h1,h2,h3 {
|
|
||||||
margin-top:0;
|
|
||||||
}
|
|
||||||
.code {
|
|
||||||
background: #F8F8F8;
|
|
||||||
font-family:Consolas,monospace;
|
|
||||||
white-space:pre;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* */
|
|
||||||
|
|
||||||
html, body {
|
|
||||||
/* structural */
|
|
||||||
height:100%;
|
|
||||||
min-height:100%;
|
|
||||||
margin:0;
|
|
||||||
border:0;
|
|
||||||
padding:0;
|
|
||||||
|
|
||||||
/* cosmetic */
|
|
||||||
font-family:"Helvetica Neue","Segoe UI",Arial,sans-serif;
|
|
||||||
font-size:12px;
|
|
||||||
background:#DDD url('pixel_weave.png'); /* thanks subtlepatterns.com ! */
|
|
||||||
color:#333;
|
|
||||||
}
|
|
||||||
|
|
||||||
#container {
|
|
||||||
margin:0 auto;
|
|
||||||
width:768px;
|
|
||||||
position:relative;
|
|
||||||
|
|
||||||
height:auto !important;
|
|
||||||
height:100%; /* oldIE */
|
|
||||||
min-height:100%;
|
|
||||||
|
|
||||||
/* cosmetic */
|
|
||||||
background:white;
|
|
||||||
}
|
|
||||||
|
|
||||||
#content {
|
|
||||||
padding:14px;
|
|
||||||
background:white;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* */
|
|
||||||
|
|
||||||
.tag::before {
|
|
||||||
content:"";
|
|
||||||
|
|
||||||
display:inline-block;
|
|
||||||
width:7px;
|
|
||||||
height:7px;
|
|
||||||
|
|
||||||
margin-right:2px;
|
|
||||||
|
|
||||||
background:transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAZUlEQVQI12P4//8/Awyrqqp6KSkp/QdhFRWV7cgS+kDBN0B8RVlZuRikACahB+T8ger6BMTXwJJAiTwg4xvMOCj+ART3ZwCa3YYm8QcopgsyEWasDVT3W5AVMHcgO6gViNORXQ8A84NToxbSsJcAAAAASUVORK5CYII=') no-repeat 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag-filter-warn {
|
|
||||||
position:fixed;
|
|
||||||
top:0;
|
|
||||||
right:0;
|
|
||||||
|
|
||||||
padding:4px;
|
|
||||||
|
|
||||||
background:lightyellow;
|
|
||||||
border-bottom: 1px solid #888;
|
|
||||||
border-left:1px solid #888;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* */
|
|
||||||
|
|
||||||
.projtable {
|
|
||||||
border-collapse: collapse;
|
|
||||||
width:100%;
|
|
||||||
}
|
|
||||||
.projtable tr {
|
|
||||||
transition:0.2s linear;
|
|
||||||
}
|
|
||||||
.projtable tr:hover {
|
|
||||||
background:#F8F8F8;
|
|
||||||
}
|
|
||||||
.projtable td {
|
|
||||||
padding: 2px 4px;
|
|
||||||
}
|
|
||||||
.projtable small {
|
|
||||||
color:grey;
|
|
||||||
font-style:italic;
|
|
||||||
}
|
|
||||||
.projtable tr td:first-child {
|
|
||||||
width:95px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.projinfo {
|
|
||||||
}
|
|
||||||
.projbody {
|
|
||||||
}
|
|
||||||
.projbody_halfw {
|
|
||||||
float:left;
|
|
||||||
width: 678px; /* 740px full - 60px rhs column - 2px border */
|
|
||||||
}
|
|
||||||
.projbody_fullw {
|
|
||||||
|
|
||||||
}
|
|
||||||
.projimg {
|
|
||||||
float:right;
|
|
||||||
width:62px; /* 60px + 2px border */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* */
|
|
||||||
|
|
||||||
#ivylogo {
|
|
||||||
background:transparent url('ivysaur24.png') no-repeat 0 0;
|
|
||||||
width:24px;
|
|
||||||
height:24px;
|
|
||||||
display:inline-block;
|
|
||||||
*display:block;
|
|
||||||
*zoom:1;
|
|
||||||
margin-right:4px;
|
|
||||||
position:relative;
|
|
||||||
top:4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* */
|
|
||||||
|
|
||||||
.homeimage {
|
|
||||||
width:90px;
|
|
||||||
height:32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.homeimage-sprite {
|
|
||||||
background: white url('logos.jpg') no-repeat 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.thumbimage {
|
|
||||||
width:60px;
|
|
||||||
height:60px;
|
|
||||||
opacity: 0.8;
|
|
||||||
transition:0.2s opacity;
|
|
||||||
border:1px solid lightgrey;
|
|
||||||
}
|
|
||||||
.thumbimage:hover {
|
|
||||||
opacity:1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.no-image {
|
|
||||||
width:90px;
|
|
||||||
height:32px;
|
|
||||||
display:block;
|
|
||||||
background: white url('no_image.png') no-repeat 0 0;
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
[codesite]
|
|
||||||
title=codesite.example.com
|
|
||||||
page_thumb_w=60
|
|
||||||
page_thumb_h=60
|
|
||||||
index_thumb_w=90
|
|
||||||
index_thumb_h=32
|
|
||||||
|
|
||||||
; n.b. Recommend a multiple of the JPEG iDCT block size for index_thumb_h
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
|
|
||||||
<p>
|
|
||||||
Homepage blurb goes here.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<select id="sortorder" style="float:right;">
|
|
||||||
<option value="a">Youngest project first</option>
|
|
||||||
<option value="b">Recent updates first</option>
|
|
||||||
<option value="c">Alphabetical</option>
|
|
||||||
</select>
|
|
||||||
|
|
||||||
<strong>PROJECTS</strong>
|
|
||||||
</p>
|
|
||||||
|
Before Width: | Height: | Size: 233 B |
|
Before Width: | Height: | Size: 264 B |
BIN
static/header.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 436 B After Width: | Height: | Size: 436 B |
|
Before Width: | Height: | Size: 233 B After Width: | Height: | Size: 233 B |
|
Before Width: | Height: | Size: 264 B After Width: | Height: | Size: 264 B |
@@ -33,52 +33,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
var get_show_tag = function(tag) {
|
var get_show_tag = function(tag) {
|
||||||
return function() {
|
return function() { show_tag(tag); return false; };
|
||||||
show_tag(tag);
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
var sort_rows = function(cb) {
|
|
||||||
var tr = document.querySelectorAll(".projtable tr");
|
|
||||||
var items = [];
|
|
||||||
for (var i = 0, e = tr.length; i !== e; ++i) {
|
|
||||||
items.push([i, cb(tr[i])]);
|
|
||||||
}
|
|
||||||
items.sort(function(a, b) {
|
|
||||||
return (a[1] - b[1]);
|
|
||||||
});
|
|
||||||
for (var i = 0, e = items.length; i !== e; ++i) {
|
|
||||||
var el = tr[items[i][0]];
|
|
||||||
var parent = el.parentElement;
|
|
||||||
parent.removeChild(el);
|
|
||||||
parent.appendChild(el);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var sort_update = function() {
|
|
||||||
var cb;
|
|
||||||
switch(document.getElementById('sortorder').value) {
|
|
||||||
case 'a':
|
|
||||||
default: {
|
|
||||||
cb = function(el) {
|
|
||||||
return el.getAttribute('data-sort-ct');
|
|
||||||
};
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case 'b': {
|
|
||||||
cb = function(el) {
|
|
||||||
return el.getAttribute('data-sort-mt');
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case 'c': {
|
|
||||||
cb = function(el) {
|
|
||||||
return el.getAttribute('data-sort-al');
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
};
|
|
||||||
sort_rows(cb);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener('load', function() {
|
window.addEventListener('load', function() {
|
||||||
@@ -87,11 +42,5 @@
|
|||||||
var tag = taglinks[i].getAttribute("data-tag");
|
var tag = taglinks[i].getAttribute("data-tag");
|
||||||
taglinks[i].addEventListener('click', get_show_tag(tag));
|
taglinks[i].addEventListener('click', get_show_tag(tag));
|
||||||
}
|
}
|
||||||
|
|
||||||
var so = document.getElementById('sortorder');
|
|
||||||
if (so) {
|
|
||||||
so.addEventListener('change', sort_update);
|
|
||||||
sort_update();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||