Skip to content

Instantly share code, notes, and snippets.

@JoshCheek
Created July 29, 2015 18:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoshCheek/c5fe07ef663492c4fd4b to your computer and use it in GitHub Desktop.
Save JoshCheek/c5fe07ef663492c4fd4b to your computer and use it in GitHub Desktop.
require 'active_record'
require 'erb'
require 'logger'
ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: ':memory:'
ActiveRecord::Base.logger = Logger.new $stdout
ActiveSupport::LogSubscriber.colorize_logging = false
ActiveRecord::Schema.define do
self.verbose = false
create_table :pages do |t|
t.string :name
t.integer :num_locations
t.text :template
# If template, then that implies we need to figure out how to put the contents into it.
# Otherwise, probably `:body` and delete the contents table.
# In that case, we can put all of the content into the body,
# and don't need any abstractions for any of this shit.
end
create_table :contents do |t|
t.string :body
t.string :content_type
t.integer :page_id
t.integer :location
end
end
class Page < ActiveRecord::Base
has_many :contents
validates :name, uniqueness: true
def content_for(n)
raise IndexError if n < 1
raise IndexError if n > num_locations
content = contents.find { |content| content.location == n }
content || Content.null(n)
end
end
class Content < ActiveRecord::Base
def self.null(location=1)
new location: location, content_type: 'html', body: "Not yet set"
end
belongs_to :page
def type?(type)
content_type == type.to_s
end
end
Page.create! do |page|
page.name = "Home"
page.num_locations = 3
page.contents.build location: 2, content_type: 'html', body: <<-HTML.strip_heredoc
<div class="video">
<h1>How Monsanto is doing it</h1>
<iframe>...</iframe>
</div>
HTML
page.contents.build location: 1, content_type: 'markdown', body: <<-MARKDOWN.strip_heredoc
This is an h2
-------------
And this is a paragraph
MARKDOWN
page.template = <<-HTML.strip_heredoc
<h1>$NAME</h1>
<p>Check our shit out!</p>
$LOCATION1
$LOCATION2
$LOCATION3
<p>Thanks for visiting!</p>
HTML
end
# /admin/static_pages/home
# route_set.draw do
# namespace :admin do
# get "/static_pages/:name", to: "static_pages#edit", as: :static_pages
# put "/static_pages/:name", to: "static_pages#update"
# patch "/static_pages/:name", to: "static_pages#update"
# end
# get "/:name", to: "static_pages#show", as: :static_pages
# end
class ApplicationController
attr_accessor :params
def initialize(params:)
self.params = params
end
def render(whatever)
# faking out the static pages rendering shit
app_views_static_pages_show_erb_html = <<-ERB.strip_heredoc
<nav>Here are some links and shit...</nav>
<content>
<%= @template %>
<content>
ERB
ERB.new(app_views_static_pages_show_erb_html).result(binding)
end
end
class StaticPagesController < ApplicationController
def show
if params[:name].nil?
puts "\e[31mExpected params[:name] to be something like 'home', but it's nil!\e[0m"
p params
require 'pry'
binding.pry
end
@page = Page.find_by!(name: params[:name].capitalize)
@template = MyTemplateRenderer.new(@page).render
render 'static_page'
end
end
module Admin
class StaticPagesController < ApplicationController
def edit
# ...
end
def update
# ...
end
end
end
require 'redcarpet'
class MyTemplateRenderer
def initialize(page)
@page = page
end
attr_reader :page
def render
rendered = @page.template
.gsub("$NAME", @page.name)
.gsub(/\$LOCATION(\d+)/) { |n| content_for $1.to_i }
if rendered.include?('<%')
raise "Wtf?! there's erb in this template: #{rendered.inspect}"
end
rendered
end
def content_for(location)
content = page.content_for(location)
body = content.body
if content.type? :markdown
renderer = Redcarpet::Render::HTML.new
markdown = Redcarpet::Markdown.new(renderer)
body = markdown.render(body)
end
body
end
end
puts StaticPagesController
.new(params: {name: "home"})
.show
# >> D, [2015-07-29T12:14:36.114904 #20567] DEBUG -- : (0.4ms) CREATE TABLE "pages" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar, "num_locations" integer, "template" text)
# >> D, [2015-07-29T12:14:36.115352 #20567] DEBUG -- : (0.1ms) CREATE TABLE "contents" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "body" varchar, "content_type" varchar, "page_id" integer, "location" integer)
# >> D, [2015-07-29T12:14:36.155901 #20567] DEBUG -- : (0.1ms) begin transaction
# >> D, [2015-07-29T12:14:36.162014 #20567] DEBUG -- : Page Exists (0.1ms) SELECT 1 AS one FROM "pages" WHERE "pages"."name" = 'Home' LIMIT 1
# >> D, [2015-07-29T12:14:36.162668 #20567] DEBUG -- : SQL (0.1ms) INSERT INTO "pages" ("name", "num_locations", "template") VALUES (?, ?, ?) [["name", "Home"], ["num_locations", 3], ["template", "<h1>$NAME</h1>\n\n<p>Check our shit out!</p>\n\n$LOCATION1\n$LOCATION2\n$LOCATION3\n\n<p>Thanks for visiting!</p>\n"]]
# >> D, [2015-07-29T12:14:36.163386 #20567] DEBUG -- : SQL (0.1ms) INSERT INTO "contents" ("location", "content_type", "body", "page_id") VALUES (?, ?, ?, ?) [["location", 2], ["content_type", "html"], ["body", "<div class=\"video\">\n <h1>How Monsanto is doing it</h1>\n <iframe>...</iframe>\n</div>\n"], ["page_id", 1]]
# >> D, [2015-07-29T12:14:36.164008 #20567] DEBUG -- : SQL (0.0ms) INSERT INTO "contents" ("location", "content_type", "body", "page_id") VALUES (?, ?, ?, ?) [["location", 1], ["content_type", "markdown"], ["body", "This is an h2\n-------------\n\nAnd this is a paragraph\n"], ["page_id", 1]]
# >> D, [2015-07-29T12:14:36.164299 #20567] DEBUG -- : (0.0ms) commit transaction
# >> D, [2015-07-29T12:14:36.196117 #20567] DEBUG -- : Page Load (0.2ms) SELECT "pages".* FROM "pages" WHERE "pages"."name" = ? LIMIT 1 [["name", "Home"]]
# >> D, [2015-07-29T12:14:36.197559 #20567] DEBUG -- : Content Load (0.1ms) SELECT "contents".* FROM "contents" WHERE "contents"."page_id" = ? [["page_id", 1]]
# >> <nav>Here are some links and shit...</nav>
# >> <content>
# >> <h1>Home</h1>
# >>
# >> <p>Check our shit out!</p>
# >>
# >> <h2>This is an h2</h2>
# >>
# >> <p>And this is a paragraph</p>
# >>
# >> <div class="video">
# >> <h1>How Monsanto is doing it</h1>
# >> <iframe>...</iframe>
# >> </div>
# >>
# >> Not yet set
# >>
# >> <p>Thanks for visiting!</p>
# >>
# >> <content>
require 'redcarpet'
class MyTemplateRenderer
def initialize(page)
@page = page
end
attr_reader :page
def render
rendered = @page.template
.gsub("$NAME", @page.name)
.gsub(/\$LOCATION(\d+)/) { |n| content_for $1.to_i }
if rendered.include?('<%')
raise "Wtf?! there's erb in this template: #{rendered.inspect}"
end
rendered
end
def content_for(location)
content = page.content_for(location)
body = content.body
if content.type == :markdown
renderer = Redcarpet::Render::HTML.new
markdown = Redcarpet::Markdown.new(renderer)
body = markdown.render(body)
end
body
end
end
class Page
def initialize(name, template, contents)
@name, @template, @contents = name, template, contents
end
attr_accessor :name, :template
def content_for(location)
@contents[location-1]
end
end
Content = Struct.new :type, :body
contents = [
Content.new(:html, <<-HTML),
<div class="banner">
Connecting Businesses, Communities and the Tech Talent Pipeline
</div>
HTML
Content.new(:markdown, <<-MARKDOWN.gsub(/^ */, '')),
This is an h2
-------------
And this is a paragraph
MARKDOWN
Content.new(:html, <<-HTML),
<div class="video">
<h1>How Monsanto is doing it</h1>
<iframe>...</iframe>
</div>
HTML
]
page = Page.new("Home", <<-HTML, contents)
<h1>$NAME</h1>
<p>Check our shit out!</p>
$LOCATION1
$LOCATION2
$LOCATION3
<p>Thanks for visiting!</p>
HTML
puts MyTemplateRenderer.new(page).render
# >> <h1>Home</h1>
# >>
# >> <p>Check our shit out!</p>
# >>
# >> <div class="banner">
# >> Connecting Businesses, Communities and the Tech Talent Pipeline
# >> </div>
# >>
# >> <h2>This is an h2</h2>
# >>
# >> <p>And this is a paragraph</p>
# >>
# >> <div class="video">
# >> <h1>How Monsanto is doing it</h1>
# >> <iframe>...</iframe>
# >> </div>
# >>
# >>
# >> <p>Thanks for visiting!</p>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment