Total Pageviews

Wednesday, 11 December 2013

在linux vps上搭建基于RUBY的静态博客程序-awestruct

gem install awestruct

as3:~# mkdir awstruct-site
as3:~# cd awstruct-site
as3:~/awstruct-site# awestruct --init --framework bootstrap
会显示:
Create directory: /root/awstruct-site/_config
Create directory: /root/awstruct-site/_layouts
Create directory: /root/awstruct-site/_ext
Create file: /root/awstruct-site/_ext/pipeline.rb
Create file: /root/awstruct-site/.awestruct_ignore
Create file: /root/awstruct-site/Rakefile
Create file: /root/awstruct-site/Gemfile
Create directory: /root/awstruct-site/stylesheets
directory _site/stylesheets/
directory images/
directory javascripts/
   create stylesheets/styles.scss
   create stylesheets/_variables.scss
   create images/glyphicons-halflings.png
   create images/glyphicons-halflings-white.png
   create javascripts/bootstrap-affix.js
   create javascripts/bootstrap-alert.js
   create javascripts/bootstrap-button.js
   create javascripts/bootstrap-carousel.js
   create javascripts/bootstrap-collapse.js
   create javascripts/bootstrap-dropdown.js
   create javascripts/bootstrap-modal.js
   create javascripts/bootstrap-popover.js
   create javascripts/bootstrap-scrollspy.js
   create javascripts/bootstrap-tab.js
   create javascripts/bootstrap-tooltip.js
   create javascripts/bootstrap-transition.js
   create javascripts/bootstrap-typeahead.js
   create _site/stylesheets/styles.css
Create file: /root/awstruct-site/_config/site.yml
Create file: /root/awstruct-site/_layouts/base.html.haml
Create file: /root/awstruct-site/index.html.haml

as3:~/awestruct-site# awestruct --generate (这个就是生成static site的命令)
Using profile: NONE
Generating site: http://localhost:4242
as3:~/awestruct-site# ls
_config  Gemfile       images           javascripts  Rakefile  stylesheets
_ext     Gemfile.lock  index.html.haml  _layouts     _site     _tmp
as3:~/awestruct-site# ls _site
images  index.html  javascripts  stylesheets
as3:~/awestruct-site#
可见~/awestruct-site/_site/就是静态网站的根目录。
as3:~/awestruct-site/_site# nohup Rwebserver 5640 > /dev/null &
访问http://as3.brite.biz:5640/,即可看到网站效果。

至于如何发贴,看本文的底部。

某人写的教程:
https://github.com/mojavelinux/decks/blob/master/awestruct-git/slides.asciidoc

演示站点: http://as3.brite.biz:5640/,http://awst.brite.biz/
项目地址:https://github.com/awestruct/awestruct
官网:http://awestruct.org
 http://awestruct.org/getting_started/
 http://awestruct.org/extensions/posts/ (好好看看这里如何发贴)
------------------------------------------------------------------------------------------

Setting Up an Awestruct-based Blog


In case you missed the announcement, I recently migrated my blog from Wordpress to Awestruct, the static site generation tool written by several JBoss engineers. As can be expected with a tool this new, there were some bumps and bruises along the way, but I managed — with lots of help — to make it to production with my efforts. To be a good open source citizen, then, I thought I’d explain my process and try to pass on what I learned.
The first step is, of course, installing Awestruct, which is pretty simple:
$ gem install awestruct
$ awestruct -i -f bootstrap
That will install Awestruct and bootstrap your site. The "bootstrap" used in the command line tells Awestruct to use the bootstrap javascript framework. The other options are blueprint and 960. I honestly can’t tell you what the differences are. I think I used blueprint, which seems to be the smallest starting point.
Once that’s done, I would suggest deleting all of the .haml files. HAML seems to be Awestruct’s default/preferred markup language, but it seems "everyone" is moving toward slim. We’ll see what that looks like below.

_config/site.yml

Let’s start with the _config/site.yml. Something like this seems to be pretty common:
title: My Blog
author: Jason Lee
local_tz: America/Chicago
interpolate: false
disqus: myblog.com
base_url: http://localhost:1234

asciidoctor:
  :compact: true
  :eruby: erubis
  :attributes:
    idprefix: ''
    idseparator: '-'

scss:
  :line_numbers: true
  :style: :expanded
