witten
/
luminotes
Archived
1
0
Fork 0

Began redesign of upgrade/pricing page.

This commit is contained in:
Dan Helfman 2008-03-22 04:01:21 +00:00
parent 2cae1faf2d
commit e9d2ea28d1
28 changed files with 440 additions and 177 deletions

3
NEWS
View File

@ -1,3 +1,6 @@
1.2.18: March ??, 2008
* Newly redesigned upgrade/pricing/signup page.
1.2.17: March 18, 2008
* Internet Explorer expects quoted download filenames, while Firefox
doesn't. So I took that into account by quoting conditionally based on the

View File

@ -13,8 +13,8 @@ from model.User import User
from view.Main_page import Main_page
from view.Front_page import Front_page
from view.Tour_page import Tour_page
from view.Upgrade_page import Upgrade_page
from view.Notebook_rss import Notebook_rss
from view.Upgrade_note import Upgrade_note
from view.Json import Json
from view.Error_page import Error_page
from view.Not_found_page import Not_found_page
@ -79,6 +79,8 @@ class Root( object ):
if note_title in ( u"sign_up", u"login" ) and https_url and cherrypy.request.remote_addr != https_proxy_ip:
if invite_id:
return dict( redirect = u"%s/%s?invite_id=%s" % ( https_url, note_title, invite_id ) )
if after_login:
return dict( redirect = u"%s/%s?after_login=%s" % ( https_url, note_title, after_login ) )
else:
return dict( redirect = u"%s/%s" % ( https_url, note_title ) )
@ -270,48 +272,35 @@ class Root( object ):
return result
@expose( view = Main_page )
@expose( view = Upgrade_page )
@strongly_expire
@end_transaction
@grab_user_id
@validate(
user_id = Valid_id( none_okay = True ),
)
def upgrade( self, user_id = None ):
def pricing( self, user_id = None ):
"""
Provide the information necessary to display the Luminotes upgrade page.
Provide the information necessary to display the Luminotes pricing page.
"""
anonymous = self.__database.select_one( User, User.sql_load_by_username( u"anonymous" ) )
if anonymous:
main_notebook = self.__database.select_one( Notebook, anonymous.sql_load_notebooks( undeleted_only = True ) )
else:
main_notebook = None
if user_id:
user = self.__database.load( User, user_id )
else:
user = None
https_url = self.__settings[ u"global" ].get( u"luminotes.https_url" )
result = self.__users.current( user_id )
result[ "notebook" ] = main_notebook
result[ "startup_notes" ] = self.__database.select_many( Note, main_notebook.sql_load_startup_notes() )
result[ "total_notes_count" ] = self.__database.select_one( Note, main_notebook.sql_count_notes() )
result[ "note_read_write" ] = False
result[ "notes" ] = [ Note.create(
object_id = u"upgrade",
contents = unicode( Upgrade_note(
self.__settings[ u"global" ].get( u"luminotes.rate_plans", [] ),
self.__settings[ u"global" ].get( u"luminotes.unsubscribe_button" ),
https_url,
user,
) ),
notebook_id = main_notebook.object_id,
) ]
result[ "invites" ] = []
parents = [ notebook for notebook in result[ u"notebooks" ] if notebook.trash_id and not notebook.deleted ]
if len( parents ) > 0:
result[ "first_notebook" ] = parents[ 0 ]
else:
result[ "first_notebook" ] = None
result[ "rate_plans" ] = self.__settings[ u"global" ].get( u"luminotes.rate_plans", [] )
result[ "unsubscribe_button" ] = self.__settings[ u"global" ].get( u"luminotes.unsubscribe_button" )
return result
@expose()
def upgrade( self ):
return dict(
redirect = u"/pricing",
)
# TODO: move this method to controller.Notebooks, and maybe give it a more sensible name
@expose( view = Json )
@end_transaction

View File

