export didn't work when sub pages

This commit is contained in:
did 2011-07-07 01:34:11 +02:00
parent 88325ca932
commit 007f34ed8c
31 changed files with 602 additions and 14 deletions

View File

@ -68,8 +68,9 @@ x remove withelist for assets since we've got now roles
x admin role is not correctly set when creating a new website
x the required star for file field is not shown
x Rights to set roles (ticket #104)
x export: problems with templatized pages (source => multi levels pages)
- do not rename files for fonts
- test and/or convert existing templates (the 2 of the themes section)
- export: problems with templatized pages
- tooltip to explain the difference between 1.) Admin 2.) Author 3.) Designer?
- overide sort for contents

View File

@ -174,17 +174,25 @@ module Locomotive
case element
when EditableShortText, EditableLongText
el_attributes['content'] = self.replace_asset_urls_in(element.content)
el_attributes['content'] = self.replace_asset_urls_in(element.content || '')
when EditableFile
filepath = File.join('/', 'samples', element.source_filename)
self.copy_file_from_an_uploader(element.source, File.join(self.public_folder, filepath))
el_attributes['content'] = filepath
unless element.source_filename.blank?
filepath = File.join('/', 'samples', element.source_filename)
self.copy_file_from_an_uploader(element.source, File.join(self.public_folder, filepath))
el_attributes['content'] = filepath
else
el_attributes['content'] = '' # not sure if we run into this
end
end
(attributes['editable_elements'] ||= []) << el_attributes
end
File.open(File.join(self.pages_folder, "#{page.fullpath}.liquid"), 'w') do |f|
page_templatepath = File.join(self.pages_folder, "#{page.fullpath}.liquid")
FileUtils.mkdir_p(File.dirname(page_templatepath))
File.open(page_templatepath, 'w') do |f|
f.write(self.replace_asset_urls_in(page.raw_template))
end
end

View File