# if no profile is specified, the first with a deploy config is selected
profiles:
  development:
    minify: false
    disqus_developer: true
    dev: true
    deploy:
      dummy:
  production:
    base_url: http://www.myblog.com
    #disqus_developer: false
    google_analytics: UA-1234567-1
    minify: true
    deploy:
      host: user@myblog.com
      path: /home/user/path/to/site
A lot of these properties should be self-explantory, so I’ll only discuss those that aren’t. The first is interpolate. Most people may not need this, but I do a lot of blogging about JSF (though not as much I used to, I guess :). As part of that, I have a lot of EL expressions, such as #{someBean.someProperty}, in my posts. Without this option, Awestruct will try to "interpolate" the text, at which point that expression will be processed as if it were a Ruby string. Since someBean hasn’t been defined in the Ruby process, an error occurs and the build fails. If you don’t have EL expressions or something similar, it may be safe to leave this set to its default of true.
I think the only one left that needs discussion is profiles.production.deploy. In my case, I have a shared host to which I want to deploy the generated site. With this configuration, when you tell Awestruct to deploy your site, it will rsync, via ssh, to myblog.com, logging in as user, and putting the files in /home/user/path/to/site. The nice thing is that it will remove files from the remote site if they are removed from the local build, so you don’t have to manage that manually.
We’ll discuss (no pun intended), disqus and disqus_developer later.

_ext/pipeline.rb

The next important file is _ext/pipeline.rb. While site.yml configures your site, pipeline.rb configures Awestruct itself. Here you enable extensions and helpers, basically turning features on and off. As of the time of this writing, I have two Awestruct based sites, and their pipeline files look basically like this:
require 'readmore'
require 'erubis'
require 'tilt'

Awestruct::Extensions::Pipeline.new do
  extension Awestruct::Extensions::Posts.new( '/posts', :posts)
  extension Awestruct::Extensions::Paginator.new( :posts, '/index', :per_page => 10 )
  extension Awestruct::Extensions::Tagger.new( :posts, '/index', '/posts/tags', :per_page => 10)
  extension Awestruct::Extensions::TagCloud.new( :tagcloud, '/posts/tags/index.html', :layout=>'base', :title=>'Tags')
  extension Awestruct::Extensions::Disqus.new

  extension Awestruct::Extensions::Indexifier.new
  extension Awestruct::Extensions::Atomizer.new( :posts, '/feed.atom', :feed_title=>'Steeplesoft' )

  helper Awestruct::Extensions::Partial
  helper Awestruct::Extensions::GoogleAnalytics
  helper Awestruct::Extensions::ReadMore
end
I don’t know Ruby (though I’ve learned some in this process), but this seems pretty straightforward to me: require is like a Java import, and the do block is configuring a new Pipeline object. Syntax questions aside, here’s my understanding of the file:
  • The Posts extension is configured. We’re telling the system to look for the posts in file under the /posts directory. An array of post objects is then stored in the posts variable.
  • The Paginator extension is added, using the posts array. It seems the paginator needs to know the location of the paginator, which is our index file, /index. I don’t know why it doesn’t seem to need the extension. Finally, we want to have 10 posts per page.
  • The Tagger extension will build data based on the tags information at the top of each post (which we’ll see in a minute). It creates static tag navigation files under /posts/tags, and it also has only 10 posts per page.
  • The TagCloud extension is here mainly to show you that it exists. I have not yet figured out how to make it work. Maybe someone can show me what I’m doing wrong. :P
  • Since this is a static site, we can’t use a local database for comments, so we’re adding support for Disqus to our site.
  • The Indexifier and Atomizer extensions are used to create the news feed for your site, which I still find important and helpful, even if Google disagress (R.I.P., Google Reader! :)
  • The Partial helper allows us to define — hold on to your seats — reusable parts of a page. We’ll see this in more detail later.
  • The GoogleAnalytics helper should be self-explanatory.
  • ReadMore is an extension I wrote to duplicate the "read more" functionality of Wordpress. It’s in a file called readmore.rb and goes in _ext. It looks like this:
module Awestruct
  module Extensions
    module ReadMore
      def truncate(content)
        index = content.index("pass::[more]")
        if index != nil
            if index > -1
                return content[0..index-1]
            end
        end
        return content
      end
      def filter(content)
        index = content.index("pass::[more]")
        if index != nil
            if index > -1
                content[index..index+11]= ""
            end
        end
        content
      end
    end
  end