@ -326,8 +326,8 @@ class Test_root( Test_controller ):
assert u"error" not in result
assert result[ u"notebook" ].object_id == self.privacy_notebook.object_id
def test_upgrade( self ):
result = self.http_get( "/upgrade" )
def test_pricing( self ):
result = self.http_get( "/pricing" )
assert result[ u"user" ].username == u"anonymous"
assert len( result[ u"notebooks" ] ) == 4
@ -341,27 +341,14 @@ class Test_root( Test_controller ):
assert rate_plan[ u"name" ] == u"super"
assert rate_plan[ u"storage_quota_bytes" ] == 1337 * 10
assert result[ u"notebook" ].object_id == self.anon_notebook.object_id
assert len( result[ u"startup_notes" ] ) == 0
assert result[ u"note_read_write" ] is False
assert result[ u"first_notebook" ] == None
assert result[ u"rate_plans" ] == self.settings[ u"global" ].get( u"luminotes.rate_plans", [] )
assert result[ u"unsubscribe_button" ] == self.settings[ u"global" ].get( u"luminotes.unsubscribe_button" )
assert result[ u"notes" ]
assert len( result[ u"notes" ] ) == 1
assert result[ u"notes" ][ 0 ].title == u"upgrade your wiki"
assert result[ u"notes" ][ 0 ].notebook_id == self.anon_notebook.object_id
contents = result[ u"notes" ][ 0 ].contents
assert u"upgrade" in contents
assert u"Super" in contents
assert u"Extra super" in contents
# since the user is not logged in, no subscription buttons should be shown
assert u"button" not in contents
def test_upgrade_after_login( self ):
def test_pricing_after_login( self ):
self.login()
result = self.http_get( "/upgrade", session_id = self.session_id )
result = self.http_get( "/pricing", session_id = self.session_id )
assert result[ u"user" ].username == self.username
assert len( result[ u"notebooks" ] ) == 5
@ -375,22 +362,14 @@ class Test_root( Test_controller ):
assert rate_plan[ u"name" ] == u"super"
assert rate_plan[ u"storage_quota_bytes" ] == 1337 * 10
assert result[ u"notebook" ].object_id == self.anon_notebook.object_id
assert len( result[ u"startup_notes" ] ) == 0
assert result[ u"note_read_write" ] is False
assert result[ u"first_notebook" ].object_id == self.notebook.object_id
assert result[ u"rate_plans" ] == self.settings[ u"global" ].get( u"luminotes.rate_plans", [] )
assert result[ u"unsubscribe_button" ] == self.settings[ u"global" ].get( u"luminotes.unsubscribe_button" )
assert result[ u"notes" ]
assert len( result[ u"notes" ] ) == 1
assert result[ u"notes" ][ 0 ].title == u"upgrade your wiki"
assert result[ u"notes" ][ 0 ].notebook_id == self.anon_notebook.object_id
def upgrade( self ):
result = self.http_get( "/upgrade" )
contents = result[ u"notes" ][ 0 ].contents
assert u"upgrade" in contents
assert u"Super" in contents
assert u"Extra super" in contents
# since the user is logged in, subscription buttons should be shown
assert u"button" in contents
assert result[ u"redirect" ] == u"/pricing"
def test_next_id( self ):
result = self.http_get( "/next_id" )

View File