@ -20,7 +20,7 @@ module Locomotive
def end_tag
super
if @context[:page].present?
@context[:page].add_or_update_editable_element({
:block => @context[:current_block].try(:name),
@ -39,7 +39,7 @@ module Locomotive
current_page = context.registers[:page]
element = current_page.find_editable_element(context['block'].try(:name), @slug)
if element.present?
unless element.default_content.present?
element.default_content = render_default_content(context)
@ -60,7 +60,7 @@ module Locomotive
def document_type
raise 'FIXME: has to be overidden'
end
def default_content_option
result = nil
if @options[:default].present?
@ -68,12 +68,9 @@ module Locomotive
end
result
end
def render_default_content(context)
puts "Old: #{@nodelist.first.to_s}"
result = render_all(@nodelist, context)
puts "New: #{result.inspect}"
result
render_all(@nodelist, context)
end
end

View File

@ -0,0 +1,9 @@
{% extends 'index' %}
{% block content %}
<section id="404">
<h2 class="404">Page not found</h2>
</section>
{% endblock %}

View File

@ -0,0 +1,12 @@
{% extends parent %}
{% block content %}
<section id="about">
<h2 class="about">{{ page.title }}</h2>
{% editable_long_text 'about', hint: "Some text about my website" %}
<p>Now this is a story all about how my life got twisted upside down and I'd like to take a minute just sit right there I'll tell you how I became the prince of a town called Bel-Air. In West Philadelphia born and raised on the playground my momma said most of my days chilling out, maxing and relaxing all cool and all shooting some b-ball outside of school when a couple of guys they were up to no good started making trouble in our neighbourhood I got in one little fight and my mom got scared, she said your moving in with your auntie and uncle in Bel-Air</p>
{% endeditable_long_text %}
</section>
{% endblock %}

View File

@ -0,0 +1,29 @@
{% extends parent %}
{% block content %}
<section id="contact">
<h2 class="contact">{{ page.title }}</h2>
{% editable_long_text 'contact text', hint: 'Text displayed just above the form' %}
<p>I whistled for a cab and when it came near the license plate said fresh and had dice in the mirror, if anything I could say that this cab was rare but I thought nah, <a href="/">forget it</a>, yo home to Bel-Air! I pulled up to the house about seven or eight I yelled to the cabbie yo home, smell you later, looked at my kingdom I was finally there to sit on my throne as the prince of Bel-Air</p>
{% endeditable_long_text %}
<form id="contactform" action="{{ contents.messages.api.create }}.html" method="post">
<input type="hidden" name="success_callback" value="/contact/success" />
<input type="hidden" name="error_callback" value="/contact/error" />
<p><label for="name">Name</label></p>
<input type="text" id=name name="content[name]" placeholder="First and last name" required tabindex="1" />
<p><label for="email">Email</label></p>
<input type="text" id=email name="content[email]" placeholder="example@domain.com" required tabindex="2" />
<p><label for="comment">Your Message</label></p>
<textarea name="content[message]" id="comment" tabindex="4" required></textarea>
<input name="submit" type="submit" id="submit" tabindex="5" value="Send Message" />
</form>
</section>
{% endblock %}

View File

@ -0,0 +1,13 @@
{% extends parent %}
{% block content %}
<section id="contact">
<h2 class="contact">{{ page.title }}</h2>
<p class="error">We were unable to record your message.</p>
</section>
{% endblock %}

View File

@ -0,0 +1,13 @@
{% extends parent %}
{% block content %}
<section id="contact">
<h2 class="contact">{{ page.title }}</h2>
<p class="success">Dear <b>{{ message.name }}</b>, Thank you ! <br/>We'll get back to you as soon as possible.</p>
</section>
{% endblock %}

View File

@ -0,0 +1,84 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xml:lang="en" lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>{{ site.name }}</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<!--[if IE]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<!--[if IE 7]>
{{ 'ie' | stylesheet_tag }}
<![endif]-->
{{ 'style' | stylesheet_tag }}
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js" type="text/javascript"></script>
{% inline_editor %}
</head>
<body>
<header> <!-- HTML5 header tag -->
<div id="headercontainer">
<h1><a class="introlink anchorLink" href="/">{{ site.name }}</a></h1>
<nav> <!-- HTML5 navigation tag -->
<ul>
<li><a class="introlink anchorLink" href="/">Home</a></li>
<li><a class="portfoliolink anchorLink" href="/portfolio">Portfolio</a></li>
<li><a class="aboutlink anchorLink" href="/about">About</a></li>
<li><a class="contactlink anchorLink" href="/contact">Contact</a></li>
</ul>
</nav>
</div>
</header>
<section id="contentcontainer">
{% block content %}
<section id="intro">
<h2 class="intro">
{% editable_short_text 'tagline', hint: 'the tagline website' %}
Hand-coded <strong>HTML</strong> and <strong>CSS</strong> is what I do. <span class="sub">It's what I'm good at so why not?</span>
{% endeditable_short_text %}
</h2>
{% with_scope featured: true %}
{% assign work = contents.projects.first %}
{% endwith_scope %}
<a class="featured" href="/portfolio/{{ work._permalink }}">
<img src="{{ work.banner.url }}" alt="Inspect Element large preview" />
</a>
<p>Featured Project: <a href="/portfolio/{{ work._permalink }}">{{ work.name }}</a></p>
</section>
{% endblock %}
<footer> <!-- HTML5 footer tag -->
<ul>
<li>{{ 'twitter.png' | theme_image_url | image_tag }} <a href="http://twitter.com/dinedine31">Follow us on Twitter</a></li>
<li>
<a href="http://inspectelement.com/articles/code-a-backwards-compatible-one-page-portfolio-with-html5-and-css3">Original template</a>
</li>
</ul>
</footer>
</section>
{% google_analytics '<your GA code>' %}
</html>

View File

@ -0,0 +1,22 @@
{% extends parent %}
{% block content %}
<section id="portfolio">
<h2 class="work">{{ page.title }}</h2>
{% paginate contents.projects by 3 %}
<ul class="work">
{% for work in paginate.collection %}
<li>
<a href="/portfolio/{{ work._permalink }}"><img src="{{ work.thumbnail.url }}" alt="{{ work.name }}" /></a>
</li>
{% endfor %}
</ul>
{{ paginate | default_pagination }}
{% endpaginate %}
</section>
{% endblock %}

View File

@ -0,0 +1 @@
{% extends 'contact/success' %}

View File

@ -0,0 +1 @@
{% extends parent %}

View File

@ -0,0 +1,26 @@
{% extends parent %}
{% block content %}
<section id="work">
<h2 class="work">{{ project.name }}</h2>
<p><b>Client</b>: {{ project.client.name }}</p>
<a class="featured" href="{{ project.url }}">
<img src="{{ project.banner.url }}" alt="Visit website" />
</a>
<div class="text">
{{ project.description }}
</div>
<h3>Our team</h3>
<ul>
{% for person in project.team %}
<li>{{ person.name }} <em>({{ person.position }})</em></li>
{% endfor %}
</ul>
</section>
{% endblock %}

View File

@ -0,0 +1,168 @@
site:
name: HTML5 portfolio
locale: en
meta_keywords: html5 portfolio theme locomotive cms
meta_description: portfolio powered by html5
pages:
index:
published: true
"404":
published: true
portfolio/template:
title: Template of a project
content_type: projects
published: true
contact/success:
title: Message posted
published: true
blog:
redirect_url: http://blog.locomotivecms.com
content_types:
clients:
name: clients
description: Fill the text here
slug: clients
highlighted_field_name: name
fields:
- name:
label: Name
kind: string
hint: Fill the text here
required: true
api_enabled: false
order_by: manually
contents:
- "My client #1": {}
- "My client #2": {}
- "My client #3": {}
messages:
name: Messages
description: Messages posted by new potential clients
slug: messages
highlighted_field_name: name
api_enabled: true
order_by: default
fields:
- name:
hint: Full name or company name
- email:
hint: Email
- message:
hint: Customer message
kind: text
people:
name: people
description: Fill the text here
slug: people
highlighted_field_name: name
fields:
- name:
label: Name
kind: string
hint: Fill the text here
required: true
- position:
label: Position
kind: string
hint: Fill the text here
required: false
api_enabled: false
order_by: manually
contents:
- Michael Scott:
position: Regional Manager
- Dwight Schrute:
position: Assistant to the Regional Manager
- Toby Flenderson:
position: Human Resources Manager
projects:
name: My projects
description: My portfolio
slug: projects
order_by: manually
highlighted_field_name: name
api_enabled: false
fields:
- name:
hint: the name of the project
- description:
kind: text
label: Short description
hint: some bla bla
- url:
label: Url
- thumbnail:
kind: file
hint: Image 300px by 204px
- banner:
kind: file
hint: Image 940px by 210px (home page and show)
- featured:
kind: boolean
hint: Displayed or not on the home page
- due_date:
kind: date
hint: The date the project should be finished
- client:
kind: has_one
hint: The client who ordered this project
target: clients
- team:
kind: has_many
hint: People who worked on this project
target: people
contents:
- Locomotive App:
description: <p>Lorem ipsum...</p>
thumbnail: /samples/contents/thumb_01.jpg
banner: /samples/contents/banner_01.jpg
featured: true
url: http://www.locomotiveapp.org
due_date: "2012-05-17"
client: "My client #1"
team:
- Michael Scott
- Dwight Schrute
- Toby Flenderson
- Locomotive test 1:
description: <p>Lorem ipsum...</p>
thumbnail: /samples/contents/thumb_01.jpg
banner: /samples/contents/banner_01.jpg
featured: false
url: http://www.locomotiveapp.org
due_date: 2012-05-17
client: "My client #2"
team:
- Michael Scott
- Toby Flenderson
- Locomotive test 2:
description: <p>Lorem ipsum...</p>
thumbnail: /samples/contents/thumb_01.jpg
banner: /samples/contents/banner_01.jpg
featured: false
url: http://www.locomotiveapp.org
client: "My client #1"
team:
- Michael Scott
- Locomotive test 3:
description: <p>Lorem ipsum...</p>
thumbnail: /samples/contents/thumb_01.jpg
banner: /samples/contents/banner_01.jpg
featured: false
url: http://www.locomotiveapp.org
client: "My client #3"
team:
- Toby Flenderson
- Locomotive test 4:
description: <p>Lorem ipsum...</p>
thumbnail: /samples/contents/thumb_01.jpg
banner: /samples/contents/banner_01.jpg
featured: false
url: http://www.locomotiveapp.org
client: "My client #1"
team:
- Dwight Schrute
- Toby Flenderson

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

View File

@ -0,0 +1,4 @@
header { position: absolute; left: 0; }
#intro h2 { margin-bottom: 100px; }
h2.work { width: 800px; }

View File

@ -0,0 +1,137 @@
* { margin: 0; padding: 0; outline: 0; }
/* HTML5 tags */
header, section, footer,
aside, nav, article, figure {
display: block;
}
@font-face { font-family: Keffeesatz; src: url(/fonts/YanoneKaffeesatz-Light.otf) format("opentype") }
@font-face { font-family: KeffeesatzBold; src: url(/fonts/YanoneKaffeesatz-Bold.otf) format("opentype") }
body { font-family: Keffeesatz, Arial; color: #4b4b4b; background: url(/images/pattern.gif); text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.2); }
::selection { background-color: rgba(122, 192, 0, 0.2); }
::-moz-selection { background-color: rgba(122, 192, 0, 0.2); border: 10px solid red; }
h1 { color: #fff; font-size: 40px; position: relative; top: 15px; }
h1 a { color: #fff; font-size: 40px; background-color: #ff5400; padding: 5px 25px 10px 25px; width: 300px; -webkit-border-radius: 10px; -moz-border-radius: 10px; -webkit-box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.4); -moz-box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.6); border-bottom: 1px solid rgba(0, 0, 0, 0.4); border-top: 1px solid rgba(255, 255, 255, 0.6);
background: -webkit-gradient(
linear,
left bottom,
left top,
color-stop(0.23, #c34000),
color-stop(0.62, #ff5400)
);
background: -moz-linear-gradient(
center bottom,
#c34000 23%,
#ff5400 62%
);
}
h1 a:hover { color: #fff; border-bottom: 1px solid rgba(0, 0, 0, 0.4); padding-bottom: 10px; background-color: #7ac000;
background: -webkit-gradient(
linear,
left bottom,
left top,
color-stop(0.23, #619702),
color-stop(0.62, #7ac000)
);
background: -moz-linear-gradient(
center bottom,
#619702 23%,
#7ac000 62%
);
}
h2 { padding-left: 125px; font-size: 66px; color: #ff5400; height: 105px; }
h2 span.sub { font-size: 48px; float: left; color: #4b4b4b; }
h2.intro { background: url(/images/intro.png) no-repeat -10px -10px; }
h2.work { background: url(/images/portfolio.png) no-repeat -10px -10px; }
h2.about { background: url(/images/about.png) no-repeat -10px -10px; }
h2.contact { background: url(/images/contact.png) no-repeat -10px -10px; }
a { color: #7ac000; text-decoration: none; border-bottom: 1px solid #7ac000; padding-bottom: 2px; }
a:hover { color: #ff5400; text-decoration: none; border-bottom: 1px solid #ff5400; padding-bottom: 2px; }
a:active { color: #ff5400; text-decoration: none; border-bottom: 1px solid #ff5400; padding-bottom: 2px; position: relative; top: 1px; }
p { font-size: 24px; margin-bottom: 15px; line-height: 36px; }
strong { font-family: KeffeesatzBold, Arial; }
header { padding: 5px 0; width: 100%; background-color: #000; margin-bottom: 25px; -webkit-box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.4); -moz-box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.4); position: fixed; z-index: 10; float: left; }
#headercontainer, #contentcontainer { width: 960px; margin: 0 auto; position: relative; }
#contentcontainer { float: none; padding-top: 0px; }
nav { width: auto; float: left; }
nav ul { position: absolute; right: 0; display: block; margin-top: -37px; }
nav ul li { display: inline; margin-left: 50px; }
nav ul li a { font-size: 24px; border-bottom: none; }
section { margin-bottom: 20px; padding-top: 150px; float: left; }
#intro h2 a { padding-bottom: 0px; }
#intro a.featured { padding-bottom: 0px; border-bottom: none; }
#intro a img { border: 5px solid rgba(122, 192, 0, 0.15); -webkit-border-radius: 5px; margin-top: 40px; margin-bottom: 5px; }
#intro a img:hover, #portfolio .work a img:hover, input:hover, textarea:hover { border: 5px solid rgba(122, 192, 0, 1); -webkit-box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.4); }
#intro a img:active, #portfolio .work a img:active { -webkit-box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1); }
#portfolio ul.work a { border-bottom: none; }
#portfolio ul.work a img { border: 5px solid rgba(122, 192, 0, 0.15); -webkit-border-radius: 5px; }
#portfolio ul.work { float: left; margin-left: -15px; width: 975px; }
#portfolio ul.work li { list-style: none; float: left; margin-left: 15px; margin-bottom: 15px; }
#portfolio .pagination { text-align: center; font-size: 20px; }
#portfolio .pagination a { margin: 0 5px; }
#portfolio .pagination a.prev_page,
#portfolio .pagination a.next_page { margin: 0px; padding: 0px; background: none ;}
#contact { margin-bottom: 0px; }
#contact .success { text-align: center; width: 940px; }
#work .text { margin-top: 30px; }
input[type="text"] { width: 400px; }
textarea { width: 750px; height: 275px; }
label { color: #ff5400; }
input, textarea { background-color: rgba(255, 255, 255, 0.4); border: 5px solid rgba(122, 192, 0, 0.15); padding: 10px; font-family: Keffeesatz, Arial; color: #4b4b4b; font-size: 24px; -webkit-border-radius: 5px; margin-bottom: 15px; margin-top: -10px; }
input:focus, textarea:focus { border: 5px solid #ff5400; background-color: rgba(255, 255, 255, 1); }
input[type="submit"] { border: none; cursor: pointer; color: #fff; font-size: 24px; background-color: #7ac000; padding: 5px 36px 8px 36px; -webkit-border-radius: 10px; -moz-border-radius: 10px; -webkit-box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.4); -moz-box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.6); border-bottom: 1px solid rgba(0, 0, 0, 0.4); border-top: 1px solid rgba(255, 255, 255, 0.6);
background: -webkit-gradient(
linear,
left bottom,
left top,
color-stop(0.23, #619702),
color-stop(0.62, #7ac000)
);
background: -moz-linear-gradient(
center bottom,
#619702 23%,
#7ac000 62%
);
}
input[type="submit"]:hover { color: #fff; border-bottom: 1px solid rgba(0, 0, 0, 0.4); background-color: #ff5400;
background: -webkit-gradient(
linear,
left bottom,
left top,
color-stop(0.23, #c34000),
color-stop(0.62, #ff5400)
);
background: -moz-linear-gradient(
center bottom,
#c34000 23%,
#ff5400 62%
);
}
input[type="submit"]:active { position: relative; top: 1px; }
footer { clear: both; float: left; margin-top: 50px; }
footer ul { margin-bottom: 150px; }
footer ul li { display: inline; margin-right: 50px; }
footer ul li a { font-size: 24px; margin-left: 10px; }
footer ul li img { vertical-align: bottom; position: relative; top: 2px; }

View File

@ -0,0 +1,59 @@
require 'spec_helper'
describe Locomotive::Export do
context 'when successful' do
before(:all) do
@site = Factory('another site')
# first import a brand new site
self.import_it
# then export it of course
@zip_file = self.export_it
end
it 'generates a zipfile' do
@zip_file.should_not be_nil
File.exists?(@zip_file).should be_true
end
it 'has the exact number of pages from the original site' do
self.unzip
Dir[File.join(self.zip_folder, 'app', 'views', 'pages', '**/*.liquid')].size.should == 10
end
def import_it
job = Locomotive::Import::Job.new(FixturedTheme.duplicate_and_open('default.zip'), @site, { :samples => true, :reset => true })
job.perform
job.success nil
end
def export_it
::Locomotive::Export.run!(@site, @site.name.parameterize)
end
def zip_folder
File.join(File.dirname(@zip_file), 'acme-website')
end
def unzip
return if @zip_file || File.exists?(self.zip_folder)
Zip::ZipFile.open(@zip_file) do |zipfile|
destination_path = File.dirname(@zip_file)
zipfile.each do |entry|
FileUtils.mkdir_p(File.dirname(File.join(destination_path, entry.name)))
zipfile.extract(entry, File.join(destination_path, entry.name))
end
end
end
after(:all) do
Site.destroy_all
end
end
end

View File

@ -2,6 +2,10 @@ require 'spec_helper'
describe 'Heroku support' do
before(:all) do
Site.destroy_all
end
before(:each) do
::Heroku::Client.any_instance.stubs(:post).returns(true)
::Heroku::Client.any_instance.stubs(:delete).returns(true)