end
Pages and posts should be able to put pass::[more] on a line by itself and things will work as expected: in page listing, the content stops at pass::[more], and on full posts, pass::[more] is removed from the output. The rest of the ugliness of the file is due to the fact that I don’t know Ruby, so I was shooting in the dark. Feel free to clean it up, but, if you do, I’d love to see your better version. :)

Layouts

With the site and Awestruct configured, we now need to create the look and feel for the site. This can, of course, be as fancy as you want. For this example, it’s going to be simple and ugly, but, hopefully, educational. :) Again, the Awestruct initialization will create a .haml file, which we want to delete. Instead, we want to create _layouts/base.html.slim:
doctype 5
html
  head
    meta charset='utf-8'
    title=(page.title ? [page.title, site.title] : [site.title]) * ' | '
    link rel="stylesheet" href='/styles/style.css'
    script src='/scripts/some.js'
    javascript:
        someInlineJs();
    css:
      .someInlineCss {
      }
  body class="someInlineCss"
    div.header
        h1
            My Site
    div.content
        = content
    div.footer
        h3
            I'm in the footer!
    javascript:
    - if site.google_analytics
        =google_analytics_async
The slim syntax is pretty simple, but, more importantly, really clean and light. No angle brackets. Yea! Hopefully, this all pretty straightforward. For more information on the slim syntax, you can visit its home page. The import part here is the = content line. This is where the information from each page, or post, will be inserted. How do we do that? Let’s go back to the index file.

index.html.slim

My index pages look more or less like this:
---
layout: base
---
#content
    =partial('pagination.html.slim', :posts => page.posts)
    div style="clear: both"
    - page.posts.each do |post|
        =partial('entry.html.slim', :post => post, :listing => true)
    =partial('pagination.html.slim', :posts => page.posts)
The text in between the --- markers provides metadata Awestruct needs, such as title, author, tags, publish date, etc. The #content line defines a div with an ID of content. The next line =partial..., makes use of the Partial helper. In this case, we tell it to use the template pagination.html.slim, which is under _partials, and assign the variable posts the value of page.posts. We’ll look at the partial in a moment.
The next line shows how to specify an HTML tag with arbitrary attributes.
Next we have, as best as I can tell (and I’m just pulling a term from the air), a directive to Awestruct, which seems to be, more or less, straight Ruby code. Whatever the right term is, what we have is a loop over the array page.posts, and calls partial for each element, this time using entry.html.slim. Finally, we output the navigation partial again so we can have prev/next at the top and bottom.

Partials

Partials allow us to define a small snippet of…parameterized HTML that we can reuse. We’ve already seen the usages of two: pagination and entry. These files are simple slim files:
pagination.html.slim
div.pagination
    div.previous style="width:50%; float: left"
        - if page.posts.previous_page
          a href=page.posts.previous_page.url Previous
        - if !page.posts.previous_page
          p Previous
    div.next style="width:50%; float: right; text-align: right"
        - if page.posts.next_page
          a href=page.posts.next_page.url Next
        - if !page.posts.next_page
          p Next
In this partial, we use the variable page.posts, which we set in the call to partial above.
entry.html.slim
article.post
  header.entry-header
    h1.title
      a href=page.post.url =page.post.title
    h4
      time.pubdate datetime=page.post.date.strftime('%FT%T%:z') =page.post.date.strftime "%A, %B #{page.post.date.day}, %Y"
  .entry-content
    = truncate(page.post.content)
  footer.entry-footer
    - if page.post.tags
      .tags
        span.title
          | tags:
        - page.post.tags.each do |tag|
          a href="/posts/tags/#{tag}"
            - if tag != page.post.tags.last
              ="#{tag}, "
            - else
              ="#{tag} "
  - if site.disqus
    #comments
      =page.post.disqus_comments
This partial operates on a single element in our posts array, which we’ve assigned to post. Not also that, using an =, we can insert Ruby snippets to perform simple transformations. Here, I’m breaking the post date apart to generate a better looking date block.
At the very end, we see Disqus come back up. When the Disqus plugin is properly configured as we did above, all the needs to be done to make use of on the page is to put =page.post.disqus_comments somewhere on your page. At build time, Awestruct does all the work required to generate the HTML and JS to do the actual integration.