@ -89,81 +89,6 @@ ol li {
padding-right: 1em;
}
#upgrade_table_area {
text-align: center;
}
#upgrade_login_text {
font-weight: bold;
text-align: center;
}
#upgrade_table {
border-collapse: collapse;
border: 1px solid #999999;
margin-left: auto;
margin-right: auto;
}
#upgrade_table th {
padding: 0.5em;
}
#upgrade_table td {
text-align: center;
background-color: #fafafa;
padding: 0.5em;
}
#upgrade_table .plan_name {
width: 16%;
text-align: center;
background-color: #d0e0f0;
}
#upgrade_table .feature_name {
width: 36%;
text-align: left;
background-color: #fafafa;
}
#upgrade_table_small {
border-collapse: collapse;
border: 1px solid #999999;
margin-left: auto;
margin-right: auto;
}
#upgrade_table_small th {
padding: 0.5em;
}
#upgrade_table_small td {
text-align: center;
background-color: #fafafa;
padding: 0.5em;
}
#upgrade_table_small .plan_name {
width: 33%;
text-align: center;
background-color: #d0e0f0;
}
.price_text {
color: #ff6600;
}
.month_text {
padding-top: 0.5em;
font-size: 75%;
}
.subscribe_form {
margin-top: 0.5em;
margin-bottom: 0;
}
.thumbnail_left {
float: left;
margin: 0.5em;

View File

@ -105,10 +105,6 @@
margin-right: 20px;
}
.hook_bullet_list {
list-style-type: none;
}
.hook_action_area {
background-color: #ffff99;
font-weight: bold;
@ -178,6 +174,10 @@
padding-bottom: 0.5em;
}
.compact_list {
line-height: 100%;
}
.quotes_area {
float: right;
width: 400px;
@ -207,10 +207,12 @@
}
.footer {
clear: both;
background-color: #b0d0ff;
height: 2em;
margin-left: 0;
margin-right: 0;
margin-top: 1em;
border-top: 1px solid #999999;
}
@ -247,3 +249,127 @@
.tour_screenshot_wrapper {
padding: 1em;
}
.upgrade_subtitle {
text-align: center;
font-weight: bold;
padding-bottom: 0.5em;
}
.upgrade_text {
text-align: left;
}
.upgrade_area {
text-align: center;
padding-top: 1em;
padding-bottom: 1em;
background-color: #ffffff;
border-bottom: 1px solid #cccccc;
margin: 0 auto;
margin-bottom: 1em;
}
.upgrade_table_area {
text-align: center;
}
#upgrade_table {
border-collapse: collapse;
border: 1px solid #999999;
margin-left: auto;
margin-right: auto;
margin-bottom: 1em;
}
#upgrade_table th {
padding: 0.5em;
}
#upgrade_table td {
text-align: center;
background-color: #fafafa;
padding: 0.5em;
}
#upgrade_table .plan_name {
width: 16%;
text-align: center;
background-color: #d0e0f0;
}
#upgrade_table .feature_name {
width: 36%;
text-align: left;
background-color: #fafafa;
}
#upgrade_table_small {
clear: both;
border-collapse: collapse;
border: 1px solid #999999;
margin-left: auto;
margin-right: auto;
}
#upgrade_table_small th {
padding: 0.5em;
}
#upgrade_table_small td {
text-align: center;
background-color: #fafafa;
padding: 0.5em;
}
#upgrade_table_small .plan_name {
width: 33%;
text-align: center;
background-color: #d0e0f0;
}
.price_text {
color: #ff6600;
}
.month_text {
padding-top: 0.5em;
font-size: 75%;
}
.subscribe_form {
margin-top: 0.5em;
margin-bottom: 0;
}
.sign_up_button_area {
margin-top: 0.5em;
}
.upgrade_left_area {
width: 400px;
margin-bottom: 1em;
}
.upgrade_right_area {
float: right;
width: 400px;
margin-left: 20px;
margin-bottom: 1em;
}
.thumbnail_left {
float: left;
margin: 0.5em;
margin-right: 1em;
margin-bottom: 0.5em;
border: 1px solid #999999;
}
.thumbnail_right {
float: right;
margin: 0.5em;
margin-left: 1em;
margin-bottom: 0.5em;
border: 1px solid #999999;
}

View File

@ -1,20 +1,15 @@
<h3>sign up</h3>
<p>
To get started with your own personal wiki, all you need to do is sign up for
an account. <b>There's nothing to download or install.</b>
<b>There's nothing to download or install.</b>
</p>
<p>
If you haven't seen it already, <a href="/users/demo" target="_top">try the
demo</a> first! The Luminotes demo doesn't require any sort of sign up.
If you're not ready to sign up
yet, <a href="/users/demo" target="_top">try the demo</a> first!
</p>
<p>
<b>Providing your email address is completely optional.</b> I only ask for it
in case you ever need your password reset. Your email address will absolutely
not be given out or used for spam.
</p>
<form id="signup_form">
<p>
@ -28,12 +23,12 @@ not be given out or used for spam.
</p>
<p>
<b>password (again)</b><br />
<b>password</b> (again)<br />
<input type="password" name="password_repeat" id="password_repeat" class="text_field" size="30" maxlength="30" />
</p>
<p>
<b>email address (optional)</b><br />
<b>email address</b> (optional and never shared)<br />
<input type="text" name="email_address" id="email_address" class="text_field" size="30" maxlength="60" />
</p>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

BIN
static/images/sign_up.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
static/images/sign_up.xcf Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

BIN
static/images/upgrade.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
static/images/upgrade.xcf Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

View File

