Several improvements

exif: cleanup metadata, rotate and add comment on all jpegs
social networks: opengraph and new image tag for SEO (A grades everywhere!)
preview: fixes, also cycling of themes
backend: now using zuper extended library of zfunctions
This commit is contained in:
Jaromil 2015-10-12 18:37:18 +02:00
parent ccb3e64036
commit aec4db9146
9 changed files with 224 additions and 172 deletions

View File

@ -3,7 +3,7 @@
.--.--.--.-----| |--.-----.-----.--------.---.-.--| | .--.--.--.-----| |--.-----.-----.--------.---.-.--| |
| | | | -__| _ | | _ | | _ | _ | | | | | -__| _ | | _ | | _ | _ |
|________|_____|_____|__|__|_____|__|__|__|___._|_____| |________|_____|_____|__|__|_____|__|__|__|___._|_____|
A slick and static website publisher v 0.4 A slick and static website publisher
http://www.dyne.org/software/webnomad http://www.dyne.org/software/webnomad

View File

@ -26,7 +26,8 @@ CMD=`basename $0`
return 1 return 1
} }
source ${DIR}/utils source ${DIR}/zuper
source ${DIR}/zuper.init
DEBUG=1 DEBUG=1

36
init
View File

@ -22,7 +22,9 @@ QUIET=0
DEBUG=0 DEBUG=0
SYS=`dirname $0` SYS=`dirname $0`
source $SYS/utils source $SYS/zuper
source $SYS/zuper.init
act "Initializing Webnomad" act "Initializing Webnomad"
@ -67,20 +69,36 @@ mkdir -p tmpl
{ test -r config.zsh } || { { test -r config.zsh } || {
cat <<EOF > config.zsh cat <<EOF > config.zsh
TITLE="A new website made with WebNomad." TITLE="A new website made with WebNomad."
DESCRIPTION="WebNomad, your slick and static website publisher, powered by HTML5, Zsh and Bootstrap" DESCRIPTION="WebNomad, your slick and static website publisher, powered by HTML5, Zsh and Bootstrap"
KEYWORDS="web, design, html" KEYWORDS="web, design, html"
# representative image, 1200 pixel width is full column banner, 400 is half
IMAGE="https://www.dyne.org/wp-content/uploads/2013/09/carciofo-webnomad.jpg"
# list of types: http://ogp.me/#types
TYPE="website"
# What is the root of this website url, after the domain
# full url includes http and no trailing slash i.e. http://www.dyne.org
# leave blank if relative, or just subdir i.e /blog
WEB_ROOT=""
# A twitter handler is necessary to activate open-graph compatible
# information that works also with twitter.
TWITTER="@DyneOrg"
# #
# Anything below is safe to leave untouched # Anything below is safe to leave untouched
# #
# Comment to disable Bootstrap
BOOTSTRAP=1
# What file extension to use for html files # What file extension to use for html files
EXTENSION=".html" EXTENSION=".html"
# What is the root of this website url, after the domain
# leave blank if relative, or for instance /blog/
WEB_ROOT=""
# What is the url for files in case indexing is used # What is the url for files in case indexing is used
# this can be different from WEB_ROOT in order to serve # this can be different from WEB_ROOT in order to serve
# files from a position different from the web pages # files from a position different from the web pages
@ -93,7 +111,13 @@ WEB_ROOT=""
# text size in an absolute way (we use Flowtype) # text size in an absolute way (we use Flowtype)
# FONT_RATIO=30 # FONT_RATIO=30
# Cleanup EXIF information from jpeg images (requires jhead)
# i.e: location, camera type, time of shot, editors used
EXIF_CLEAN=1
# Add a comment to EXIF in jpeg images (requires jhead)
# EXIF_COMMENT=""
# Automatically rotate the image according to EXIF information
# EXIF_ROTATE=1
EOF EOF
} }

View File