Site Content

We can now look at the important part of this exercise, the site content itself. Personally, I’m a pretty big fan of Asciidoc, so we’re going to write our pages and post using that. Before we look at blog entries, let’s take a quick look at the simple page use case.
For a "normal" page, such as an About page, for which you simply need to create a page called about.adoc:
---
title: About
author: Jason Lee
---
h1
    About
This page is all about me!
When the site is built, this page can be accessed via http://localhost:1234/about. Each .adoc file is compiled to a directory with the same name as the file, which contains the file index.html.
Blog posts are only slight more complicated, as it seems there are conventions that need to be followed. Based on our configuration above, all blog posts must be put in the posts/ directory, and it seems, must follow the naming scheme yyyy-mm-dd-blog-post-title.adoc. Other than that, they look pretty much like any other page, with a couple more metadata entries:
---
title: Blog Post Title
author: Jason Lee
date: 2013-04-19
tags: [tag1, tag2]
---
Blog content
If you know Asciidoc, you should be ready to author your post. It’s important to note that the value of tags must be an array, or the page will fail to compile.

Testing

Before we’re ready to push this site live, we need to test it. Awestruct comes with a simple server that should be sufficient for most cases. While starting is very simple, I have a small shell script I use, as I like to force a site clean up before I start the server, and I need to change the port on which the server listens:
#!/bin/bash

rm -rf _tmp _site
awestruct --auto --server --port 1234 --profile development
The site is now available at http://localhost:1234. For simple changes, such as page content changes, Awestruct will detect changes and recompile the page, making it more or less immediately available. For other changes, such as configuration changes, you will have to restart the server.

Deployment

Once we have our site set up and looking the way want it to, we’re ready to deploy. Again, Awestruct makes this very simple:
$ awestruct -P production -g --force --deploy
Here we’re telling Awestruct to use the production profile, to generate the site (forcing it to do so even if it thinks it doesn’t need to), and then to deploy the site using the configuration in _config/site.yml. In our case here, it will rsync the generated site with the remote host. Once that finishes, your very lightweight and, therefore, very fast web site is ready for public consumption.

Final Notes

As I’ve kind of hinted at, I’m still pretty new to Awestruct, so there’s a really good chance I have some things wrong: terms, techniques, other assumptions. What I’ve put together here, though, should, I hope, spare you some of the pain I went through in trying to come up to speed with tool. For things I’ve not made clear — or covered — or got completely wrong, the folks in #awestruct on Freenode are very helpful. I’ve gotten great support from Dan Allen, Aslak Knutsen, Jason Porter, and Bob McWhirter and others there. I try to hang out there as well, but as of right now, everything I know is in this document. :)
Give it a go, then, and let me know if you run into problems with my instructions, and I’ll do my best to clarify and correct. Good luck.

from http://blogs.steeplesoft.com/posts/2013/04/19/Setting-Up-an-Awestruct-based-Blog/
------------------
 使用steeplesoft-blog对awestruct所修改的源码搭建静态博客

wget  https://bitbucket.org/jdlee/steeplesoft-blog/get/87e732fbac58.zip
unzip 87e732fbac58.zip
mv  jdlee-steeplesoft-blog-87e732fbac58 steeplesoft-blog
cd  steeplesoft-blog

as3:~/steeplesoft-blog# ls
about.ad  Gemfile          _layouts   projects.ad  scripts
_config   images           _partials  Rakefile         videos
_ext      index.html.slim  posts      resume.pdf   styles
as3:~/steeplesoft-blog# cd _config
as3:~/steeplesoft-blog/_config# ls
site.yml 
as3:~/steeplesoft-blog/_config# cp site.yml site.yml.bak
as3:~/steeplesoft-blog/_config# nano site.yml
把site.yml 文件中的production:这行下面的一行的base_url的值改为你的域名地址,我的情形为:
    base_url: http://ss.bright.za.net

发贴方法:
as3:~/steeplesoft-blog/_config# cd ..
as3:~/steeplesoft-blog# cd posts
as3:~/steeplesoft-blog/posts# nano 2014-02-14-test2.ad
按~/steeplesoft-blog/posts/里面某个ad文件的内容格式,新建帖子
2014-02-14-test2.ad,格式如下:
---
title: 测试2
author: ym
date: 2014-02-14
layout : blog-post
tags: [ misc1, misc2 ]
---

