From 4b927c4f291655789ad2a99618b149ac951184a8 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Tue, 10 Apr 2018 19:11:33 +0300 Subject: [PATCH] add simple blog controller --- .gitignore | 90 ++++++++++++++++++++++++++++++ app/controllers/blog_controller.rb | 19 +++++++ app/models/post.rb | 54 ++++++++++++++++++ config/application.rb | 3 + spec/models/blog_spec.rb | 82 +++++++++++++++++++++++++++ 5 files changed, 248 insertions(+) create mode 100644 app/controllers/blog_controller.rb create mode 100644 app/models/post.rb create mode 100644 spec/models/blog_spec.rb diff --git a/.gitignore b/.gitignore index 45e8ddf..f0c4d7c 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,93 @@ _site .sass-cache .jekyll-metadata .DS_Store + +#---------------------------------------------------------------------------- +# Ignore these files when commiting to a git repository. +# +# See http://help.github.com/ignore-files/ for more about ignoring files. +# +# The original version of this file is found here: +# https://github.com/RailsApps/rails-composer/blob/master/files/gitignore.txt +# +# Corrections? Improvements? Create a GitHub issue: +# http://github.com/RailsApps/rails-composer/issues +#---------------------------------------------------------------------------- + +public/assets +.ruby-version + +# bundler state +/.bundle +/vendor/bundle/ +/vendor/ruby/ + +# minimal Rails specific artifacts +db/*.sqlite3 +/db/*.sqlite3-journal +/log/* +/tmp/* + +# add /config/database.yml if it contains passwords +/config/database.yml +/config/secrets.yml + +# various artifacts +**.war +*.rbc +*.sassc +.redcar/ +.sass-cache +/config/config.yml +/coverage.data +/coverage/ +/db/*.javadb/ +/db/*.sqlite3 +/doc/api/ +/doc/app/ +/doc/features.html +/doc/specs.html +/public/cache +/public/stylesheets/compiled +/public/system/* +/spec/tmp/* +/cache +/capybara* +/capybara-*.html +/gems +/specifications +rerun.txt +pickle-email-*.html +.zeus.sock + +# If you find yourself ignoring temporary files generated by your text editor +# or operating system, you probably want to add a global ignore instead: +# git config --global core.excludesfile ~/.gitignore_global +# +# Here are some files you may want to ignore globally: + +# scm revert files +**.orig + +# Mac finder artifacts +.DS_Store + +# Netbeans project directory +/nbproject/ + +# RubyMine project files +.idea + +# Textmate project files +/*.tmproj + +# vim artifacts +**.swp + +# Environment files that may contain sensitive data +.env +.powenv + +# tilde files are usually backup files from a text editor +*~ +app/views/blog/_2017-2-2-The-Distraction-Free-Path-to-Becoming-a-Professional-Programmer.haml diff --git a/app/controllers/blog_controller.rb b/app/controllers/blog_controller.rb new file mode 100644 index 0000000..1d708e0 --- /dev/null +++ b/app/controllers/blog_controller.rb @@ -0,0 +1,19 @@ +class BlogController < ApplicationController + + def index + @pages = Page.pages + end + + def page + title = params[:title] + return redirect_to(root_path) unless title + @page = get_page(title) + return redirect_to(root_path) unless @page + end + + def get_page(title) + page = Page.pages[title] + #puts "No #{title} in #{Page.pages.keys.join(':')}" + page + end +end diff --git a/app/models/post.rb b/app/models/post.rb new file mode 100644 index 0000000..67c115c --- /dev/null +++ b/app/models/post.rb @@ -0,0 +1,54 @@ +class Post + @@posts = nil + + attr_reader :year , :month , :day , :dir , :ext + + def initialize(path) + @dir = File.dirname(path) + base , @ext = File.basename(path).split(".") + raise "must be partial, statr with _ not:#{base}" unless base[0] == "_" + @words = base.split("-") + @year = parse_int(@words.shift[1 .. -1] , 2100) + @day = parse_int(@words.shift , 32) + @month = parse_int(@words.shift , 12) + raise "Invalid path #{path}" unless @words + end + + def slug + @words.join("-").downcase + end + def title + @words.join(" ") + end + def template_name + "#{date}-#{@words.join("-")}" + end + def date + "#{year}-#{day}-#{month}" + end + def parse_int( value , max) + ret = value.to_i + raise "invalid value #{value} > #{max}" if ret > max or ret < 1 + ret + end + def content + File.open("#{@dir}/_#{template_name}.#{ext}" ).read + end + def summary + ret = content.split("%h2").first.gsub("%p", "
").html_safe + ret[0 .. 400] + end + def self.posts + return @@posts if @@posts + @@posts ={} + Dir["#{self.blog_path}/_2*.haml"].reverse.each do |file| + post = Post.new(file) + @@posts[post.slug] = post + end + @@posts + end + + def self.blog_path + Rails.configuration.blog_path + end +end diff --git a/config/application.rb b/config/application.rb index 60fdc59..f662d6b 100644 --- a/config/application.rb +++ b/config/application.rb @@ -15,5 +15,8 @@ module RubyxWebpage # Application configuration can go into files in config/initializers # -- all .rb files in that directory are automatically loaded after loading # the framework and any gems in your application. + config.assets.paths << Gem.loaded_specs['susy'].full_gem_path+'/sass' + + config.blog_path = Rails.root.to_s + "/app/views/posts" end end diff --git a/spec/models/blog_spec.rb b/spec/models/blog_spec.rb new file mode 100644 index 0000000..851c4cb --- /dev/null +++ b/spec/models/blog_spec.rb @@ -0,0 +1,82 @@ +require 'rails_helper' + +RSpec.describe Post, type: :model do + + describe "creation" do + it "ok with valid slug" do + post = Post.new("_1993-2-4-title") + expect(post).not_to eq nil + end + it "raises with invalid slug" do + expect{Post.new("_1993-4-title")}.to raise_error RuntimeError + end + it "must start with a year" do + expect{Post.new("_no-num-4-title")}.to raise_error RuntimeError + end + it "must start with a underscore" do + expect{Post.new("_no-num-4-title")}.to raise_error RuntimeError + end + end + + describe "basic api" do + before :each do + @post = Post.new("_1993-2-4-title") + end + it "returns title" do + expect(@post.title).to eq "title" + end + it "returns dates" do + expect(@post.year).to eq 1993 + expect(@post.month).to eq 4 + expect(@post.day).to eq 2 + end + it "returns date" do + expect(@post.date).to eq "1993-2-4" + end + it "returns file_name" do + expect(@post.template_name).to eq "1993-2-4-title" + end + end + + describe "precise api definition" do + it "returns whole title" do + post = Post.new("_1993-2-4-Multi-word-title") + expect(post.title).to eq "Multi word title" + end + it "returns slug" do + post = Post.new("_1993-2-4-Multi-word-title") + expect(post.slug).to eq "multi-word-title" + end + it "returns title without extension if given file name" do + post = Post.new("_1993-2-4-title.rb") + expect(post.title).to eq "title" + end + it 'slugs are downcase' do + post = Post.new("_1993-2-4-Multi-word-title") + slug = post.slug + expect(slug.downcase).to eq slug + end + end + + describe "post list" do + before :each do + @posts = Post.posts + @first = @posts.values.first + end + it "reads config path" do + expect(Post.blog_path.include?("app")).to eq true + end + it "first post has content" do + expect(@posts.values.first).not_to be_nil + expect(@posts.values.first.content.length).to be > 10 + end + it "return a list of posts" do + expect(@posts.class).to eq Hash + expect(@posts.length).to be > 0 + end + it "post template exists" do + file = Post.blog_path + "/_" + @first.template_name + ".haml" + expect(File.exists?(file)).to eq true + end + end +end