Merge branch 'master' into edge
diff --git a/accounts/doctype/sales_invoice/sales_invoice.py b/accounts/doctype/sales_invoice/sales_invoice.py
index 47e3195..b31d549 100644
--- a/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/accounts/doctype/sales_invoice/sales_invoice.py
@@ -8,7 +8,7 @@
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
diff --git a/accounts/doctype/sales_invoice/test_sales_invoice.py b/accounts/doctype/sales_invoice/test_sales_invoice.py
index fb290d2..1f165f0 100644
--- a/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -38,72 +38,199 @@
si.insert()
si.submit()
- self.assertEquals(webnotes.conn.get_value("Time Log Batch", "_T-Time Log Batch-00001", "status"),
- "Billed")
+ self.assertEquals(webnotes.conn.get_value("Time Log Batch", "_T-Time Log Batch-00001",
+ "status"), "Billed")
self.assertEquals(webnotes.conn.get_value("Time Log", "_T-Time Log-00001", "status"),
"Billed")
si.cancel()
- self.assertEquals(webnotes.conn.get_value("Time Log Batch", "_T-Time Log Batch-00001", "status"),
- "Submitted")
+ self.assertEquals(webnotes.conn.get_value("Time Log Batch", "_T-Time Log Batch-00001",
+ "status"), "Submitted")
self.assertEquals(webnotes.conn.get_value("Time Log", "_T-Time Log-00001", "status"),
"Batched for Billing")
+ def test_sales_invoice_gl_entry_without_aii(self):
+ si = webnotes.bean(webnotes.copy_doclist(test_records[1]))
+ si.insert()
+ si.submit()
+ webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
+
+ gl_entries = webnotes.conn.sql("""select account, debit, credit
+ from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
+ order by account asc""", si.doc.name, as_dict=1)
+ self.assertTrue(gl_entries)
+ expected_values = sorted([
+ [si.doc.debit_to, 630.0, 0.0],
+ [test_records[1][1]["income_account"], 0.0, 500.0],
+ [test_records[1][2]["account_head"], 0.0, 80.0],
+ [test_records[1][3]["account_head"], 0.0, 50.0],
+ ])
+
+ for i, gle in enumerate(gl_entries):
+ self.assertEquals(expected_values[i][0], gle.account)
+ self.assertEquals(expected_values[i][1], gle.debit)
+ self.assertEquals(expected_values[i][2], gle.credit)
+
+ def test_sales_invoice_gl_entry_with_aii(self):
+ webnotes.defaults.set_global_default("auto_inventory_accounting", 1)
+
+ self._insert_purchase_receipt()
+ dn = self._insert_delivery_note()
+
+ si_against_dn = webnotes.copy_doclist(test_records[1])
+ si_against_dn[1]["delivery_note"] = dn.doc.name
+ si = webnotes.bean(si_against_dn)
+ si.insert()
+ si.submit()
+
+ gl_entries = webnotes.conn.sql("""select account, debit, credit
+ from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
+ order by account asc""", si.doc.name, as_dict=1)
+ self.assertTrue(gl_entries)
+
+ expected_values = sorted([
+ [si.doc.debit_to, 630.0, 0.0],
+ [test_records[1][1]["income_account"], 0.0, 500.0],
+ [test_records[1][2]["account_head"], 0.0, 80.0],
+ [test_records[1][3]["account_head"], 0.0, 50.0],
+ ["Stock Delivered But Not Billed - _TC", 0.0, 375.0],
+ [test_records[1][1]["expense_account"], 375.0, 0.0]
+ ])
+ print expected_values
+ print gl_entries
+ for i, gle in enumerate(gl_entries):
+ self.assertEquals(expected_values[i][0], gle.account)
+ self.assertEquals(expected_values[i][1], gle.debit)
+ self.assertEquals(expected_values[i][2], gle.credit)
+
+ webnotes.defaults.set_global_default("auto_inventory_accounting", 1)
+
+
+ def _insert_purchase_receipt(self):
+ from stock.doctype.purchase_receipt.test_purchase_receipt import test_records \
+ as pr_test_records
+ pr = webnotes.bean(copy=pr_test_records[0])
+ pr.run_method("calculate_taxes_and_totals")
+ pr.insert()
+ pr.submit()
+
+ def _insert_delivery_note(self):
+ from stock.doctype.delivery_note.test_delivery_note import test_records \
+ as dn_test_records
+ dn = webnotes.bean(copy=dn_test_records[0])
+ dn.insert()
+ dn.submit()
+ return dn
test_dependencies = ["Journal Voucher"]
-test_records = [[
- {
- "naming_series": "_T-Sales Invoice-",
- "company": "_Test Company",
- "conversion_rate": 1.0,
- "currency": "INR",
- "debit_to": "_Test Customer - _TC",
- "customer": "_Test Customer",
- "customer_name": "_Test Customer",
- "doctype": "Sales Invoice",
- "due_date": "2013-01-23",
- "fiscal_year": "_Test Fiscal Year 2013",
- "grand_total": 561.8,
- "grand_total_export": 561.8,
- "net_total": 500.0,
- "plc_conversion_rate": 1.0,
- "posting_date": "2013-01-23",
- "price_list_currency": "INR",
- "price_list_name": "_Test Price List",
- "territory": "_Test Territory"
- },
- {
- "amount": 500.0,
- "basic_rate": 500.0,
- "description": "138-CMS Shoe",
- "doctype": "Sales Invoice Item",
- "export_amount": 500.0,
- "export_rate": 500.0,
- "income_account": "Sales - _TC",
- "cost_center": "_Test Cost Center - _TC",
- "item_name": "138-CMS Shoe",
- "parentfield": "entries",
- "qty": 1.0
- },
- {
- "account_head": "_Test Account VAT - _TC",
- "charge_type": "On Net Total",
- "description": "VAT",
- "doctype": "Sales Taxes and Charges",
- "parentfield": "other_charges",
- "tax_amount": 30.0,
- },
- {
- "account_head": "_Test Account Service Tax - _TC",
- "charge_type": "On Net Total",
- "description": "Service Tax",
- "doctype": "Sales Taxes and Charges",
- "parentfield": "other_charges",
- "tax_amount": 31.8,
- }
-]]
\ No newline at end of file
+test_records = [
+ [
+ {
+ "naming_series": "_T-Sales Invoice-",
+ "company": "_Test Company",
+ "conversion_rate": 1.0,
+ "currency": "INR",
+ "debit_to": "_Test Customer - _TC",
+ "customer": "_Test Customer",
+ "customer_name": "_Test Customer",
+ "doctype": "Sales Invoice",
+ "due_date": "2013-01-23",
+ "fiscal_year": "_Test Fiscal Year 2013",
+ "grand_total": 561.8,
+ "grand_total_export": 561.8,
+ "net_total": 500.0,
+ "plc_conversion_rate": 1.0,
+ "posting_date": "2013-01-23",
+ "price_list_currency": "INR",
+ "price_list_name": "_Test Price List",
+ "territory": "_Test Territory"
+ },
+ {
+ "amount": 500.0,
+ "basic_rate": 500.0,
+ "description": "138-CMS Shoe",
+ "doctype": "Sales Invoice Item",
+ "export_amount": 500.0,
+ "export_rate": 500.0,
+ "income_account": "Sales - _TC",
+ "cost_center": "_Test Cost Center - _TC",
+ "item_name": "138-CMS Shoe",
+ "parentfield": "entries",
+ "qty": 1.0
+ },
+ {
+ "account_head": "_Test Account VAT - _TC",
+ "charge_type": "On Net Total",
+ "description": "VAT",
+ "doctype": "Sales Taxes and Charges",
+ "parentfield": "other_charges",
+ "tax_amount": 30.0,
+ },
+ {
+ "account_head": "_Test Account Service Tax - _TC",
+ "charge_type": "On Net Total",
+ "description": "Service Tax",
+ "doctype": "Sales Taxes and Charges",
+ "parentfield": "other_charges",
+ "tax_amount": 31.8,
+ }
+ ],
+ [
+ {
+ "naming_series": "_T-Sales Invoice-",
+ "company": "_Test Company",
+ "conversion_rate": 1.0,
+ "currency": "INR",
+ "debit_to": "_Test Customer - _TC",
+ "customer": "_Test Customer",
+ "customer_name": "_Test Customer",
+ "doctype": "Sales Invoice",
+ "due_date": "2013-01-23",
+ "fiscal_year": "_Test Fiscal Year 2013",
+ "grand_total": 630.0,
+ "grand_total_export": 630.0,
+ "net_total": 500.0,
+ "plc_conversion_rate": 1.0,
+ "posting_date": "2013-03-07",
+ "price_list_currency": "INR",
+ "price_list_name": "_Test Price List",
+ "territory": "_Test Territory"
+ },
+ {
+ "item_code": "_Test Item",
+ "item_name": "_Test Item",
+ "description": "_Test Item",
+ "doctype": "Sales Invoice Item",
+ "parentfield": "entries",
+ "qty": 1.0,
+ "basic_rate": 500.0,
+ "amount": 500.0,
+ "export_rate": 500.0,
+ "export_amount": 500.0,
+ "income_account": "Sales - _TC",
+ "expense_account": "_Test Account Cost for Goods Sold",
+ "cost_center": "_Test Cost Center - _TC",
+ },
+ {
+ "account_head": "_Test Account VAT - _TC",
+ "charge_type": "On Net Total",
+ "description": "VAT",
+ "doctype": "Sales Taxes and Charges",
+ "parentfield": "other_charges",
+ "tax_amount": 80.0,
+ },
+ {
+ "account_head": "_Test Account Service Tax - _TC",
+ "charge_type": "On Net Total",
+ "description": "Service Tax",
+ "doctype": "Sales Taxes and Charges",
+ "parentfield": "other_charges",
+ "tax_amount": 50.0,
+ }
+ ],
+]
\ No newline at end of file
diff --git a/patches/patch_list.py b/patches/patch_list.py
index d136820..2751854e 100644
--- a/patches/patch_list.py
+++ b/patches/patch_list.py
@@ -16,7 +16,6 @@
from __future__ import unicode_literals
patch_list = [
- "execute:webnotes.reload_doc('core', 'doctype', 'report') # 2013-03-07",
"patches.mar_2012.so_rv_mapper_fix",
"patches.mar_2012.clean_property_setter",
"patches.april_2012.naming_series_patch",
@@ -209,4 +208,5 @@
"execute:webnotes.conn.sql('update tabDocPerm set `submit`=1, `cancel`=1, `amend`=1 where parent=\"Time Log\"')",
"execute:webnotes.delete_doc('DocType', 'Attendance Control Panel')",
"patches.march_2013.p02_get_global_default",
+ "execute:webnotes.bean('Style Settings', 'Style Settings').save()"
]
\ No newline at end of file
diff --git a/selling/doctype/sales_common/sales_common.py b/selling/doctype/sales_common/sales_common.py
index 47d139f..12ae4a8 100644
--- a/selling/doctype/sales_common/sales_common.py
+++ b/selling/doctype/sales_common/sales_common.py
@@ -341,12 +341,10 @@
# ========================================================================
# it indicates % contribution of sales person in sales
def get_allocated_sum(self,obj):
- sum = 0
- for d in getlist(obj.doclist,'sales_team'):
- sum += flt(d.allocated_percentage)
- if (flt(sum) != 100) and getlist(obj.doclist,'sales_team'):
- msgprint("Total Allocated % of Sales Persons should be 100%")
- raise Exception
+ sales_team_list = obj.doclist.get({"parentfield": "sales_team"})
+ total_allocation = sum([flt(d.allocated_percentage) for d in sales_team_list])
+ if sales_team_list and total_allocation != 100.0:
+ msgprint("Total Allocated %% of Sales Persons should be 100%", raise_exception=True)
# Check Conversion Rate (i.e. it will not allow conversion rate to be 1 for Currency other than default currency set in Global Defaults)
# ===========================================================================
diff --git a/stock/doctype/delivery_note/test_delivery_note.py b/stock/doctype/delivery_note/test_delivery_note.py
index c2bb5d0..acdf8b9 100644
--- a/stock/doctype/delivery_note/test_delivery_note.py
+++ b/stock/doctype/delivery_note/test_delivery_note.py
@@ -109,7 +109,7 @@
"description": "CPU",
"doctype": "Delivery Note Item",
"item_code": "_Test Item",
- "item_name": "CPU",
+ "item_name": "_Test Item",
"parentfield": "delivery_note_details",
"qty": 5.0,
"basic_rate": 100.0,
diff --git a/stock/doctype/stock_ledger/stock_ledger.py b/stock/doctype/stock_ledger/stock_ledger.py
index 05fc0e0..5dff992 100644
--- a/stock/doctype/stock_ledger/stock_ledger.py
+++ b/stock/doctype/stock_ledger/stock_ledger.py
@@ -17,7 +17,7 @@
from __future__ import unicode_literals
import webnotes
-from webnotes.utils import add_days, cstr, flt, nowdate, cint
+from webnotes.utils import add_days, cstr, flt, nowdate, cint, now
from webnotes.model.doc import Document
from webnotes.model.bean import getlist
from webnotes.model.code import get_obj
@@ -49,7 +49,7 @@
serial_nos = get_valid_serial_nos(d.serial_no)
for s in serial_nos:
s = s.strip()
- sr_war = sql("select warehouse,name from `tabSerial No` where name = '%s'" % (s))
+ sr_war = webnotes.conn.sql("select warehouse,name from `tabSerial No` where name = '%s'" % (s))
if not sr_war:
msgprint("Serial No %s does not exists"%s, raise_exception = 1)
elif not sr_war[0][0]:
@@ -81,7 +81,7 @@
def set_pur_serial_no_values(self, obj, serial_no, d, s, new_rec, rejected=None):
- item_details = sql("""select item_group, warranty_period
+ item_details = webnotes.conn.sql("""select item_group, warranty_period
from `tabItem` where name = '%s' and (ifnull(end_of_life,'')='' or
end_of_life = '0000-00-00' or end_of_life > now()) """ %(d.item_code), as_dict=1)
@@ -112,7 +112,7 @@
def update_serial_purchase_details(self, obj, d, serial_no, is_submit, purpose = '', rejected=None):
- exists = sql("select name, status, docstatus from `tabSerial No` where name = '%s'" % (serial_no))
+ exists = webnotes.conn.sql("select name, status, docstatus from `tabSerial No` where name = '%s'" % (serial_no))
if is_submit:
if exists and exists[0][2] != 2 and purpose not in ['Material Transfer', 'Sales Return']:
msgprint("Serial No: %s already %s" % (serial_no, exists and exists[0][1]), raise_exception = 1)
@@ -126,15 +126,15 @@
if exists and exists[0][1] == 'Delivered' and exists[0][2] != 2:
msgprint("Serial No: %s is already delivered, you can not cancel the document." % serial_no, raise_exception=1)
elif purpose == 'Material Transfer':
- sql("update `tabSerial No` set status = 'In Store', purchase_document_type = '', purchase_document_no = '', warehouse = '%s' where name = '%s'" % (d.s_warehouse, serial_no))
+ webnotes.conn.sql("update `tabSerial No` set status = 'In Store', purchase_document_type = '', purchase_document_no = '', warehouse = '%s' where name = '%s'" % (d.s_warehouse, serial_no))
elif purpose == 'Sales Return':
- sql("update `tabSerial No` set status = 'Delivered', purchase_document_type = '', purchase_document_no = '' where name = '%s'" % serial_no)
+ webnotes.conn.sql("update `tabSerial No` set status = 'Delivered', purchase_document_type = '', purchase_document_no = '' where name = '%s'" % serial_no)
else:
- sql("update `tabSerial No` set docstatus = 2, status = 'Not in Use', purchase_document_type = '', purchase_document_no = '', purchase_date = null, purchase_rate = 0, supplier = null, supplier_name = '', supplier_address = '', warehouse = '' where name = '%s'" % serial_no)
+ webnotes.conn.sql("update `tabSerial No` set docstatus = 2, status = 'Not in Use', purchase_document_type = '', purchase_document_no = '', purchase_date = null, purchase_rate = 0, supplier = null, supplier_name = '', supplier_address = '', warehouse = '' where name = '%s'" % serial_no)
def check_serial_no_exists(self, serial_no, item_code):
- chk = sql("select name, status, docstatus, item_code from `tabSerial No` where name = %s", (serial_no), as_dict=1)
+ chk = webnotes.conn.sql("select name, status, docstatus, item_code from `tabSerial No` where name = %s", (serial_no), as_dict=1)
if not chk:
msgprint("Serial No: %s does not exists in the system" % serial_no, raise_exception=1)
elif chk and chk[0]['item_code'] != item_code:
@@ -169,7 +169,7 @@
self.check_serial_no_exists(serial_no, d.item_code)
self.set_delivery_serial_no_values(obj, serial_no)
else:
- sql("update `tabSerial No` set docstatus = 0, status = 'In Store', delivery_document_type = '', delivery_document_no = '', delivery_date = null, customer = null, customer_name = '', delivery_address = '', territory = null where name = '%s'" % (serial_no))
+ webnotes.conn.sql("update `tabSerial No` set docstatus = 0, status = 'In Store', delivery_document_type = '', delivery_document_no = '', delivery_date = null, customer = null, customer_name = '', delivery_address = '', territory = null where name = '%s'" % (serial_no))
def update_serial_record(self, obj, fname, is_submit = 1, is_incoming = 0):
@@ -202,8 +202,10 @@
if v.get('is_cancelled') == 'Yes':
v['actual_qty'] = -flt(v['actual_qty'])
# cancel matching entry
- sql("update `tabStock Ledger Entry` set is_cancelled='Yes' where voucher_no=%s \
- and voucher_type=%s", (v['voucher_no'], v['voucher_type']))
+ webnotes.conn.sql("""update `tabStock Ledger Entry` set is_cancelled='Yes',
+ modified=%s, modified_by=%s
+ where voucher_no=%s and voucher_type=%s""",
+ (now(), webnotes.session.user, v['voucher_no'], v['voucher_type']))
if v.get("actual_qty"):
sle_id = self.make_entry(v)
@@ -230,5 +232,5 @@
"""
Repost everything!
"""
- for wh in sql("select name from tabWarehouse"):
+ for wh in webnotes.conn.sql("select name from tabWarehouse"):
get_obj('Warehouse', wh[0]).repost_stock()
diff --git a/website/css/website.css b/website/css/website.css
index 956f22e..dc5b967 100644
--- a/website/css/website.css
+++ b/website/css/website.css
@@ -1,17 +1,12 @@
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: 20px;
- margin: 30px -20px 10px -20px;
+ padding: 30px;
+ margin: 30px -30px 10px -30px;
min-height: 400px;
overflow: hidden;
}
.outer .navbar {
- margin: -20px -20px 10px -20px;
+ margin: -30px -30px 10px -30px;
}
footer {
@@ -24,6 +19,8 @@
border: 0px;
border-bottom: 1px solid #ddd;
border-radius: 0px;
+ padding-right: 30px;
+ padding-left: 30px;
}
p, li {
@@ -98,6 +95,18 @@
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;
@@ -121,5 +130,3 @@
.avatar-x-large img {
width: 100px;
}
-
-/* */
\ No newline at end of file
diff --git a/website/doctype/blog/blog.py b/website/doctype/blog/blog.py
index cfc0ca6..d7ffdac 100644
--- a/website/doctype/blog/blog.py
+++ b/website/doctype/blog/blog.py
@@ -18,6 +18,7 @@
import webnotes
import website.utils
+from webnotes import _
class DocType:
def __init__(self, d, dl):
@@ -27,6 +28,9 @@
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 +70,20 @@
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
+
+ self.doc.categories = webnotes.conn.sql_list("select name from `tabBlog Category` order by name")
+
+ self.doc.texts = {
+ "comments": _("Comments"),
+ "first_comment": _("Be the first one to comment"),
+ "add_comment": _("Add Comment"),
+ "submit": _("Submit"),
+ "all_posts_by": _("All posts by"),
+ }
comment_list = webnotes.conn.sql("""\
select comment, comment_by_fullname, creation
diff --git a/website/doctype/blog/blog.txt b/website/doctype/blog/blog.txt
index af9606a..e4c92c2 100644
--- a/website/doctype/blog/blog.txt
+++ b/website/doctype/blog/blog.txt
@@ -2,7 +2,7 @@
{
"creation": "2013-01-25 11:35:09",
"docstatus": 0,
- "modified": "2013-02-21 16:54:04",
+ "modified": "2013-03-08 09:41:37",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -50,18 +50,44 @@
"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": "blog_category",
+ "fieldtype": "Link",
+ "label": "Blog Category",
+ "options": "Blog Category"
+ },
+ {
+ "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",
diff --git a/website/doctype/blog_category/__init__.py b/website/doctype/blog_category/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/website/doctype/blog_category/__init__.py
diff --git a/website/doctype/blog_category/blog_category.py b/website/doctype/blog_category/blog_category.py
new file mode 100644
index 0000000..c8c369c
--- /dev/null
+++ b/website/doctype/blog_category/blog_category.py
@@ -0,0 +1,14 @@
+# 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):
+ # for blog footer
+ from website.utils import clear_cache
+ clear_cache()
+
\ No newline at end of file
diff --git a/website/doctype/blog_category/blog_category.txt b/website/doctype/blog_category/blog_category.txt
new file mode 100644
index 0000000..cf8cad6
--- /dev/null
+++ b/website/doctype/blog_category/blog_category.txt
@@ -0,0 +1,51 @@
+[
+ {
+ "creation": "2013-03-08 09:41:11",
+ "docstatus": 0,
+ "modified": "2013-03-08 09:41:11",
+ "modified_by": "Administrator",
+ "owner": "Administrator"
+ },
+ {
+ "autoname": "field:category_name",
+ "doctype": "DocType",
+ "document_type": "Master",
+ "module": "Website",
+ "name": "__common__"
+ },
+ {
+ "doctype": "DocField",
+ "fieldname": "category_name",
+ "fieldtype": "Data",
+ "label": "Category Name",
+ "name": "__common__",
+ "parent": "Blog Category",
+ "parentfield": "fields",
+ "parenttype": "DocType",
+ "permlevel": 0,
+ "reqd": 1
+ },
+ {
+ "cancel": 1,
+ "create": 1,
+ "doctype": "DocPerm",
+ "name": "__common__",
+ "parent": "Blog Category",
+ "parentfield": "permissions",
+ "parenttype": "DocType",
+ "permlevel": 0,
+ "read": 1,
+ "role": "Website Manager",
+ "write": 1
+ },
+ {
+ "doctype": "DocType",
+ "name": "Blog Category"
+ },
+ {
+ "doctype": "DocField"
+ },
+ {
+ "doctype": "DocPerm"
+ }
+]
\ No newline at end of file
diff --git a/website/doctype/blogger/__init__.py b/website/doctype/blogger/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/website/doctype/blogger/__init__.py
diff --git a/website/doctype/blogger/blogger.py b/website/doctype/blogger/blogger.py
new file mode 100644
index 0000000..28d0f29
--- /dev/null
+++ b/website/doctype/blogger/blogger.py
@@ -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()
+
diff --git a/website/doctype/blogger/blogger.txt b/website/doctype/blogger/blogger.txt
new file mode 100644
index 0000000..01e0cea
--- /dev/null
+++ b/website/doctype/blogger/blogger.txt
@@ -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"
+ }
+]
\ No newline at end of file
diff --git a/website/doctype/style_settings/custom_template.css b/website/doctype/style_settings/custom_template.css
index 9009bbe..e625f95 100644
--- a/website/doctype/style_settings/custom_template.css
+++ b/website/doctype/style_settings/custom_template.css
@@ -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 @@
{% 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,8 +25,106 @@
}
{% 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 %}
+{% if doc.heading_text_as %}
+h1, h2, h3, h4, h5 {
+ text-transform: {{ doc.heading_text_as }};
}
{% endif %}
+
+{% 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;
+ border-color: transparent;
+ background-image: none;
+}
+
+.navbar-inverse .brand,
+.navbar-inverse .nav > li > a {
+ color: #{{ doc.top_bar_foreground or "fff"}};
+ text-shadow: none;
+}
+
+.navbar-inverse .brand:hover,
+.navbar-inverse .nav > li > a:hover,
+.navbar-inverse .brand:focus,
+.navbar-inverse .nav > li > a:focus {
+ color: #{{ doc.top_bar_foreground or "fff"}};
+}
+
+.navbar-inverse .brand {
+ color: #{{ doc.top_bar_foreground or "fff"}};
+}
+
+.navbar-inverse .navbar-text {
+ color: #999999;
+}
+
+.navbar-inverse .nav > li > a:focus,
+.navbar-inverse .nav > li > a:hover {
+ color: #{{ doc.top_bar_foreground or "fff"}};
+ background-color: transparent;
+}
+
+.navbar-inverse .nav .active > a,
+.navbar-inverse .nav .active > a:hover,
+.navbar-inverse .nav .active > a:focus {
+ color: #{{ doc.top_bar_foreground or "fff"}};
+ background-color: transparent;
+}
+
+.navbar-inverse .navbar-link {
+ color: #999999;
+}
+
+.navbar-inverse .navbar-link:hover,
+.navbar-inverse .navbar-link:focus {
+ color: #{{ doc.top_bar_foreground or "fff"}};
+}
+
+.navbar-fixed-top .navbar-inner,
+.navbar-static-top .navbar-inner {
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+ box-shadow: none;
+
+}
+.navbar .nav > .active > a,
+.navbar .nav > .active > a:hover,
+.navbar .nav > .active > a:focus {
+ color: #424242;
+ text-decoration: none;
+ background-color: transparent;
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+ box-shadow: none;
+}
+
+.navbar-inverse .nav li.dropdown > .dropdown-toggle .caret {
+ border-top-color: #{{ doc.top_bar_foreground or "fff"}};
+ border-bottom-color: #{{ doc.top_bar_foreground or "fff"}};
+}
diff --git a/website/doctype/style_settings/style_settings.js b/website/doctype/style_settings/style_settings.js
index 54091a3..e8ee908 100644
--- a/website/doctype/style_settings/style_settings.js
+++ b/website/doctype/style_settings/style_settings.js
@@ -18,5 +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();
}
\ No newline at end of file
diff --git a/website/doctype/style_settings/style_settings.py b/website/doctype/style_settings/style_settings.py
index 5179948..0a1a2e0 100644
--- a/website/doctype/style_settings/style_settings.py
+++ b/website/doctype/style_settings/style_settings.py
@@ -15,6 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from __future__ import unicode_literals
+from webnotes.utils import cint, cstr
+
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
@@ -29,10 +31,7 @@
'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 +40,36 @@
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 = cstr(cint(self.doc.font_size[:-2])-2) + 'px'
+ self.doc.page_border = cint(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))
+
+ if self.doc.heading_text_as:
+ self.doc.heading_text_as = {
+ "UPPERCASE": "uppercase",
+ "Title Case":"capitalize",
+ "lowercase": "lowercase"
+ }[self.doc.heading_text_as]
+
+ 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"""
diff --git a/website/doctype/style_settings/style_settings.txt b/website/doctype/style_settings/style_settings.txt
index 5f53441..e58ae09 100644
--- a/website/doctype/style_settings/style_settings.txt
+++ b/website/doctype/style_settings/style_settings.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-10 16:34:32",
+ "creation": "2013-01-25 11:35:10",
"docstatus": 0,
- "modified": "2013-01-22 14:57:25",
+ "modified": "2013-03-08 09:58:49",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -24,24 +24,27 @@
"permlevel": 0
},
{
- "create": 1,
"doctype": "DocPerm",
"name": "__common__",
"parent": "Style Settings",
"parentfield": "permissions",
"parenttype": "DocType",
- "permlevel": 0,
"read": 1,
- "report": 1,
+ "report": 0,
"role": "Website Manager",
- "submit": 0,
- "write": 1
+ "submit": 0
},
{
"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",
"fieldname": "background_image",
@@ -58,6 +61,18 @@
},
{
"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%",
@@ -65,24 +80,70 @@
},
{
"doctype": "DocField",
+ "fieldname": "top_bar_background",
+ "fieldtype": "Data",
+ "label": "Top Bar Background"
+ },
+ {
+ "description": "000 is black, fff is white",
+ "doctype": "DocField",
+ "fieldname": "top_bar_foreground",
+ "fieldtype": "Select",
+ "label": "Top Bar Foreground",
+ "options": "000\nFFF"
+ },
+ {
+ "doctype": "DocField",
+ "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",
+ "fieldname": "heading_text_as",
"fieldtype": "Select",
- "label": "Heading Font",
- "options": "\nHelvetica Neue\nLucida Grande\nVerdana\nArial\nGeorgia\nTahoma\nLato\nOpen Sans"
+ "label": "Heading Text As",
+ "options": "\nUPPERCASE\nTitle Case\nlowercase"
+ },
+ {
+ "doctype": "DocField",
+ "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",
@@ -115,6 +176,16 @@
"print_hide": 1
},
{
- "doctype": "DocPerm"
+ "create": 1,
+ "doctype": "DocPerm",
+ "permlevel": 0,
+ "write": 1
+ },
+ {
+ "amend": 0,
+ "cancel": 0,
+ "create": 0,
+ "doctype": "DocPerm",
+ "permlevel": 1
}
]
\ No newline at end of file
diff --git a/website/doctype/website_settings/website_settings.py b/website/doctype/website_settings/website_settings.py
index 88af634..714b75a 100644
--- a/website/doctype/website_settings/website_settings.py
+++ b/website/doctype/website_settings/website_settings.py
@@ -31,9 +31,6 @@
from website.utils import clear_cache
clear_cache()
- from webnotes.sessions import clear_cache
- clear_cache('Guest')
-
def set_home_page(self):
import webnotes
diff --git a/website/helpers/blog.py b/website/helpers/blog.py
index 2bff6e5..d90c85a 100644
--- a/website/helpers/blog.py
+++ b/website/helpers/blog.py
@@ -4,41 +4,44 @@
from __future__ import unicode_literals
import webnotes
import website.utils
+from webnotes import _
@webnotes.whitelist(allow_guest=True)
-def get_blog_list(args=None):
- """
- args = {
- 'start': 0,
- }
- """
+def get_blog_list(start=0, by=None, category=None):
import webnotes
-
- if not args: args = webnotes.form_dict
-
+ condition = ""
+ if by:
+ condition = " and t1.blogger='%s'" % by.replace("'", "\'")
+ if category:
+ condition += " and t1.blog_category='%s'" % category.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 +118,22 @@
import webnotes.utils
content = webnotes.utils.escape_html(content)
return content
+
+def get_blog_template_args():
+ return {
+ "categories": webnotes.conn.sql_list("select name from `tabBlog Category` order by name")
+ }
-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
\ No newline at end of file
+def get_writers_args():
+ bloggers = webnotes.conn.sql("select * from `tabBlogger` order by full_name", as_dict=1)
+ for blogger in bloggers:
+ if blogger.avatar and not "/" in blogger.avatar:
+ blogger.avatar = "files/" + blogger.avatar
+
+ return {
+ "bloggers": bloggers,
+ "texts": {
+ "all_posts_by": _("All posts by")
+ },
+ "categories": webnotes.conn.sql_list("select name from `tabBlog Category` order by name")
+ }
\ No newline at end of file
diff --git a/website/page/website_home/website_home.js b/website/page/website_home/website_home.js
index c6b2253..40e29e8 100644
--- a/website/page/website_home/website_home.js
+++ b/website/page/website_home/website_home.js
@@ -12,11 +12,6 @@
doctype:"Web Page"
},
{
- label: wn._("Blog"),
- description: wn._("Blog entry."),
- doctype:"Blog"
- },
- {
label: wn._("Website Slideshow"),
description: wn._("Embed image slideshows in website pages."),
doctype:"Website Slideshow"
@@ -24,6 +19,28 @@
]
},
{
+ title: wn._("Blog"),
+ icon: "icon-edit",
+ items: [
+ {
+ label: wn._("Blog"),
+ description: wn._("Blog post."),
+ doctype:"Blog"
+ },
+ {
+ label: wn._("Blogger"),
+ description: wn._("Profile of a blog writer."),
+ doctype:"Blogger"
+ },
+ {
+ label: wn._("Blog Category"),
+ description: wn._("Categorize blog posts."),
+ doctype:"Blogger"
+ },
+ ]
+ },
+
+ {
title: wn._("Website Overall Settings"),
icon: "icon-wrench",
right: true,
diff --git a/website/templates/html/blog_footer.html b/website/templates/html/blog_footer.html
new file mode 100644
index 0000000..e439d14
--- /dev/null
+++ b/website/templates/html/blog_footer.html
@@ -0,0 +1,13 @@
+<div class="span12">
+ <hr />
+ {% if categories %}
+ <h5>Explore posts by categories</h5>
+ <ul class="breadcrumb" style="background-color: transparent; padding-left: 0px;">
+ {% for category in categories %}
+ <li><a href="blog?category={{ category }}">{{ category }}</a>
+ {% if not loop.last %}<span class="divider">/</span>{% endif %}</li>
+ {% endfor %}
+ <br><br>
+ {% endif %}
+ <p>Show posts by <a href="blog">everyone</a>. Meet the <a href="writers">writers</a> of this blog</p>
+</div>
diff --git a/website/templates/html/blog_page.html b/website/templates/html/blog_page.html
index 24dd8d7..e605a12 100644
--- a/website/templates/html/blog_page.html
+++ b/website/templates/html/blog_page.html
@@ -13,41 +13,41 @@
<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 }} / {{ updated }}</div>
<br>
{{ content_html }}
<!-- end blog content -->
-
+ {% if blogger_info %}
+ <hr />
+ {% include "html/blogger.html" %}
+ {% endif %}
<hr>
- <h3>Comments</h3><br>
+ <h3>{{ texts.comments }}</h3><br>
<div class="blog-comments">
{% if not comment_list %}
- <div class="alert no-comment">
- <p>Be the first one to comment</p>
+ <div class="no-comment">
+ <p>{{ texts.first_comment }}</p>
</div>
{% endif %}
{% include 'html/comment.html' %}
</div>
- <div><button class="btn add-comment">Add Comment</button></div>
+ <div><button class="btn add-comment">{{ texts.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>
- <button class="btn btn-info" id="submit-comment">Submit</button>
+ </textarea><br>
+ <button class="btn btn-info" id="submit-comment">{{ texts.submit }}</button>
+ </fieldset>
</form>
</div>
</div>
+{% include 'html/blog_footer.html' %}
{% endblock %}
\ No newline at end of file
diff --git a/website/templates/html/blogger.html b/website/templates/html/blogger.html
new file mode 100644
index 0000000..eab371e
--- /dev/null
+++ b/website/templates/html/blogger.html
@@ -0,0 +1,13 @@
+<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 style="color: #999">{{ blogger_info.bio }}</p>
+ <p><a href="blog?by={{ blogger_info.name }}&by_name={{ blogger_info.full_name }}">
+ {{ texts.all_posts_by }} {{ blogger_info.full_name }}</a></p>
+ </div>
+</div>
\ No newline at end of file
diff --git a/website/templates/html/outer.html b/website/templates/html/outer.html
index de96122..e582d0a 100644
--- a/website/templates/html/outer.html
+++ b/website/templates/html/outer.html
@@ -6,7 +6,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">
diff --git a/website/templates/js/blog.js b/website/templates/js/blog.js
index 6c006de..3cfb234 100644
--- a/website/templates/js/blog.js
+++ b/website/templates/js/blog.js
@@ -23,6 +23,15 @@
$("#next-page").click(function() {
blog.get_list();
})
+
+ if(get_url_arg("by_name")) {
+ $("#blog-title").html("Posts by " + get_url_arg("by_name"));
+ }
+
+ if(get_url_arg("category")) {
+ $("#blog-title").html("Posts filed under " + get_url_arg("category"));
+ }
+
});
var blog = {
@@ -33,10 +42,13 @@
url: "server.py",
data: {
cmd: "website.helpers.blog.get_blog_list",
- start: blog.start
+ start: blog.start,
+ by: get_url_arg("by"),
+ category: get_url_arg("category")
},
dataType: "json",
success: function(data) {
+ if(data.exc) console.log(data.exc);
blog.render(data.message);
}
});
@@ -53,11 +65,20 @@
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) {
diff --git a/website/templates/pages/blog.html b/website/templates/pages/blog.html
index 3c2a579..05302c6 100644
--- a/website/templates/pages/blog.html
+++ b/website/templates/pages/blog.html
@@ -12,7 +12,7 @@
{% block content %}
<div class="span12">
- <h1>Blog</h1>
+ <h2 id="blog-title">Blog</h2>
<br>
<div id="blog-list">
<!-- blog list will be generated dynamically -->
@@ -22,4 +22,5 @@
style="display:none;">More...</button>
</div>
</div>
+{% include 'html/blog_footer.html' %}
{% endblock %}
\ No newline at end of file
diff --git a/website/templates/pages/writers.html b/website/templates/pages/writers.html
new file mode 100644
index 0000000..0ae8549
--- /dev/null
+++ b/website/templates/pages/writers.html
@@ -0,0 +1,14 @@
+{% extends "html/page.html" %}
+
+{% set title="Blog Writers" %}
+
+{% block content %}
+<div class="span12">
+ <h2 id="blog-title">Blog Writers</h2>
+ <hr>
+ {% for blogger_info in bloggers %}
+ {% include "html/blogger.html" %}
+ {% endfor %}
+</div>
+{% include 'html/blog_footer.html' %}
+{% endblock %}
\ No newline at end of file
diff --git a/website/utils.py b/website/utils.py
index 97c03bc..a9569b4 100644
--- a/website/utils.py
+++ b/website/utils.py
@@ -41,7 +41,9 @@
page_settings_map = {
"about": "About Us Settings",
- "contact": "Contact Us Settings"
+ "contact": "Contact Us Settings",
+ "blog": "website.helpers.blog.get_blog_template_args",
+ "writers": "website.helpers.blog.get_writers_args"
}
def render(page_name):
@@ -155,7 +157,11 @@
'name': page_name,
})
if page_name in page_settings_map:
- args.obj = webnotes.bean(page_settings_map[page_name]).obj
+ target = page_settings_map[page_name]
+ if "." in target:
+ args.update(webnotes.get_method(target)())
+ else:
+ args.obj = webnotes.bean(page_settings_map[page_name]).obj
else:
args = get_doc_fields(page_name)