@ -21,7 +21,12 @@
# full path to webnomad's system # full path to webnomad's system
R="`pwd`" R="`pwd`"
SYS="$R/webnomad" SYS="$R/webnomad"
source $SYS/utils source $SYS/zuper
vars=(BROWSER TIME_FORMAT OUTPUT_FORMAT SYS)
vars=(views BROWSER_WINDOW_ID)
source $SYS/zuper.init
source $R/config.zsh
BROWSER=${1:-firefox} BROWSER=${1:-firefox}
TIME_FORMAT='%F %H:%M' TIME_FORMAT='%F %H:%M'
@ -31,6 +36,7 @@ $SYS/render test
$BROWSER $R/test/index.html & $BROWSER $R/test/index.html &
views=" views="
$R/test
$R/views $R/views
$R/tmpl $R/tmpl
$R/config.zsh $R/config.zsh

258
render
View File

@ -18,50 +18,45 @@
# this source code; if not, write to: # this source code; if not, write to:
# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
VERSION=0.3
QUIET=0
# full path to webnomad's system # full path to webnomad's system
SYS="`pwd`/webnomad" SYS="`pwd`/webnomad"
source $SYS/utils
source $SYS/zuper
vars+=(SYS DIR CMD dst)
vars+=(TITLE DESCRIPTION KEYWORDS TYPE IMAGE EXTENSION)
vars+=(WEB_ROOT FILES_ROOT THUMB_SIZE BOOTSTRAP destination)
vars+=(FLOWTYPE FONT_RATIO EXIF_CLEAN EXIF_COMMENT EXIF_ROTATE)
vars+=(total_fonts cssfound)
arrs+=(includecss includejs fonts)
arrs+=(custom_fonts)
source $SYS/zuper.init
VERSION=0.5
# fill path to the source website root # fill path to the source website root
DIR="`pwd`" DIR="`pwd`"
CMD="$1" CMD="$1"
{ test -r config.zsh } || { [[ -r config.zsh ]] || {
error "Directory not configured for WebNomad. First use /webnomad/init" error "Directory not configured for WebNomad. First use /webnomad/init"
exit 1 } return 1 }
####################################
# Base configuration
# web root for all urls
WEB_ROOT=""
# prefix to all indexed files
# this can be a full path on the filesystem
FILES_ROOT=""
# thumbnail size
THUMB_SIZE=256
# font ratio
FONT_RATIO=30
source config.zsh source config.zsh
# thumbnail size
THUMB_SIZE=${THUMB_SIZE:-256}
#################################### ####################################
typeset -h dst
typeset -alU includecss # array of css files to include
typeset -alU includejs # array of js files to include
typeset -alU fonts # array of available fonts
# string match case insensitive # string match case insensitive
unsetopt CASE_GLOB unsetopt CASE_GLOB
@ -88,6 +83,11 @@ act "WEB_ROOT = $WEB_ROOT"
render_file() { sed -e "s@\${baseurl}@${baseurl}@g" $@ } render_file() { sed -e "s@\${baseurl}@${baseurl}@g" $@ }
render_header() { render_header() {
if [[ "$IMAGE" =~ "http://" ]] ; then
_image=$IMAGE
else
_image=$WEB_ROOT/$IMAGE
fi
cat <<EOF cat <<EOF
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
@ -99,7 +99,10 @@ render_header() {
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="Generator" content="WebNomad $VERSION - http://dyne.org/software/webnomad" /> <meta name="Generator" content="WebNomad $VERSION - http://dyne.org/software/webnomad" />
<meta name="MSSmartTagsPreventParsing" content="True" /> <meta name="MSSmartTagsPreventParsing" content="True" />
EOF
[[ $BOOTSTRAP = 1 ]] && {
cat <<EOF
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements
http://html5shim.googlecode.com/svn/trunk/html5.js --> http://html5shim.googlecode.com/svn/trunk/html5.js -->
<!--[if lt IE 9]> <!--[if lt IE 9]>
@ -110,11 +113,39 @@ render_header() {
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="${baseurl}/css/bootstrap.min.css" rel="stylesheet" /> <link href="${baseurl}/css/bootstrap.min.css" rel="stylesheet" />
<link href="${baseurl}/css/bootstrap-responsive.css" rel="stylesheet" /> <link href="${baseurl}/css/bootstrap-responsive.css" rel="stylesheet" />
EOF
}
cat <<EOF
<!-- Open Graph for social networks -->
<meta property="og:title" content="$TITLE" />
<meta property="og:description" content="$DESCRIPTION" />
<meta property="og:type" content="$TYPE" />
EOF
[[ "$WEB_ROOT" = "" ]] || {
cat <<EOF
<meta property="og:url" content="$WEB_ROOT" />
EOF
}
cat <<EOF
<meta property="og:image" content="$_image" />
EOF EOF
[[ "$TWITTER" = "" ]] || {
cat <<EOF
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="$TWITTER">
<meta name="twitter:title" content="$TITLE">
<meta name="twitter:description" content="$DESCRIPTION">
<meta name="twitter:image" content="$_image">
EOF
}
# include all css files found in views/css # include all css files found in views/css
cssfound=`find $DIR/views/css -name '*.css'` cssfound=`find $DIR/views/css -iname '*.css'`
for c in ${(f)cssfound}; do for c in ${(f)cssfound}; do
includecss+=(${c##*/}) includecss+=(${c##*/})
done done
@ -129,10 +160,11 @@ EOF
act "+ css: $c" act "+ css: $c"
func "<link href=\"${baseurl}/css/${c}\" rel=\"stylesheet\" />" func "<link href=\"${baseurl}/css/${c}\" rel=\"stylesheet\" />"
cat <<EOF cat <<EOF
<link href="${baseurl}/css/${c}" rel="stylesheet" /> <link href="${baseurl}/css/${c}" rel="stylesheet" />
EOF EOF
if [[ -r "$DIR"/views/css/$c ]]; then if [[ -r "$DIR"/views/css/$c ]]; then
cp -a $DIR/views/css/$c "${destination}"/css/ cp -a $DIR/views/css/$c "${destination}"/css/
elif [[ -r "$SYS"/css/${c} ]]; then elif [[ -r "$SYS"/css/${c} ]]; then
cp -a "$SYS"/css/${c} "${destination}"/css/ cp -a "$SYS"/css/${c} "${destination}"/css/
@ -140,12 +172,10 @@ EOF
done done
# add any argument string to header
[[ "$1" = "" ]] || { print "${@}"; print }
# add the user configured header # add the user configured header
render_file "$DIR"/tmpl/header.html render_file "$DIR"/tmpl/header.html
} }
render_footer() { render_footer() {
@ -167,13 +197,13 @@ EOF
# insert and copy all js files # insert and copy all js files
for j in $includejs; do for j in $includejs; do
act "+ js: $j" act "+ js: $j"
cat <<EOF cat <<EOF
<script type="text/javascript" src="${baseurl}/js/$j"></script> <script type="text/javascript" src="${baseurl}/js/$j"></script>
EOF EOF
if [[ -r "$DIR"/views/js/$j ]]; then if [[ -r "$DIR"/views/js/$j ]]; then
cp -a "$DIR"/views/js/$j "$destination"/js cp -a "$DIR"/views/js/$j "$destination"/js
elif [[ -r "$SYS"/js/$i ]]; then elif [[ -r "$SYS"/js/$i ]]; then
cp -a "$SYS"/js/$i "$destination"/js cp -a "$SYS"/js/$i "$destination"/js
fi fi
done done
@ -238,7 +268,7 @@ EOF
EOF EOF
} }
cat <<EOF cat <<EOF
</body> </body>
</html> </html>
EOF EOF
@ -262,43 +292,43 @@ render_html() {
# first pass marks the markdown parts and saves them separate # first pass marks the markdown parts and saves them separate
mds=(`find . -name 'tmp.md*'`) mds=(`find . -name 'tmp.md*'`)
{ test "${#mds}" = "0" } || { { test "${#mds}" = "0" } || {
# second pass substituted saved parts with rendered markdown # second pass substituted saved parts with rendered markdown
act -n "${#mds} markdown fields " act -n "${#mds} markdown fields "
# check which markdown parser is available in PATH # check which markdown parser is available in PATH
command -v pandoc > /dev/null command -v pandoc > /dev/null
if [ "$?" = "0" ]; then parser="pandoc -f markdown_github -t html5" if [ "$?" = "0" ]; then parser="pandoc -f markdown_github -t html5"
else command -v maruku > /dev/null else command -v maruku > /dev/null
if [ "$?" = "0" ]; then parser="maruku --html-frag" if [ "$?" = "0" ]; then parser="maruku --html-frag"
else command -v markdown > /dev/null; else command -v markdown > /dev/null;
if [ "$?" = "0" ]; then parser=markdown if [ "$?" = "0" ]; then parser=markdown
else command -v multimarkdown > /dev/null else command -v multimarkdown > /dev/null
if [ "$?" = "0"]; then parser=multimarkdown if [ "$?" = "0"]; then parser=multimarkdown
fi fi
fi fi
fi fi
fi fi
# parses all html and renders each markdown in the html # parses all html and renders each markdown in the html
for i in $mds; do for i in $mds; do
md=`basename $i` md=`basename $i`
newtemp="tmp.$RANDOM" newtemp="tmp.$RANDOM"
cat $tmp | awk ' cat $tmp | awk '
/^'"$md"'/ { system("cat '"$md"' | '"$parser"'"); next } /^'"$md"'/ { system("cat '"$md"' | '"$parser"'"); next }
{ print $0; }' > $newtemp { print $0; }' > $newtemp
rm $tmp; tmp=$newtemp rm $tmp; tmp=$newtemp
done done
} }
cat $tmp cat $tmp
# extra js for html pages # extra js for html pages
[[ "$FLOWTYPE" = "" ]] || { [[ "$FLOWTYPE" = "" ]] || {
includejs+=(jquery.min.js) includejs+=(jquery.min.js)
includejs+=(flowtype.js) includejs+=(flowtype.js)
} }
# clean up from temporary files # clean up from temporary files
rm -f tmp.* rm -f tmp.*
@ -317,8 +347,8 @@ read_meta() {
# calculate the destination path for a file or folder to render from views # calculate the destination path for a file or folder to render from views
calc_dest() { calc_dest() {
{ test -r "$1" } || { { test -r "$1" } || {
error "error calculating destination: cannot read $1" error "error calculating destination: cannot read $1"
return 0 } return 0 }
# optional 2nd arg: extension # optional 2nd arg: extension
ext="$2" ext="$2"
{ test "$ext" = "" } && { ext="$EXTENSION" } { test "$ext" = "" } && { ext="$EXTENSION" }
@ -334,11 +364,11 @@ calc_dest() {
# compute destination file # compute destination file
if [ "${dstfile%.*}" = "${dstdir%.*}" ]; then if [ "${dstfile%.*}" = "${dstdir%.*}" ]; then
# no subdirs, root level # no subdirs, root level
dst="${destination}/${dstfile}" dst="${destination}/${dstfile}"
else else
dst="${destination}/${dstdir}/${dstfile}" dst="${destination}/${dstdir}/${dstfile}"
mkdir -p ${destination}/${dstdir} mkdir -p ${destination}/${dstdir}
fi fi
func "calculated destination: $dst" func "calculated destination: $dst"
print $dst print $dst
@ -346,25 +376,32 @@ calc_dest() {
######### #########
# MAIN # MAIN
func MAIN
{ test "$1" = "source" } && { return 0 } { test "$1" = "source" } && { return 0 }
{ test "$1" = "test" } && { { test "$1" = "test" } && {
act "Local test rendering inside test/" act "Local test rendering inside test/"
source $SYS/test } source $SYS/test }
# copy core bootstrap files in place # render the base skeleton dir tree
mkdir -p "$destination/css" mkdir -p "$destination/css"
mkdir -p "$destination/js" mkdir -p "$destination/js"
mkdir -p "$destination/img" mkdir -p "$destination/img"
#{ test -r "$destination"/css/bootstrap.css } || { [[ $BOOTSTRAP = 1 ]] && {
#{ test -r "$destination"/css/bootstrap.css } || {
cp "$SYS"/css/bootstrap.css "$destination"/css/ cp "$SYS"/css/bootstrap.css "$destination"/css/
cp "$SYS"/img/* "$destination"/img/ cp "$SYS"/img/* "$destination"/img/
cp "$SYS"/css/bootstrap.min.css "$destination"/css/ cp "$SYS"/css/bootstrap.min.css "$destination"/css/
cp "$SYS"/css/bootstrap-responsive.css "$destination"/css/ cp "$SYS"/css/bootstrap-responsive.css "$destination"/css/
#} #}
cp "$SYS"/js/bootstrap.min.js "$destination"/js/ cp "$SYS"/js/bootstrap.min.js "$destination"/js/
cp "$SYS"/js/html5.js "$destination"/js/ cp "$SYS"/js/html5.js "$destination"/js/
}
@ -414,22 +451,25 @@ EOF
# don't forget the navbar # don't forget the navbar
render_file "$DIR"/tmpl/navbar.html >> $dst render_file "$DIR"/tmpl/navbar.html >> $dst
cat <<EOF >> $dst [[ $BOOTSTRAP = 1 ]] && {
cat <<EOF >> $dst
<p>&nbsp;</p> <p>&nbsp;</p>
<div class="container-fluid"> <div class="container-fluid">
<article> <article>
EOF EOF
}
cat $src | render_html >> $dst cat $src | render_html >> $dst
cat <<EOF >> $dst [[ $BOOTSTRAP = 1 ]] && {
cat <<EOF >> $dst
</article> </article>
<p>&nbsp;</p> <p>&nbsp;</p>
<p>&nbsp;</p> <p>&nbsp;</p>
EOF EOF
}
# includejs=(js/bootstrap.min.js)
render_footer >> $dst render_footer >> $dst
act "done" act "done"
@ -448,11 +488,11 @@ if [[ "${#gals}" > 0 ]]; then
cp "$SYS"/js/jquery.min.js "$destination"/js/ cp "$SYS"/js/jquery.min.js "$destination"/js/
for src in $gals; do for src in $gals; do
cat ${src} | read_meta cat ${src} | read_meta
dst=`calc_dest "$src"` dst=`calc_dest "$src"`
act -n "Gallery rendering: $B $dst $r ... " act -n "Gallery rendering: $B $dst $r ... "
cat $src | render_gallery > $dst cat $src | render_gallery > $dst
[[ $QUIET = 1 ]] || print "done" [[ $QUIET = 1 ]] || print "done"
done done
fi fi
@ -465,32 +505,59 @@ idxs+=(`find views -type f -name '*.index'`)
# loop through all .idx files # loop through all .idx files
for idx in $idxs; do for idx in $idxs; do
# destination dir is named after the .idx file # destination dir is named after the .idx file
dst=`calc_dest "$idx"` dst=`calc_dest "$idx"`
# strip extension: an index builds a dir structure # strip extension: an index builds a dir structure
dst="${dst%.*}" dst="${dst%.*}"
notice "Directory index rendering to: $dst" notice "Directory index rendering to: $dst"
# loop through all contents of the idx: # loop through all contents of the idx:
# one directory to index recursively on each line # one directory to index recursively on each line
dirs=`cat ${idx}` dirs=`cat ${idx}`
for d in ${(f)dirs}; do for d in ${(f)dirs}; do
mkdir -p "${dst}" mkdir -p "${dst}"
pushd "${dst}" pushd "${dst}"
# recursion wrap: $1=archive $2=diralias $3=indextype # recursion wrap: $1=archive $2=diralias $3=indextype
recursive_index "${d[(ws: :)1]}" "${d[(ws: :)2]}" "${d[(ws: :)3]}" recursive_index "${d[(ws: :)1]}" "${d[(ws: :)2]}" "${d[(ws: :)3]}"
# archive: full path where the files to be indexed are found # archive: full path where the files to be indexed are found
# diralias: index directory appended to url # diralias: index directory appended to url
# indextype: type of index (short | long) # indextype: type of index (short | long)
popd popd
done done
done done
} }
# copy to destination all subdirs in views/ # copy to destination all subdirs in views/
act -n "publishing all $B views $r ... " act -n "publishing all $B views $r ... "
rsync -a -W --ignore-existing "$DIR/views/" "${destination}/" rsync -a -W --ignore-existing "$DIR/views/" "${destination}/"
# make sure that new css styles are updates # make sure that new css styles are updated
{ test -r "$DIR/views/css/custom.css" } && { [[ -r "$DIR/views/css/custom.css" ]] && {
cp -f "$DIR/views/css/custom.css" "${destination}/css/" } cp -f "$DIR/views/css/custom.css" "${destination}/css/" }
# Here all files are copied inside the destination
# we can run special operations on file-types and overwrite them now
# for instance edit EXIF information on images etc.
# clean up jpegs if jhead is installed
command -v jhead && {
jpegs=`find "$destination" -iname "*.jpg"`
[[ $EXIF_CLEAN = 1 ]] && {
for j in ${(f)jpegs}; do
jhead -purejpg $j
done
}
[[ "$EXIF_COMMENT" != "" ]] && {
for j in ${(f)jpegs}; do
jhead -cl "$EXIF_COMMENT" $j
done
}
[[ $EXIF_ROTATE = 1 ]] && {
for j in ${(f)jpegs}; do
jhead -autorot $j
done
}
}
[[ $QUIET = 1 ]] || print "done" [[ $QUIET = 1 ]] || print "done"
# if the whole website is a "slideshow" (set in config.zsh) then we start with # if the whole website is a "slideshow" (set in config.zsh) then we start with
@ -501,9 +568,8 @@ rsync -a -W --ignore-existing "$DIR/views/" "${destination}/"
# generate a list of all images (removing duplicates) # generate a list of all images (removing duplicates)
act "Indexing all images ... " act "Indexing all images ... "
find pub -iname '*.jpg' | sed -e 's/^pub\///g' -e 's/^.\/pub\///g' -e "s@'@@g" | sort | uniq \ find pub -iname '*.jpg' | sed -e 's/^pub\///g' -e 's/^.\/pub\///g' -e "s@'@@g" | sort | uniq \
| render_gallery views/index.html > ${destination}/index | render_gallery views/index.html > ${destination}/index
} }
notice "Website refreshed." notice "Website refreshed."

11
theme
View File

@ -31,12 +31,19 @@ CMD="`basename $0`"
QUIET=0 QUIET=0
DEBUG=0 DEBUG=0
source ${DIR}/utils source ${DIR}/zuper
{ test -r config.zsh } || { { test -r config.zsh } || {
error "Directory not configured for WebNomad. First use ./webnomad/init" error "Directory not configured for WebNomad. First use ./webnomad/init"
exit 1 } return 1 }
source ${DIR}/zuper.init
source config.zsh
[[ $BOOTSTRAP = 1 ]] || {
error "Bootstrap deactivated in config.zsh, no themes available"
return 1 }
#################################### ####################################

54
update
View File

@ -1,54 +0,0 @@
#!/usr/bin/env zsh
#
# WebNomad, your slick and static website publisher
#
# Copyright (C) 2012-2013 Denis Roio <jaromil@dyne.org>
#
# This source code is free software; you can redistribute it and/or
# modify it under the terms of the GNU Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This source code is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# Please refer to the GNU Public License for more details.
#
# You should have received a copy of the GNU Public License along with
# this source code; if not, write to:
# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
{ test -r init } || {
echo "Error: update must be run from inside the webnomad directory"
return 1 }
source utils
# eventually these will need an update
bootstrap2="http://getbootstrap.com/2.3.2/assets/bootstrap.zip"
blueimp_gallery="https://github.com/blueimp/Gallery.git"
{ test "$1" = "" } || { test "$1" = "bootstrap" } && {
notice "Downloading and installing the latest Bootstrap2"
act "url: $bootstrap2"
curl "$bootstrap2" -o bootstrap.zip
unzip -q bootstrap.zip
rsync -r bootstrap/css .
rsync -r bootstrap/js .
rsync -r bootstrap/img .
rm -rf bootstrap bootstrap.zip
act "Bootstrap2 installed"
}
{ test "$1" = "" } || { test "$1" = "blueimp" } && {
notice "Downloading and installing BlueImp gallery"
git clone ${blueimp_gallery} blueimp
rsync -r blueimp/css .
rsync -r blueimp/js .
rsync -r blueimp/img .
rm -rf blueimp
act "BlueImp installed"
}

1
zuper Symbolic link
View File

@ -0,0 +1 @@
/home/jrml/devel/zuper/zuper

1
zuper.init Symbolic link
View File

@ -0,0 +1 @@
/home/jrml/devel/zuper/zuper.init