Created
July 29, 2015 18:16
-
-
Save JoshCheek/c5fe07ef663492c4fd4b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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