这是测试2.


as3:~/steeplesoft-blog/posts# cd ..
as3:~/steeplesoft-blog# awestruct -P production --generate --force
(这个是生成/更新静态网站的命令)
as3:~/steeplesoft-blog# ls
about.ad  Gemfile          _layouts   projects.ad  scripts  _tmp
_config   images           _partials  Rakefile     _site    videos
_ext      index.html.slim  posts      resume.pdf   styles
as3:~/steeplesoft-blog#
(新出现了_site目录)
as3:~/steeplesoft-blog# cd _site
as3:~/steeplesoft-blog/_site# ls
about      images      page   projects    scripts  videos
feed.atom  index.html  posts  resume.pdf  styles
as3:~/steeplesoft-blog/_site#
可见 ~/steeplesoft-blog/_site/就是静态网站的根目录。

演示站点:http://ss.bright.za.net/
项目地址:https://bitbucket.org/jdlee/steeplesoft-blog
作者的教程:http://blogs.steeplesoft.com/posts/2013/04/19/Setting-Up-an-Awestruct-based-Blog/

注意:如果你要在一个源贴中,插入html code,须在html code的上方一行和下方一行各加上5个加号+++++
----------------------------
另外一个示例:
as3:~# git clone https://github.com/wesleyhales/wesleyhales.com wesleyhales.com-site
as3:~# cd wesleyhales.com-site
as3:~/wesleyhales.com-site# 
as3:~/wesleyhales.com-site# ls
404.html.haml      experiment       js                  rwx.html     _tweets
blog               _ext             _layouts                                      type
build              favicon.ico      orientation         slides       workers
_config            Gemfile          post-icon.psd       storage
contact.html.haml  images           projects.html.haml  stylesheets
design.html.haml   index.html.haml  Rakefile            test.html
_examples          iscroll          readme.md           _tmp
as3:~/wesleyhales.com-site# nano _config/site.yml
把site.yml 文件中的production:这行下面的一行的base_url的值改为你的域名地址,我的情形为:
    base_url: http://wh.brite.biz.st

发贴方法:
as3:~/wesleyhales.com-site# cd blog
as3:~/wesleyhales.com-site/blog# nano 2014-03-18-test1.md
按~/wesleyhales.com-site/blog/里面某个md文件的格式,新建帖子2014-03-18-test1.md,格式如下:
---
layout: blog
title: 测试1
tags: [misc1, misc2, misc3]
preview: 点击标题看全文
---

这是测试1.


然后,
as3:~/wesleyhales.com-site/blog# cd ..
as3:~/wesleyhales.com-site#  awestruct -P production --generate --force
as3:~/wesleyhales.com-site# ls
404.html.haml      experiment       js                  rwx.html     _tweets
blog               _ext             _layouts            _site        type
build              favicon.ico      orientation         slides       workers
_config            Gemfile          post-icon.psd       storage
contact.html.haml  images           projects.html.haml  stylesheets
design.html.haml   index.html.haml  Rakefile            test.html
_examples          iscroll          readme.md           _tmp
(新出现了_site目录)
as3:~/wesleyhales.com-site# cd _site
as3:~/wesleyhales.com-site/_site# ls
404        design       iscroll      post-icon.psd  slides       type
blog       favicon.ico  js           projects       storage      workers
blog.atom  images       orientation  readme         stylesheets
contact    index.html   page         rwx            test
(可见~/wesleyhales.com-site/_site/就是静态网站的根目录)
as3:~/wesleyhales.com-site/_site#  nohup Rwebserver 43257 > /dev/null &
访问http://as3.brite.biz:43257/就可见到网站效果。

演示站点:http://wh.brite.biz.st/ ,http://as3.brite.biz:43257
项目地址:https://github.com/wesleyhales/wesleyhales.com
作者的教程:http://wesleyhales.com/blog/2013/03/29/Fun-with-Static-Site-Generators-and-Travis/ (作者的此做法有点复杂)
-------------------

 https://github.com/mgreau/mgreau.github.io
--------------------

https://github.com/LightGuard/seam_site_awestruct