@ -1,5 +1,5 @@
from Product_page import Product_page
from Tags import Div, Img, A, P, Table, Tr, Td, Li, Span, I, Br
from Tags import Div, Img, A, P, Table, Tr, Td, Li, Span, I, Br, Ul, Li
class Front_page( Product_page ):
@ -49,7 +49,7 @@ class Front_page( Product_page ):
A( u"Take a tour", href = u"/tour", class_ = u"hook_action" ), u", ",
A( u"Try the demo", href = u"/users/demo", class_ = u"hook_action" ), u", ",
Span( u" or ", class_ = u"hook_action_or" ),
A( u"Sign up", href = u"/sign_up", class_ = u"hook_action" ),
A( u"Sign up", href = u"/pricing", class_ = u"hook_action" ),
class_ = u"hook_action_area",
separator = u"",
),
@ -70,6 +70,27 @@ class Front_page( Product_page ):
),
),
Div(
Div(
u'"',
Span(
u"As soon as I saw Luminotes I knew it was what I and my students needed.",
class_ = u"quote_title",
separator = u"",
),
u"""
Clear, easy to use and beautifully simple.
""",
class_ = u"quote_text",
separator = u"",
),
Div(
u"-Jonathan Lecun, Director, ", A( u"UK Teachers Online", href = u"http://www.ukteachersonline.co.uk/" ),
class_ = u"quote_signature"
),
class_ = u"quote",
),
Div(
Div(
u'"',
@ -94,6 +115,29 @@ class Front_page( Product_page ):
class_ = u"quote",
),
Div(
Div(
u'"',
Span(
u"I'm a wiki addict, so I've tried most of them, desktop and web-based.",
class_ = u"quote_title",
separator = u"",
),
u"""
What I like about your excellent product is the modeless editing (no edit
and save buttons). This makes Luminotes the fastest web-based wiki I have
used.
""",
class_ = u"quote_text",
separator = u"",
),
Div(
u"-Scott Tiner",
class_ = u"quote_signature"
),
class_ = u"quote",
),
Div(
Div(
u'"',
@ -194,6 +238,17 @@ class Front_page( Product_page ):
),
class_ = u"thumbnail_area",
),
P(
u"What can you do with Luminotes?",
),
Ul(
Li( u"Plan a story" ),
Li( u"Collect recipes" ),
Li( u"Record your ideas" ),
Li( u"Keep track of your tasks" ),
Li( u"Take notes" ),
class_ = u"compact_list",
),
P(
u"""
Luminotes is open source / free software and licensed under the terms of the
@ -202,24 +257,23 @@ class Front_page( Product_page ):
),
class_ = u"what_is_luminotes_text",
),
Div(
P(
Span( u"Sound interesting?", class_ = u"hook_action_question" ), Br(),
A( u"Take a tour", href = u"/tour", class_ = u"hook_action" ), u", ",
A( u"Try the demo", href = u"/users/demo", class_ = u"hook_action" ), u", ",
Span( u" or ", class_ = u"hook_action_or" ),
A( u"Sign up", href = u"/pricing", class_ = u"hook_action" ),
class_ = u"hook_action_area",
separator = u"",
),
),
class_ = u"what_is_luminotes_area",
),
class_ = u"wide_center_area",
),
Div(
P(
Span( u"Sound interesting?", class_ = u"hook_action_question" ), Br(),
A( u"Take a tour", href = u"/tour", class_ = u"hook_action" ), u", ",
A( u"Try the demo", href = u"/users/demo", class_ = u"hook_action" ), u", ",
Span( u" or ", class_ = u"hook_action_or" ),
A( u"Sign up", href = u"/sign_up", class_ = u"hook_action" ),
class_ = u"hook_action_area",
separator = u"",
),
class_ = u"center_area",
),
P(
Span( id = u"new_note_button_preload" ),
Span( id = u"link_button_preload" ),

View File

@ -18,7 +18,8 @@ class Product_page( Page ):
Div(
( note_title == u"home" ) and title_image or A( title_image, href = u"/" ),
( login_url and user.username == u"anonymous" ) and Div(
A( u"sign up", href = u"/sign_up", class_ = u"bold_link" ), u" | ",
( note_title == u"pricing" ) and Span( u"pricing &amp sign up", class_ = u"bold_link" ) or \
A( u"pricing &amp; sign up", href = u"/pricing", class_ = u"bold_link" ), u" | ",
A(
u"login",
href = login_url,
@ -39,16 +40,18 @@ class Product_page( Page ):
user.username and Span(
A(
u"upgrade",
href = u"/upgrade",
href = u"/pricing",
title = u"Upgrade your Luminotes account.",
class_ = u"bold_link",
),
" | ",
) or Span(
( note_title == u"pricing" ) and Span( u"pricing &amp sign up", class_ = u"bold_link" ) or \
A(
u"sign up",
href = u"/sign_up",
u"pricing &amp; sign up",
href = u"/pricing",
title = u"Sign up for a real Luminotes account.",
class_ = u"bold_link",
),
" | ",
) or None,
@ -64,7 +67,6 @@ class Product_page( Page ):
( note_title == u"home" ) and Span( u"home", class_ = u"bold_link" ) or A( u"home", href = u"/" ), u" | ",
( note_title == u"tour" ) and Span( u"tour", class_ = u"bold_link" ) or A( u"tour", href = u"/tour" ), u" | ",
( note_title == u"demo" ) and Span( u"demo", class_ = u"bold_link" ) or A( u"demo", href = u"/users/demo" ), u" | ",
( note_title == u"upgrade" ) and Span( u"upgrade", class_ = u"bold_link" ) or A( u"pricing", href = u"/upgrade" ), u" | ",
( note_title == u"faq" ) and Span( u"faq", class_ = u"bold_link" ) or A( u"faq", href = u"/faq" ), u" | ",
( note_title == u"guide" ) and Span( u"guide", class_ = u"bold_link" ) or A( u"help", href = u"/guide" ), u" | ",
( note_title == u"contact" ) and Span( u"contact", class_ = u"bold_link" ) or A( u"contact", href = u"/contact_info" ), u" | ",

View File

@ -25,7 +25,7 @@ class Thanks_error_note( Span ):
u"""
Note: You can check the current status of your account by refreshing the
""",
A( u"upgrade", href = u"/upgrade", target = "_top" ),
A( u"upgrade", href = u"/pricing", target = "_top" ),
u"""
page while logged in.
"""

View File

@ -74,7 +74,7 @@ class Tour_page( Product_page ):
Span( u"Like what you've seen so far?", class_ = u"hook_action_question" ), Br(),
A( u"Try the demo", href = u"/users/demo", class_ = u"hook_action" ),
Span( u" or ", class_ = u"hook_action_or" ),
A( u"Sign up", href = u"/sign_up", class_ = u"hook_action" ),
A( u"Sign up", href = u"/pricing", class_ = u"hook_action" ),
class_ = u"hook_action_area",
separator = u"",
),

190
view/Upgrade_page.py Normal file
View File

@ -0,0 +1,190 @@
from Product_page import Product_page
from Tags import Div, Img, A, P, Table, Th, Tr, Td, Li, Span, I, Br, Ul, Li
class Upgrade_page( Product_page ):
def __init__( self, user, notebooks, first_notebook, login_url, logout_url, rate_plan, rate_plans, unsubscribe_button ):
MEGABYTE = 1024 * 1024
Product_page.__init__(
self,
user,
first_notebook,
login_url,
logout_url,
u"pricing", # note title
Div(
Div(
user and user.username not in ( None, u"anonymous" ) and Div(
Img(
src = u"/static/images/upgrade.png",
width = u"152", height = u"51",
alt = u"Upgrade",
),
) or Div(
Img(
src = u"/static/images/sign_up.png",
width = u"138", height = u"51",
alt = u"Sign Up",
),
),
P(
"""
Upgrade, downgrade, or cancel anytime. 60-day money-back guarantee.
""",
class_ = u"upgrade_subtitle",
),
P(
Table(
self.fee_row( rate_plans, user ),
Tr(
Td( u"Included storage space", class_ = u"feature_name" ),
[ Td(
plan[ u"storage_quota_bytes" ] // MEGABYTE, " MB",
) for plan in rate_plans ],
),
Tr(
Td( u"Unlimited wiki notebooks", class_ = u"feature_name" ),
[ Td(
Img( src = u"/static/images/check.png", width = u"20", height = u"17" ),
) for plan in rate_plans ],
),
Tr(
Td( u"Friendly email support", class_ = u"feature_name" ),
[ Td(
Img( src = u"/static/images/check.png", width = u"20", height = u"17" ),
) for plan in rate_plans ],
),
Tr(
Td( u"Invite people to view your wiki", class_ = u"feature_name" ),
[ Td(
Img( src = u"/static/images/check.png", width = u"20", height = u"17" ),
) for plan in rate_plans ],
),
Tr(
Td( u"Invite people to edit your wiki", class_ = u"feature_name" ),
[ Td(
plan[ u"notebook_collaboration" ] and
Img( src = u"/static/images/check.png", width = u"20", height = u"17" ) or u"&nbsp",
) for plan in rate_plans ],
),
Tr(
Td( u"Wiki access control", class_ = u"feature_name" ),
[ Td(
plan[ u"notebook_collaboration" ] and
Img( src = u"/static/images/check.png", width = u"20", height = u"17" ) or u"&nbsp",
) for plan in rate_plans ],
),
border = u"1",
id = u"upgrade_table",
),
class_ = u"upgrade_table_area",
),
user and user.username and P(
u"You're currently subscribed to Luminotes %s." %
rate_plans[ user.rate_plan ][ u"name" ].capitalize(),
( user.rate_plan > 0 ) and unsubscribe_button or None,
) or None,
class_ = u"upgrade_area",
),
Div(
Div(
Img(
src = u"/static/images/more_room_to_stretch_out.png",
width = u"280", height = u"29",
alt = u"More room to stretch out",
),
Ul(
Li( u"More room for your wiki notes." ),
Li( u"More room for your documents and files." ),
class_ = u"upgrade_text",
),
Img(
src = u"/static/images/zero_hassle.png",
width = u"122", height = u"29",
alt = u"Zero hassle",
),
Ul(
Li( u"Cancel online anytime without losing access to your wiki." ),
Li( u"60-day money-back guarantee. No questions asked." ),
Li( u"No lock-in: Download your entire wiki anytime." ),
class_ = u"upgrade_text",
),
class_= u"upgrade_right_area",
),
Div(
Img(
src = u"/static/images/more_collaboration.png",
width = u"204", height = u"29",
alt = u"More collaboration",
),
P(
Ul(
Li( u"Invite specific people to collaborate on your wiki." ),
Li( u"Decide who can edit and who can only view." ),
Li( u"Invite as many people as you want. They only need free Luminotes accounts." ),
Li( u"Revoke access with a single click." ),
Li( u"Share only the notebooks you want to share. Keep the others private." ),
class_ = u"upgrade_text",
),
),
class_= u"upgrade_left_area",
),
P(
Table(
self.fee_row( rate_plans, user, include_blank = False ),
Tr(
[ Td(
plan[ u"storage_quota_bytes" ] // MEGABYTE, " MB",
) for plan in rate_plans ],
),
border = u"1",
id = u"upgrade_table_small",
),
class_= u"upgrade_table_area",
),
Div(
P(
Span( u"Have a question before you sign up?", class_ = u"hook_action_question" ), Br(),
A( u"Contact support", href = u"/contact_info", class_ = u"hook_action" ),
class_ = u"hook_action_area",
separator = u"",
),
class_ = u"center_area",
),
class_ = u"wide_center_area",
),
),
)
def fee_row( self, rate_plans, user, include_blank = True ):
return Tr(
include_blank and Th( u"&nbsp;" ) or None,
[ Th(
plan[ u"name" ].capitalize(),
plan[ u"fee" ] and Div(
Span(
u"$%s" % plan[ u"fee" ],
Span( u"/month", class_ = u"month_text" ),
class_ = u"price_text",
separator = u"",
),
user and user.username and user.rate_plan != index and plan.get( u"button" ).strip() and plan.get( u"button" ) % user.object_id,
) or None,
( not user or user.username in ( u"anonymous", None ) ) and Div(
A(
Img( src = u"/static/images/sign_up_button.png", width = "76", height = "23" ),
href = u"/sign_up?plan=%s" % index,
),
class_ = u"sign_up_button_area",
) or None,
class_ = u"plan_name",
) for ( index, plan ) in enumerate( rate_plans ) ],
)

View File

@ -17,14 +17,14 @@ class User_area( Div ):
user.username and Span(
A(
u"upgrade",
href = u"/upgrade",
href = u"/pricing",
title = u"Upgrade your Luminotes account.",
),
" | ",
) or Span(
A(
u"sign up",
href = u"/sign_up",
href = u"/pricing",
title = u"Sign up for a real Luminotes account.",
),
" | ",