added blogger, updated style and blogs

This commit is contained in:
Rushabh Mehta 2013-03-07 18:51:10 +05:30
parent 18c11214fa
commit 676a568f5a
16 changed files with 341 additions and 78 deletions

View File

@ -1,9 +1,4 @@
div.outer {
-moz-box-shadow: 0px 0px 3px rgba(0,0,0,0.9);
-webkit-box-shadow: 0px 0px 3px rgba(0,0,0,0.9);
box-shadow: 0px 0px 3px rgba(0,0,0,0.9);
background-color: #fff;
border-radius: 5px;
padding: 30px;
margin: 30px -30px 10px -30px;
min-height: 400px;
@ -24,6 +19,8 @@ footer {
border: 0px;
border-bottom: 1px solid #ddd;
border-radius: 0px;
padding-right: 30px;
padding-left: 30px;
}
p, li {
@ -98,6 +95,18 @@ p, li {
width: 30px;
}
.avatar-medium {
margin-right: 5px;
width: 48px;
height: 48px;
border-radius: 48px;
-moz-border-radius: 48px;
-webkit-border-radius: 48px;
}
.avatar-medium img {
width: 48px;
}
.avatar-large {
margin-right: 10px;
width: 72px;

View File

@ -27,6 +27,9 @@ class DocType:
from website.utils import page_name
self.doc.name = page_name(self.doc.title)
def validate(self):
self.doc.blog_intro = self.doc.blog_intro[:140]
def on_update(self):
from website.utils import update_page_name
update_page_name(self.doc, self.doc.title)
@ -66,6 +69,10 @@ class DocType:
self.doc.full_name = get_fullname(self.doc.owner)
self.doc.updated = global_date_format(self.doc.creation)
self.doc.content_html = self.doc.content
if self.doc.blogger:
self.doc.blogger_info = webnotes.doc("blogger", self.doc.blogger).fields
if self.doc.blogger_info.avatar and not "/" in self.doc.blogger_info.avatar:
self.doc.blogger_info.avatar = "files/" + self.doc.blogger_info.avatar
comment_list = webnotes.conn.sql("""\
select comment, comment_by_fullname, creation

View File

@ -2,7 +2,7 @@
{
"creation": "2013-01-25 11:35:09",
"docstatus": 0,
"modified": "2013-02-21 16:54:04",
"modified": "2013-03-07 16:32:13",
"modified_by": "Administrator",
"owner": "Administrator"
},
@ -50,18 +50,37 @@
"label": "Published"
},
{
"description": "Description for listing page, in plain text, only a couple of lines.",
"doctype": "DocField",
"fieldname": "column_break_3",
"fieldtype": "Column Break"
},
{
"doctype": "DocField",
"fieldname": "blogger",
"fieldtype": "Link",
"label": "Blogger",
"options": "Blogger",
"reqd": 1
},
{
"doctype": "DocField",
"fieldname": "section_break_5",
"fieldtype": "Section Break"
},
{
"description": "Description for listing page, in plain text, only a couple of lines. (max 140 characters)",
"doctype": "DocField",
"fieldname": "blog_intro",
"fieldtype": "Small Text",
"label": "Blog Intro"
"label": "Blog Intro",
"reqd": 1
},
{
"doctype": "DocField",
"fieldname": "content",
"fieldtype": "Text Editor",
"label": "Content",
"reqd": 0
"reqd": 1
},
{
"doctype": "DocField",

View File

View File

@ -0,0 +1,18 @@
# For license information, please see license.txt
from __future__ import unicode_literals
import webnotes
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
def on_update(self):
"if profile is set, then update all older blogs"
if self.doc.profile:
for blog in webnotes.conn.sql_list("""select name from tabBlog where owner=%s
and ifnull(blogger,'')=''""", self.doc.profile):
b = webnotes.bean("Blog", blog)
b.blogger = self.doc.name
b.save()

View File

@ -0,0 +1,95 @@
[
{
"creation": "2013-03-07 16:28:19",
"docstatus": 0,
"modified": "2013-03-07 16:33:37",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"allow_attach": 1,
"autoname": "field:short_name",
"description": "Profile of a Blogger",
"doctype": "DocType",
"document_type": "Master",
"max_attachments": 1,
"module": "Website",
"name": "__common__"
},
{
"doctype": "DocField",
"name": "__common__",
"parent": "Blogger",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0
},
{
"doctype": "DocPerm",
"name": "__common__",
"parent": "Blogger",
"parentfield": "permissions",
"parenttype": "DocType",
"permlevel": 0,
"read": 1,
"write": 1
},
{
"doctype": "DocType",
"name": "Blogger"
},
{
"description": "Will be used in url (usually first name).",
"doctype": "DocField",
"fieldname": "short_name",
"fieldtype": "Data",
"label": "Short Name",
"reqd": 1
},
{
"doctype": "DocField",
"fieldname": "full_name",
"fieldtype": "Data",
"label": "Full Name",
"reqd": 1
},
{
"doctype": "DocField",
"fieldname": "profile",
"fieldtype": "Link",
"label": "Profile",
"options": "Profile"
},
{
"doctype": "DocField",
"fieldname": "bio",
"fieldtype": "Small Text",
"label": "Bio"
},
{
"doctype": "DocField",
"fieldname": "avatar",
"fieldtype": "Select",
"label": "Avatar",
"options": "attach_files:"
},
{
"doctype": "DocField",
"fieldname": "file_list",
"fieldtype": "Text",
"hidden": 1,
"label": "File List",
"no_copy": 1,
"print_hide": 1
},
{
"create": 1,
"doctype": "DocPerm",
"role": "Website Manager"
},
{
"doctype": "DocPerm",
"match": "owner:profile",
"role": "Blogger"
}
]

View File

@ -1,3 +1,7 @@
{% if doc.at_import %}
{{ doc.at_import }}
{% endif %}
body {
{% if doc.background_image %}
background: url("../files/{{ doc.background_image }}") repeat;
@ -7,8 +11,8 @@ body {
{% else %}
background-color: #edede7;
{% endif %}
{% if doc.font %}
font-family: '{{ doc.font }}', Verdana, Sans !important;
{% if doc.font or doc.google_web_font_for_text %}
font-family: '{{ doc.google_web_font_for_text or doc.font }}', Verdana, Sans !important;
{% endif %}
{% if doc.font_size %}
font-size: {{ doc.font_size }} !important;
@ -21,14 +25,32 @@ body {
}
{% endif %}
{% if doc.heading_font %}
div.outer {
background-color: #{{ doc.page_background or "fff" }};
}
{% if doc.google_web_font_for_heading or doc.heading_font %}
h1, h2, h3, h4, h5 {
font-family: '{{ doc.heading_font}}', Arial, 'Helvetica Neue' !important;
font-family: '{{ doc.google_web_font_for_heading or doc.heading_font }}', Arial, 'Helvetica Neue' !important;
}
{% endif %}
/* Bootstrap Navbar */
{% if doc.page_border %}
/* Page Border*/
div.outer {
-moz-box-shadow: 0px 0px 3px rgba(0,0,0,0.9);
-webkit-box-shadow: 0px 0px 3px rgba(0,0,0,0.9);
box-shadow: 0px 0px 3px rgba(0,0,0,0.9);
border-radius: 5px;
}
{% else %}
div.web-footer {
border-top: 1px solid #eee;
padding-top: 10px;
}
{% endif %}
/* Bootstrap Navbar */
.navbar-inverse .navbar-inner {
background-color: #{{ doc.top_bar_background or "444"}};
background-repeat: repeat-x;

View File

@ -18,6 +18,7 @@
cur_frm.cscript.onload_post_render = function() {
wn.require('lib/public/js/lib/jscolor/jscolor.js');
cur_frm.fields_dict.background_color.input.className = 'color';
cur_frm.fields_dict.page_background.input.className = 'color';
cur_frm.fields_dict.top_bar_background.input.className = 'color';
jscolor.bind();
}

View File

@ -29,10 +29,7 @@ class DocType:
'custom_template.css'), 'r') as f:
temp = Template(f.read())
if not self.doc.font_size:
self.doc.font_size = '13px'
self.doc.small_font_size = str(int(self.doc.font_size[:-2])-2) + 'px'
self.prepare()
self.doc.custom_css = temp.render(doc = self.doc)
if self.doc.add_css:
@ -41,7 +38,30 @@ class DocType:
from webnotes.sessions import clear_cache
clear_cache('Guest')
del self.doc.fields['small_font_size']
for f in ["small_font_size", "at_import"]:
if f in self.doc.fields:
del self.doc.fields[f]
def prepare(self):
if not self.doc.font_size:
self.doc.font_size = '13px'
self.doc.small_font_size = str(int(self.doc.font_size[:-2])-2) + 'px'
self.doc.page_border = int(self.doc.page_border)
fonts = []
if self.doc.google_web_font_for_heading:
fonts.append(self.doc.google_web_font_for_heading)
if self.doc.google_web_font_for_text:
fonts.append(self.doc.google_web_font_for_text)
fonts = list(set(fonts))
self.doc.at_import = ""
for f in fonts:
self.doc.at_import += "\n@import url(http://fonts.googleapis.com/css?family=%s);" % f.replace(" ", "+")
def on_update(self):
"""rebuild pages"""

View File

@ -2,7 +2,7 @@
{
"creation": "2013-01-25 11:35:10",
"docstatus": 0,
"modified": "2013-03-07 14:46:51",
"modified": "2013-03-07 16:06:22",
"modified_by": "Administrator",
"owner": "Administrator"
},
@ -38,6 +38,12 @@
"doctype": "DocType",
"name": "Style Settings"
},
{
"doctype": "DocField",
"fieldname": "color",
"fieldtype": "Section Break",
"label": "Color"
},
{
"description": "If image is selected, color will be ignored (attach first)",
"doctype": "DocField",
@ -53,6 +59,25 @@
"fieldtype": "Data",
"label": "Background Color"
},
{
"doctype": "DocField",
"fieldname": "page_background",
"fieldtype": "Data",
"label": "Page Background"
},
{
"doctype": "DocField",
"fieldname": "page_border",
"fieldtype": "Check",
"label": "Page Border"
},
{
"doctype": "DocField",
"fieldname": "cb0",
"fieldtype": "Column Break",
"print_width": "50%",
"width": "50%"
},
{
"doctype": "DocField",
"fieldname": "top_bar_background",
@ -69,31 +94,49 @@
},
{
"doctype": "DocField",
"fieldname": "cb0",
"fieldtype": "Column Break",
"print_width": "50%",
"width": "50%"
"fieldname": "fonts",
"fieldtype": "Section Break",
"label": "Fonts"
},
{
"doctype": "DocField",
"fieldname": "heading_font",
"fieldtype": "Select",
"label": "Font (Heading)",
"options": "\nHelvetica Neue\nLucida Grande\nVerdana\nArial\nGeorgia\nTahoma\nLato\nOpen Sans"
},
{
"doctype": "DocField",
"fieldname": "font",
"fieldtype": "Select",
"label": "Font",
"label": "Font (Text)",
"options": "\nHelvetica Neue\nLucida Grande\nVerdana\nArial\nGeorgia\nTahoma"
},
{
"doctype": "DocField",
"fieldname": "font_size",
"fieldtype": "Select",
"label": "Font Size",
"label": "Font Size (Text)",
"options": "\n12px\n13px\n14px\n15px\n16px"
},
{
"doctype": "DocField",
"fieldname": "heading_font",
"fieldtype": "Select",
"label": "Heading Font",
"options": "\nHelvetica Neue\nLucida Grande\nVerdana\nArial\nGeorgia\nTahoma\nLato\nOpen Sans"
"fieldname": "column_break_13",
"fieldtype": "Column Break"
},
{
"description": "Add the name of Google Web Font e.g. \"Open Sans\"",
"doctype": "DocField",
"fieldname": "google_web_font_for_heading",
"fieldtype": "Data",
"label": "Google Web Font (Heading)"
},
{
"description": "Add the name of Google Web Font e.g. \"Open Sans\"",
"doctype": "DocField",
"fieldname": "google_web_font_for_text",
"fieldtype": "Data",
"label": "Google Web Font (Text)"
},
{
"doctype": "DocField",

View File

@ -6,39 +6,39 @@ import webnotes
import website.utils
@webnotes.whitelist(allow_guest=True)
def get_blog_list(args=None):
"""
args = {
'start': 0,
}
"""
def get_blog_list(start=0, by=None):
import webnotes
if not args: args = webnotes.form_dict
condition = ""
if by:
condition = " and t1.blogger='%s'" % by.replace("'", "\'")
query = """\
select
name, page_name, content, owner, creation as creation,
title, (select count(name) from `tabComment` where
comment_doctype='Blog' and comment_docname=`tabBlog`.name) as comments
from `tabBlog`
where ifnull(published,0)=1
t1.title, t1.name, t1.page_name, t1.creation as creation,
ifnull(t1.blog_intro, t1.content) as content,
t2.full_name, t2.avatar, t1.blogger,
(select count(name) from `tabComment` where
comment_doctype='Blog' and comment_docname=t1.name) as comments
from `tabBlog` t1, `tabBlogger` t2
where ifnull(t1.published,0)=1
and t1.blogger = t2.name
%(condition)s
order by creation desc, name asc
limit %s, 5""" % args.start
limit %(start)s, 5""" % {"start": start, "condition": condition}
result = webnotes.conn.sql(query, args, as_dict=1)
result = webnotes.conn.sql(query, as_dict=1)
# strip html tags from content
import webnotes.utils
for res in result:
from webnotes.utils import global_date_format, get_fullname
res['full_name'] = get_fullname(res['owner'])
res['published'] = global_date_format(res['creation'])
if not res['content']:
res['content'] = website.utils.get_html(res['page_name'])
res['content'] = split_blog_content(res['content'])
res['content'] = res['content'][:140]
if res.avatar and not "/" in res.avatar:
res.avatar = "files/" + res.avatar
return result
@webnotes.whitelist(allow_guest=True)
@ -115,10 +115,4 @@ def get_blog_content(blog_page_name):
import webnotes.utils
content = webnotes.utils.escape_html(content)
return content
def split_blog_content(content):
content = content.split("<!-- begin blog content -->")
content = len(content) > 1 and content[1] or content[0]
content = content.split("<!-- end blog content -->")
content = content[0]
return content

View File

@ -21,6 +21,11 @@ wn.module_page["Website"] = [
description: wn._("Embed image slideshows in website pages."),
doctype:"Website Slideshow"
},
{
label: wn._("Blogger"),
description: wn._("Profile of a blog writer."),
doctype:"Blogger"
},
]
},
{

View File

@ -13,17 +13,33 @@
<h2>{{ title }}</h2>
<!-- begin blog content -->
<div class="help">By {{ full_name }} on {{ updated }}</div>
<div class="help" style="color: #aaa">
{{ blogger_info and blogger_info.full_name or full_name }} wrote this on {{ updated }}</div>
<br>
{{ content_html }}
<!-- end blog content -->
{% if blogger_info %}
<hr />
<div class="row">
<div class="span2">
<div class="avatar avatar-large">
<img src="{{ blogger_info.avatar }}" />
</div>
</div>
<div class="span10">
<h4>{{ blogger_info.full_name }}</h4>
<p>{{ blogger_info.bio }}</p>
<p><a href="blog?by={{ blogger_info.name }}&by_name={{ blogger_info.full_name }}">
All posts by {{ blogger_info.full_name }}</a></p>
</div>
</div>
{% endif %}
<hr>
<h3>Comments</h3><br>
<div class="blog-comments">
{% if not comment_list %}
<div class="alert no-comment">
<div class="no-comment">
<p>Be the first one to comment</p>
</div>
{% endif %}
@ -32,22 +48,19 @@
</div>
<div><button class="btn add-comment">Add Comment</button></div>
<div style="display: none; margin-top: 10px;"
id="comment-form" class="well">
id="comment-form">
<div class="alert" style="display:none;"></div>
<form>
<p>
<input name="comment_by_fullname" placeholder="Your Name" />
</p>
<p>
<input name="comment_by" placeholder="Your Email Id" />
</p>
<p>
<fieldset>
<input name="comment_by_fullname" placeholder="Your Name" type="text"/><br>
<input name="comment_by" placeholder="Your Email Id" type="text"/><br>
<textarea name="comment" placeholder="Comment" style="width: 300px; height: 120px;"/>
</textarea>
</p>
<p>
</textarea><br>
<button class="btn btn-info" id="submit-comment">Submit</button>
</fieldset>
</form>
</div>
<hr>
<a href="blog">Show posts by everyone</p>
</div>
{% endblock %}

View File

@ -10,7 +10,7 @@
<div class="container">
<div class="outer">
<div class="navbar{% if top_bar_background=="Black" %} navbar-inverse{% endif %}"
style="margin-bottom: 0px;">
style="">
<div class="navbar-inner">
<a class="brand" href="index">{{ brand_html }}</a>
<div class="container">

View File

@ -23,6 +23,11 @@ $(document).ready(function() {
$("#next-page").click(function() {
blog.get_list();
})
if(get_url_arg("by_name")) {
$("#blog-title").html("Posts by " + get_url_arg("by_name"));
$("#blog-link").toggle(true);
}
});
var blog = {
@ -33,10 +38,12 @@ var blog = {
url: "server.py",
data: {
cmd: "website.helpers.blog.get_blog_list",
start: blog.start
start: blog.start,
by: get_url_arg("by")
},
dataType: "json",
success: function(data) {
if(data.exc) console.log(data.exc);
blog.render(data.message);
}
});
@ -53,11 +60,20 @@ var blog = {
b.comment_text = b.comments + ' comments.'
}
$(repl('<h2><a href="%(page_name)s">%(title)s</a></h2>\
<div class="help">%(comment_text)s</div>\
%(content)s<br />\
<p><a href="%(page_name)s">Read with comments...</a></p>\
<hr /><br />', b)).appendTo($wrap);
$(repl('<div class="row">\
<div class="span1">\
<div class="avatar avatar-medium" style="margin-top: 6px;">\
<img src="%(avatar)s" />\
</div>\
</div>\
<div class="span11">\
<h4><a href="%(page_name)s">%(title)s</a></h4>\
<p>%(content)s</p>\
<p style="color: #aaa; font-size: 90%">\
<a href="blog?by=%(blogger)s&by_name=%(full_name)s">\
%(full_name)s</a> wrote this on %(published)s / %(comment_text)s</p>\
</div>\
</div><hr>', b)).appendTo($wrap);
});
blog.start += (data.length || 0);
if(!data.length) {

View File

@ -12,7 +12,8 @@
{% block content %}
<div class="span12">
<h1>Blog</h1>
<h2 id="blog-title">Blog</h2>
<p id="blog-link" style="display:none"><a href="blog">Show posts by everyone.</a></p>
<br>
<div id="blog-list">
<!-- blog list will be generated dynamically -->