diff options
-rw-r--r-- | README.md | 9 | ||||
-rwxr-xr-x | bb.sh | 103 |
2 files changed, 90 insertions, 22 deletions
@@ -42,6 +42,12 @@ When you're done, access the public URL for that folder (e.g. `http://server.co and you should see the index file and a new page for that post! +How to... +--------- + +Please [read the wiki](https://github.com/cfenollosa/bashblog/wiki) to learn how to use the advanced features of Bashblog, such as headers and footers, static pages, and more. + + Features -------- @@ -131,7 +137,8 @@ As a guideline, pull requests should: Changelog --------- - +- 2.10 Added `global_twitter_card_image` +- 2.9 Added `body_begin_file_index` - 2.8 Bugfixes<br/> Slavic language support thanks to Tomasz Jadowski<br/> Removed the now defunct Twitter JSON API share count<br/> @@ -17,7 +17,7 @@ global_config=".config" # by the 'global_config' file contents global_variables() { global_software_name="BashBlog" - global_software_version="2.8" + global_software_version="2.10" # Blog title global_title="My fancy blog" @@ -49,6 +49,8 @@ global_variables() { # Change this to your username if you want to use twitter for comments global_twitter_username="" + # Default image for the Twitter cards. Use an absolute URL + global_twitter_card_image="" # Set this to false for a Twitter button with share count. The cookieless version # is just a link. global_twitter_cookieless="true" @@ -71,6 +73,8 @@ global_variables() { # Add them as a bash array, e.g. non_blogpost_files=("news.html" "test.html") non_blogpost_files=() + # site map file + blog_sitemap="sitemap.xml" # feed file (rss in this case) blog_feed="feed.rss" number_of_feed_articles="10" @@ -95,9 +99,11 @@ global_variables() { # extra content to add just after we open the <body> tag # and before the actual blog content body_begin_file="" - # extra content to add just before we cloese <body tag (just before - # </body>) + # extra content to add just before we close </body> body_end_file="" + # extra content to ONLY on the index page AFTER `body_begin_file` contents + # and before the actual content + body_begin_file_index="" # CSS files to include on every page, f.ex. css_include=('main.css' 'blog.css') # leave empty to use generated css_include=() @@ -141,6 +147,8 @@ global_variables() { date_format_full="%a, %d %b %Y %H:%M:%S %z" date_format_timestamp="%Y%m%d%H%M.%S" date_allposts_header="%B %Y" + # Data format for sitemap + date_format_sitemap="%Y/%m/%d" # Perform the post title -> filename conversion # Experts only. You may need to tune the locales too @@ -338,15 +346,25 @@ edit() { twitter_card() { [[ -z $global_twitter_username ]] && return - echo "<meta name='twitter:card' content='summary' />" - echo "<meta name='twitter:site' content='@$global_twitter_username' />" - echo "<meta name='twitter:title' content='$2' />" # Twitter truncates at 70 char - description=$(grep -v "^<p>$template_tags_line_header" "$1" | sed -e 's/<[^>]*>//g' | head -c 250 | tr '\n' ' ' | sed "s/\"/'/g") - echo "<meta name='twitter:description' content=\"$description\" />" - image=$(sed -n 's/.*<img.*src="\([^"]*\)".*/\1/p' "$1" | head -n 1) # First image is fine + + echo "<meta name='twitter:card' content='summary'>" + echo "<meta name='twitter:site' content='@$global_twitter_username'>" + echo "<meta name='twitter:title' content='$2'>" # Twitter truncates at 70 char + description=$(grep -v "^<p>$template_tags_line_header" "$1" | sed -e 's/<[^>]*>//g' | tr '\n' ' ' | sed "s/\"/'/g" | head -c 250) + echo "<meta name='twitter:description' content=\"$description\">" + + # For the image we try to locate the first image in the article + image=$(sed -n '2,$ d; s/.*<img.*src="\([^"]*\)".*/\1/p' "$1") + + # If none, then we try a global setting image + [[ -z $image ]] && [[ -n $global_twitter_card_image ]] && image=$global_twitter_card_image + + # If none, return [[ -z $image ]] && return + + # Final housekeeping [[ $image =~ ^https?:// ]] || image=$global_url/$image # Check that URL is absolute - echo "<meta name='twitter:image' content='$image' />" + echo "<meta name='twitter:image' content='$image'>" } # Adds the code needed by the twitter button @@ -433,6 +451,7 @@ create_html_page() { echo "</head><body>" # stuff to add before the actual body content [[ -n $body_begin_file ]] && cat "$body_begin_file" + [[ $filename = $index_file* ]] && [[ -n $body_begin_file_index ]] && cat "$body_begin_file_index" # body divs echo '<div id="divbodyholder">' echo '<div class="headerholder"><div class="header">' @@ -664,6 +683,9 @@ all_posts() { while IFS='' read -r i; do is_boilerplate_file "$i" && continue echo -n "." 1>&3 + # Read timestamp from post, and sync file timestamp + timestamp=$(awk '/<!-- '$date_inpost': .+ -->/ { print }' "$i" | cut -d '#' -f 2) + [[ -n $timestamp ]] && touch -t "$timestamp" "$i" # Month headers month=$(LC_ALL=$date_locale date -r "$i" +"$date_allposts_header") if [[ $month != "$prev_month" ]]; then @@ -678,7 +700,7 @@ all_posts() { # Date date=$(LC_ALL=$date_locale date -r "$i" +"$date_format") echo " $date</li>" - done < <(ls -t ./*.html) + done < <(list_html_by_timestamp) echo "" 1>&3 echo "</ul>" echo "<div id=\"all_posts\"><a href=\"./$index_file\">$template_archive_index_page</a></div>" @@ -748,7 +770,7 @@ rebuild_index() { fi echo -n "." 1>&3 n=$(( n + 1 )) - done < <(ls -t ./*.html) # sort by date, newest first + done < <(list_html_by_timestamp) # sort by file timestamp, newest first feed=$blog_feed if [[ -n $global_feedburner ]]; then feed=$global_feedburner; fi @@ -866,7 +888,7 @@ list_tags() { [[ -f "$i" ]] || break nposts=$(grep -c "<\!-- text begin -->" "$i") tagname=${i#"$prefix_tags"} - tagname=${tagname#.html} + tagname=${tagname%.html} ((nposts > 1)) && word=$template_tags_posts || word=$template_tags_posts_singular line="$tagname # $nposts # $word" lines+=$line\\n @@ -896,6 +918,35 @@ list_posts() { echo -e "$lines" | column -t -s "#" } + +# generate sitemap +make_sitemap() { + echo -n "Building Sitemap " + rm "$blog_sitemap" + + sitemapfile=$blog_sitemap.$RANDOM + while [[ -f $blog_sitemap ]]; do sitemapfile=$blog_sitemap.$RANDOM; done + + { + echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + echo "<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">" + echo -n "." 1>&3 + while IFS='' read -r i; do + echo -n "." 1>&3 + echo "<url>" + echo "<loc>$global_url/${i#./}</loc>" + echo "<lastmod>$(LC_ALL=C date -r "$i" +"$date_format_sitemap")</lastmod>" + echo "</url>" + done < <(ls -t ./*.html) + + echo "</urlset>" + } 3>&1 >"$sitemapfile" + echo "" + + mv "$sitemapfile" "$blog_sitemap" + chmod 644 $blog_sitemap +} + # Generate the feed file make_rss() { echo -n "Making RSS " @@ -947,15 +998,15 @@ create_includes() { if [[ -f $header_file ]]; then cp "$header_file" .header.html else { - echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">' - echo '<html xmlns="http://www.w3.org/1999/xhtml"><head>' - echo '<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />' - echo '<meta name="viewport" content="width=device-width, initial-scale=1.0" />' - printf '<link rel="stylesheet" href="%s" type="text/css" />\n' "${css_include[@]}" + echo '<!DOCTYPE html>' + echo '<html><head>' + echo '<meta charset="UTF-8">' + echo '<meta name="viewport" content="width=device-width, initial-scale=1.0">' + printf '<link rel="stylesheet" href="%s" type="text/css">\n' "${css_include[@]}" if [[ -z $global_feedburner ]]; then - echo "<link rel=\"alternate\" type=\"application/rss+xml\" title=\"$template_subscribe_browser_button\" href=\"$blog_feed\" />" + echo "<link rel=\"alternate\" type=\"application/rss+xml\" title=\"$template_subscribe_browser_button\" href=\"$blog_feed\">" else - echo "<link rel=\"alternate\" type=\"application/rss+xml\" title=\"$template_subscribe_browser_button\" href=\"$global_feedburner\" />" + echo "<link rel=\"alternate\" type=\"application/rss+xml\" title=\"$template_subscribe_browser_button\" href=\"$global_feedburner\">" fi } > ".header.html" fi @@ -964,7 +1015,7 @@ create_includes() { else { protected_mail=${global_email//@/@} protected_mail=${protected_mail//./.} - echo "<div id=\"footer\">$global_license <a href=\"$global_author_url\">$global_author</a> — <a href=\"mailto:$protected_mail\">$protected_mail</a><br/>" + echo "<div id=\"footer\">$global_license <a href=\"$global_author_url\">$global_author</a> — <a href=\"mailto:$protected_mail\">$protected_mail</a><br>" echo 'Generated with <a href="https://github.com/cfenollosa/bashblog">bashblog</a>, a single bash script to easily create blogs like this one</div>' } >> ".footer.html" fi @@ -1120,6 +1171,15 @@ date_version_detect() { fi } +# Lists html files in directory ordering by their timestamps +# instead of modified date +list_html_by_timestamp() { + grep "$date_inpost" ./*.html \ + | sed -nr 's/<!-- '"$date_inpost"': #(.*)# -->$/\1/p' \ + | sort --field-separator=: --key=2 --stable --reverse \ + | sed -nr 's/^(.*):.*$/\1/p' +} + # Main function # Encapsulated on its own function for readability purposes # @@ -1189,6 +1249,7 @@ do_main() { all_posts all_tags make_rss + make_sitemap delete_includes } |