Merge branch 'master' into edge
This commit is contained in:
commit
981db7b561
@ -38,25 +38,98 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
si.insert()
|
si.insert()
|
||||||
si.submit()
|
si.submit()
|
||||||
|
|
||||||
self.assertEquals(webnotes.conn.get_value("Time Log Batch", "_T-Time Log Batch-00001", "status"),
|
self.assertEquals(webnotes.conn.get_value("Time Log Batch", "_T-Time Log Batch-00001",
|
||||||
"Billed")
|
"status"), "Billed")
|
||||||
|
|
||||||
self.assertEquals(webnotes.conn.get_value("Time Log", "_T-Time Log-00001", "status"),
|
self.assertEquals(webnotes.conn.get_value("Time Log", "_T-Time Log-00001", "status"),
|
||||||
"Billed")
|
"Billed")
|
||||||
|
|
||||||
si.cancel()
|
si.cancel()
|
||||||
|
|
||||||
self.assertEquals(webnotes.conn.get_value("Time Log Batch", "_T-Time Log Batch-00001", "status"),
|
self.assertEquals(webnotes.conn.get_value("Time Log Batch", "_T-Time Log Batch-00001",
|
||||||
"Submitted")
|
"status"), "Submitted")
|
||||||
|
|
||||||
self.assertEquals(webnotes.conn.get_value("Time Log", "_T-Time Log-00001", "status"),
|
self.assertEquals(webnotes.conn.get_value("Time Log", "_T-Time Log-00001", "status"),
|
||||||
"Batched for Billing")
|
"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_dependencies = ["Journal Voucher"]
|
||||||
|
|
||||||
test_records = [[
|
test_records = [
|
||||||
|
[
|
||||||
{
|
{
|
||||||
"naming_series": "_T-Sales Invoice-",
|
"naming_series": "_T-Sales Invoice-",
|
||||||
"company": "_Test Company",
|
"company": "_Test Company",
|
||||||
@ -106,4 +179,58 @@ test_records = [[
|
|||||||
"parentfield": "other_charges",
|
"parentfield": "other_charges",
|
||||||
"tax_amount": 31.8,
|
"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,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
]
|
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
patch_list = [
|
patch_list = [
|
||||||
"execute:webnotes.reload_doc('core', 'doctype', 'report') # 2013-03-07",
|
|
||||||
"patches.mar_2012.so_rv_mapper_fix",
|
"patches.mar_2012.so_rv_mapper_fix",
|
||||||
"patches.mar_2012.clean_property_setter",
|
"patches.mar_2012.clean_property_setter",
|
||||||
"patches.april_2012.naming_series_patch",
|
"patches.april_2012.naming_series_patch",
|
||||||
@ -209,4 +208,5 @@ patch_list = [
|
|||||||
"execute:webnotes.conn.sql('update tabDocPerm set `submit`=1, `cancel`=1, `amend`=1 where parent=\"Time Log\"')",
|
"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')",
|
"execute:webnotes.delete_doc('DocType', 'Attendance Control Panel')",
|
||||||
"patches.march_2013.p02_get_global_default",
|
"patches.march_2013.p02_get_global_default",
|
||||||
|
"execute:webnotes.bean('Style Settings', 'Style Settings').save()"
|
||||||
]
|
]
|
@ -341,12 +341,10 @@ class DocType(TransactionBase):
|
|||||||
# ========================================================================
|
# ========================================================================
|
||||||
# it indicates % contribution of sales person in sales
|
# it indicates % contribution of sales person in sales
|
||||||
def get_allocated_sum(self,obj):
|
def get_allocated_sum(self,obj):
|
||||||
sum = 0
|
sales_team_list = obj.doclist.get({"parentfield": "sales_team"})
|
||||||
for d in getlist(obj.doclist,'sales_team'):
|
total_allocation = sum([flt(d.allocated_percentage) for d in sales_team_list])
|
||||||
sum += flt(d.allocated_percentage)
|
if sales_team_list and total_allocation != 100.0:
|
||||||
if (flt(sum) != 100) and getlist(obj.doclist,'sales_team'):
|
msgprint("Total Allocated %% of Sales Persons should be 100%", raise_exception=True)
|
||||||
msgprint("Total Allocated % of Sales Persons should be 100%")
|
|
||||||
raise Exception
|
|
||||||
|
|
||||||
# Check Conversion Rate (i.e. it will not allow conversion rate to be 1 for Currency other than default currency set in Global Defaults)
|
# Check Conversion Rate (i.e. it will not allow conversion rate to be 1 for Currency other than default currency set in Global Defaults)
|
||||||
# ===========================================================================
|
# ===========================================================================
|
||||||
|
@ -109,7 +109,7 @@ test_records = [
|
|||||||
"description": "CPU",
|
"description": "CPU",
|
||||||
"doctype": "Delivery Note Item",
|
"doctype": "Delivery Note Item",
|
||||||
"item_code": "_Test Item",
|
"item_code": "_Test Item",
|
||||||
"item_name": "CPU",
|
"item_name": "_Test Item",
|
||||||
"parentfield": "delivery_note_details",
|
"parentfield": "delivery_note_details",
|
||||||
"qty": 5.0,
|
"qty": 5.0,
|
||||||
"basic_rate": 100.0,
|
"basic_rate": 100.0,
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import webnotes
|
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.doc import Document
|
||||||
from webnotes.model.bean import getlist
|
from webnotes.model.bean import getlist
|
||||||
from webnotes.model.code import get_obj
|
from webnotes.model.code import get_obj
|
||||||
@ -49,7 +49,7 @@ class DocType:
|
|||||||
serial_nos = get_valid_serial_nos(d.serial_no)
|
serial_nos = get_valid_serial_nos(d.serial_no)
|
||||||
for s in serial_nos:
|
for s in serial_nos:
|
||||||
s = s.strip()
|
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:
|
if not sr_war:
|
||||||
msgprint("Serial No %s does not exists"%s, raise_exception = 1)
|
msgprint("Serial No %s does not exists"%s, raise_exception = 1)
|
||||||
elif not sr_war[0][0]:
|
elif not sr_war[0][0]:
|
||||||
@ -81,7 +81,7 @@ class DocType:
|
|||||||
|
|
||||||
|
|
||||||
def set_pur_serial_no_values(self, obj, serial_no, d, s, new_rec, rejected=None):
|
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
|
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)
|
end_of_life = '0000-00-00' or end_of_life > now()) """ %(d.item_code), as_dict=1)
|
||||||
|
|
||||||
@ -112,7 +112,7 @@ class DocType:
|
|||||||
|
|
||||||
|
|
||||||
def update_serial_purchase_details(self, obj, d, serial_no, is_submit, purpose = '', rejected=None):
|
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 is_submit:
|
||||||
if exists and exists[0][2] != 2 and purpose not in ['Material Transfer', 'Sales Return']:
|
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)
|
msgprint("Serial No: %s already %s" % (serial_no, exists and exists[0][1]), raise_exception = 1)
|
||||||
@ -126,15 +126,15 @@ class DocType:
|
|||||||
if exists and exists[0][1] == 'Delivered' and exists[0][2] != 2:
|
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)
|
msgprint("Serial No: %s is already delivered, you can not cancel the document." % serial_no, raise_exception=1)
|
||||||
elif purpose == 'Material Transfer':
|
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':
|
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:
|
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):
|
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:
|
if not chk:
|
||||||
msgprint("Serial No: %s does not exists in the system" % serial_no, raise_exception=1)
|
msgprint("Serial No: %s does not exists in the system" % serial_no, raise_exception=1)
|
||||||
elif chk and chk[0]['item_code'] != item_code:
|
elif chk and chk[0]['item_code'] != item_code:
|
||||||
@ -169,7 +169,7 @@ class DocType:
|
|||||||
self.check_serial_no_exists(serial_no, d.item_code)
|
self.check_serial_no_exists(serial_no, d.item_code)
|
||||||
self.set_delivery_serial_no_values(obj, serial_no)
|
self.set_delivery_serial_no_values(obj, serial_no)
|
||||||
else:
|
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):
|
def update_serial_record(self, obj, fname, is_submit = 1, is_incoming = 0):
|
||||||
@ -202,8 +202,10 @@ class DocType:
|
|||||||
if v.get('is_cancelled') == 'Yes':
|
if v.get('is_cancelled') == 'Yes':
|
||||||
v['actual_qty'] = -flt(v['actual_qty'])
|
v['actual_qty'] = -flt(v['actual_qty'])
|
||||||
# cancel matching entry
|
# cancel matching entry
|
||||||
sql("update `tabStock Ledger Entry` set is_cancelled='Yes' where voucher_no=%s \
|
webnotes.conn.sql("""update `tabStock Ledger Entry` set is_cancelled='Yes',
|
||||||
and voucher_type=%s", (v['voucher_no'], v['voucher_type']))
|
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"):
|
if v.get("actual_qty"):
|
||||||
sle_id = self.make_entry(v)
|
sle_id = self.make_entry(v)
|
||||||
@ -230,5 +232,5 @@ class DocType:
|
|||||||
"""
|
"""
|
||||||
Repost everything!
|
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()
|
get_obj('Warehouse', wh[0]).repost_stock()
|
||||||
|
@ -1,17 +1,12 @@
|
|||||||
div.outer {
|
div.outer {
|
||||||
-moz-box-shadow: 0px 0px 3px rgba(0,0,0,0.9);
|
padding: 30px;
|
||||||
-webkit-box-shadow: 0px 0px 3px rgba(0,0,0,0.9);
|
margin: 30px -30px 10px -30px;
|
||||||
box-shadow: 0px 0px 3px rgba(0,0,0,0.9);
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 5px;
|
|
||||||
padding: 20px;
|
|
||||||
margin: 30px -20px 10px -20px;
|
|
||||||
min-height: 400px;
|
min-height: 400px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.outer .navbar {
|
.outer .navbar {
|
||||||
margin: -20px -20px 10px -20px;
|
margin: -30px -30px 10px -30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
footer {
|
footer {
|
||||||
@ -24,6 +19,8 @@ footer {
|
|||||||
border: 0px;
|
border: 0px;
|
||||||
border-bottom: 1px solid #ddd;
|
border-bottom: 1px solid #ddd;
|
||||||
border-radius: 0px;
|
border-radius: 0px;
|
||||||
|
padding-right: 30px;
|
||||||
|
padding-left: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
p, li {
|
p, li {
|
||||||
@ -98,6 +95,18 @@ p, li {
|
|||||||
width: 30px;
|
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 {
|
.avatar-large {
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
width: 72px;
|
width: 72px;
|
||||||
@ -121,5 +130,3 @@ p, li {
|
|||||||
.avatar-x-large img {
|
.avatar-x-large img {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
|
@ -18,6 +18,7 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
import webnotes
|
import webnotes
|
||||||
import website.utils
|
import website.utils
|
||||||
|
from webnotes import _
|
||||||
|
|
||||||
class DocType:
|
class DocType:
|
||||||
def __init__(self, d, dl):
|
def __init__(self, d, dl):
|
||||||
@ -27,6 +28,9 @@ class DocType:
|
|||||||
from website.utils import page_name
|
from website.utils import page_name
|
||||||
self.doc.name = page_name(self.doc.title)
|
self.doc.name = page_name(self.doc.title)
|
||||||
|
|
||||||
|
def validate(self):
|
||||||
|
self.doc.blog_intro = self.doc.blog_intro[:140]
|
||||||
|
|
||||||
def on_update(self):
|
def on_update(self):
|
||||||
from website.utils import update_page_name
|
from website.utils import update_page_name
|
||||||
update_page_name(self.doc, self.doc.title)
|
update_page_name(self.doc, self.doc.title)
|
||||||
@ -66,6 +70,20 @@ class DocType:
|
|||||||
self.doc.full_name = get_fullname(self.doc.owner)
|
self.doc.full_name = get_fullname(self.doc.owner)
|
||||||
self.doc.updated = global_date_format(self.doc.creation)
|
self.doc.updated = global_date_format(self.doc.creation)
|
||||||
self.doc.content_html = self.doc.content
|
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("""\
|
comment_list = webnotes.conn.sql("""\
|
||||||
select comment, comment_by_fullname, creation
|
select comment, comment_by_fullname, creation
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"creation": "2013-01-25 11:35:09",
|
"creation": "2013-01-25 11:35:09",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-02-21 16:54:04",
|
"modified": "2013-03-08 09:41:37",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -50,18 +50,44 @@
|
|||||||
"label": "Published"
|
"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",
|
"doctype": "DocField",
|
||||||
"fieldname": "blog_intro",
|
"fieldname": "blog_intro",
|
||||||
"fieldtype": "Small Text",
|
"fieldtype": "Small Text",
|
||||||
"label": "Blog Intro"
|
"label": "Blog Intro",
|
||||||
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "content",
|
"fieldname": "content",
|
||||||
"fieldtype": "Text Editor",
|
"fieldtype": "Text Editor",
|
||||||
"label": "Content",
|
"label": "Content",
|
||||||
"reqd": 0
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
|
0
website/doctype/blog_category/__init__.py
Normal file
0
website/doctype/blog_category/__init__.py
Normal file
14
website/doctype/blog_category/blog_category.py
Normal file
14
website/doctype/blog_category/blog_category.py
Normal file
@ -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()
|
||||||
|
|
51
website/doctype/blog_category/blog_category.txt
Normal file
51
website/doctype/blog_category/blog_category.txt
Normal file
@ -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"
|
||||||
|
}
|
||||||
|
]
|
0
website/doctype/blogger/__init__.py
Normal file
0
website/doctype/blogger/__init__.py
Normal file
18
website/doctype/blogger/blogger.py
Normal file
18
website/doctype/blogger/blogger.py
Normal 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()
|
||||||
|
|
95
website/doctype/blogger/blogger.txt
Normal file
95
website/doctype/blogger/blogger.txt
Normal 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"
|
||||||
|
}
|
||||||
|
]
|
@ -1,3 +1,7 @@
|
|||||||
|
{% if doc.at_import %}
|
||||||
|
{{ doc.at_import }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
{% if doc.background_image %}
|
{% if doc.background_image %}
|
||||||
background: url("../files/{{ doc.background_image }}") repeat;
|
background: url("../files/{{ doc.background_image }}") repeat;
|
||||||
@ -7,8 +11,8 @@ body {
|
|||||||
{% else %}
|
{% else %}
|
||||||
background-color: #edede7;
|
background-color: #edede7;
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if doc.font %}
|
{% if doc.font or doc.google_web_font_for_text %}
|
||||||
font-family: '{{ doc.font }}', Verdana, Sans !important;
|
font-family: '{{ doc.google_web_font_for_text or doc.font }}', Verdana, Sans !important;
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if doc.font_size %}
|
{% if doc.font_size %}
|
||||||
font-size: {{ doc.font_size }} !important;
|
font-size: {{ doc.font_size }} !important;
|
||||||
@ -21,8 +25,106 @@ body {
|
|||||||
}
|
}
|
||||||
{% endif %}
|
{% 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 {
|
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 %}
|
{% 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"}};
|
||||||
|
}
|
||||||
|
@ -18,5 +18,7 @@
|
|||||||
cur_frm.cscript.onload_post_render = function() {
|
cur_frm.cscript.onload_post_render = function() {
|
||||||
wn.require('lib/public/js/lib/jscolor/jscolor.js');
|
wn.require('lib/public/js/lib/jscolor/jscolor.js');
|
||||||
cur_frm.fields_dict.background_color.input.className = 'color';
|
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();
|
jscolor.bind();
|
||||||
}
|
}
|
@ -15,6 +15,8 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
from webnotes.utils import cint, cstr
|
||||||
|
|
||||||
class DocType:
|
class DocType:
|
||||||
def __init__(self, d, dl):
|
def __init__(self, d, dl):
|
||||||
self.doc, self.doclist = d, dl
|
self.doc, self.doclist = d, dl
|
||||||
@ -29,10 +31,7 @@ class DocType:
|
|||||||
'custom_template.css'), 'r') as f:
|
'custom_template.css'), 'r') as f:
|
||||||
temp = Template(f.read())
|
temp = Template(f.read())
|
||||||
|
|
||||||
if not self.doc.font_size:
|
self.prepare()
|
||||||
self.doc.font_size = '13px'
|
|
||||||
|
|
||||||
self.doc.small_font_size = str(int(self.doc.font_size[:-2])-2) + 'px'
|
|
||||||
|
|
||||||
self.doc.custom_css = temp.render(doc = self.doc)
|
self.doc.custom_css = temp.render(doc = self.doc)
|
||||||
if self.doc.add_css:
|
if self.doc.add_css:
|
||||||
@ -41,7 +40,36 @@ class DocType:
|
|||||||
from webnotes.sessions import clear_cache
|
from webnotes.sessions import clear_cache
|
||||||
clear_cache('Guest')
|
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):
|
def on_update(self):
|
||||||
"""rebuild pages"""
|
"""rebuild pages"""
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"creation": "2013-01-10 16:34:32",
|
"creation": "2013-01-25 11:35:10",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-01-22 14:57:25",
|
"modified": "2013-03-08 09:58:49",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -24,23 +24,26 @@
|
|||||||
"permlevel": 0
|
"permlevel": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"create": 1,
|
|
||||||
"doctype": "DocPerm",
|
"doctype": "DocPerm",
|
||||||
"name": "__common__",
|
"name": "__common__",
|
||||||
"parent": "Style Settings",
|
"parent": "Style Settings",
|
||||||
"parentfield": "permissions",
|
"parentfield": "permissions",
|
||||||
"parenttype": "DocType",
|
"parenttype": "DocType",
|
||||||
"permlevel": 0,
|
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 0,
|
||||||
"role": "Website Manager",
|
"role": "Website Manager",
|
||||||
"submit": 0,
|
"submit": 0
|
||||||
"write": 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"name": "Style Settings"
|
"name": "Style Settings"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "color",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Color"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"description": "If image is selected, color will be ignored (attach first)",
|
"description": "If image is selected, color will be ignored (attach first)",
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
@ -56,6 +59,18 @@
|
|||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Background Color"
|
"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",
|
"doctype": "DocField",
|
||||||
"fieldname": "cb0",
|
"fieldname": "cb0",
|
||||||
@ -63,26 +78,72 @@
|
|||||||
"print_width": "50%",
|
"print_width": "50%",
|
||||||
"width": "50%"
|
"width": "50%"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"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",
|
"doctype": "DocField",
|
||||||
"fieldname": "font",
|
"fieldname": "font",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "Font",
|
"label": "Font (Text)",
|
||||||
"options": "\nHelvetica Neue\nLucida Grande\nVerdana\nArial\nGeorgia\nTahoma"
|
"options": "\nHelvetica Neue\nLucida Grande\nVerdana\nArial\nGeorgia\nTahoma"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "font_size",
|
"fieldname": "font_size",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "Font Size",
|
"label": "Font Size (Text)",
|
||||||
"options": "\n12px\n13px\n14px\n15px\n16px"
|
"options": "\n12px\n13px\n14px\n15px\n16px"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "heading_font",
|
"fieldname": "heading_text_as",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "Heading Font",
|
"label": "Heading Text As",
|
||||||
"options": "\nHelvetica Neue\nLucida Grande\nVerdana\nArial\nGeorgia\nTahoma\nLato\nOpen Sans"
|
"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",
|
"doctype": "DocField",
|
||||||
@ -115,6 +176,16 @@
|
|||||||
"print_hide": 1
|
"print_hide": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocPerm"
|
"create": 1,
|
||||||
|
"doctype": "DocPerm",
|
||||||
|
"permlevel": 0,
|
||||||
|
"write": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"amend": 0,
|
||||||
|
"cancel": 0,
|
||||||
|
"create": 0,
|
||||||
|
"doctype": "DocPerm",
|
||||||
|
"permlevel": 1
|
||||||
}
|
}
|
||||||
]
|
]
|
@ -31,9 +31,6 @@ class DocType:
|
|||||||
from website.utils import clear_cache
|
from website.utils import clear_cache
|
||||||
clear_cache()
|
clear_cache()
|
||||||
|
|
||||||
from webnotes.sessions import clear_cache
|
|
||||||
clear_cache('Guest')
|
|
||||||
|
|
||||||
def set_home_page(self):
|
def set_home_page(self):
|
||||||
|
|
||||||
import webnotes
|
import webnotes
|
||||||
|
@ -4,40 +4,43 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import webnotes
|
import webnotes
|
||||||
import website.utils
|
import website.utils
|
||||||
|
from webnotes import _
|
||||||
|
|
||||||
@webnotes.whitelist(allow_guest=True)
|
@webnotes.whitelist(allow_guest=True)
|
||||||
def get_blog_list(args=None):
|
def get_blog_list(start=0, by=None, category=None):
|
||||||
"""
|
|
||||||
args = {
|
|
||||||
'start': 0,
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
import webnotes
|
import webnotes
|
||||||
|
condition = ""
|
||||||
if not args: args = webnotes.form_dict
|
if by:
|
||||||
|
condition = " and t1.blogger='%s'" % by.replace("'", "\'")
|
||||||
|
if category:
|
||||||
|
condition += " and t1.blog_category='%s'" % category.replace("'", "\'")
|
||||||
query = """\
|
query = """\
|
||||||
select
|
select
|
||||||
name, page_name, content, owner, creation as creation,
|
t1.title, t1.name, t1.page_name, t1.creation as creation,
|
||||||
title, (select count(name) from `tabComment` where
|
ifnull(t1.blog_intro, t1.content) as content,
|
||||||
comment_doctype='Blog' and comment_docname=`tabBlog`.name) as comments
|
t2.full_name, t2.avatar, t1.blogger,
|
||||||
from `tabBlog`
|
(select count(name) from `tabComment` where
|
||||||
where ifnull(published,0)=1
|
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
|
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
|
# strip html tags from content
|
||||||
import webnotes.utils
|
import webnotes.utils
|
||||||
|
|
||||||
for res in result:
|
for res in result:
|
||||||
from webnotes.utils import global_date_format, get_fullname
|
from webnotes.utils import global_date_format, get_fullname
|
||||||
res['full_name'] = get_fullname(res['owner'])
|
|
||||||
res['published'] = global_date_format(res['creation'])
|
res['published'] = global_date_format(res['creation'])
|
||||||
if not res['content']:
|
if not res['content']:
|
||||||
res['content'] = website.utils.get_html(res['page_name'])
|
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
|
return result
|
||||||
|
|
||||||
@ -116,9 +119,21 @@ def get_blog_content(blog_page_name):
|
|||||||
content = webnotes.utils.escape_html(content)
|
content = webnotes.utils.escape_html(content)
|
||||||
return content
|
return content
|
||||||
|
|
||||||
def split_blog_content(content):
|
def get_blog_template_args():
|
||||||
content = content.split("<!-- begin blog content -->")
|
return {
|
||||||
content = len(content) > 1 and content[1] or content[0]
|
"categories": webnotes.conn.sql_list("select name from `tabBlog Category` order by name")
|
||||||
content = content.split("<!-- end blog content -->")
|
}
|
||||||
content = content[0]
|
|
||||||
return content
|
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")
|
||||||
|
}
|
@ -11,11 +11,6 @@ wn.module_page["Website"] = [
|
|||||||
description: wn._("Content web page."),
|
description: wn._("Content web page."),
|
||||||
doctype:"Web Page"
|
doctype:"Web Page"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
label: wn._("Blog"),
|
|
||||||
description: wn._("Blog entry."),
|
|
||||||
doctype:"Blog"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: wn._("Website Slideshow"),
|
label: wn._("Website Slideshow"),
|
||||||
description: wn._("Embed image slideshows in website pages."),
|
description: wn._("Embed image slideshows in website pages."),
|
||||||
@ -23,6 +18,28 @@ wn.module_page["Website"] = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
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"),
|
title: wn._("Website Overall Settings"),
|
||||||
icon: "icon-wrench",
|
icon: "icon-wrench",
|
||||||
|
13
website/templates/html/blog_footer.html
Normal file
13
website/templates/html/blog_footer.html
Normal file
@ -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>
|
@ -13,41 +13,41 @@
|
|||||||
<h2>{{ title }}</h2>
|
<h2>{{ title }}</h2>
|
||||||
|
|
||||||
<!-- begin blog content -->
|
<!-- 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>
|
<br>
|
||||||
{{ content_html }}
|
{{ content_html }}
|
||||||
<!-- end blog content -->
|
<!-- end blog content -->
|
||||||
|
{% if blogger_info %}
|
||||||
|
<hr />
|
||||||
|
{% include "html/blogger.html" %}
|
||||||
|
{% endif %}
|
||||||
<hr>
|
<hr>
|
||||||
<h3>Comments</h3><br>
|
<h3>{{ texts.comments }}</h3><br>
|
||||||
<div class="blog-comments">
|
<div class="blog-comments">
|
||||||
|
|
||||||
{% if not comment_list %}
|
{% if not comment_list %}
|
||||||
<div class="alert no-comment">
|
<div class="no-comment">
|
||||||
<p>Be the first one to comment</p>
|
<p>{{ texts.first_comment }}</p>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% include 'html/comment.html' %}
|
{% include 'html/comment.html' %}
|
||||||
</div>
|
</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;"
|
<div style="display: none; margin-top: 10px;"
|
||||||
id="comment-form" class="well">
|
id="comment-form">
|
||||||
<div class="alert" style="display:none;"></div>
|
<div class="alert" style="display:none;"></div>
|
||||||
<form>
|
<form>
|
||||||
<p>
|
<fieldset>
|
||||||
<input name="comment_by_fullname" placeholder="Your Name" />
|
<input name="comment_by_fullname" placeholder="Your Name" type="text"/><br>
|
||||||
</p>
|
<input name="comment_by" placeholder="Your Email Id" type="text"/><br>
|
||||||
<p>
|
|
||||||
<input name="comment_by" placeholder="Your Email Id" />
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<textarea name="comment" placeholder="Comment" style="width: 300px; height: 120px;"/>
|
<textarea name="comment" placeholder="Comment" style="width: 300px; height: 120px;"/>
|
||||||
</textarea>
|
</textarea><br>
|
||||||
</p>
|
<button class="btn btn-info" id="submit-comment">{{ texts.submit }}</button>
|
||||||
<p>
|
</fieldset>
|
||||||
<button class="btn btn-info" id="submit-comment">Submit</button>
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% include 'html/blog_footer.html' %}
|
||||||
{% endblock %}
|
{% endblock %}
|
13
website/templates/html/blogger.html
Normal file
13
website/templates/html/blogger.html
Normal file
@ -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>
|
@ -6,7 +6,7 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="outer">
|
<div class="outer">
|
||||||
<div class="navbar{% if top_bar_background=="Black" %} navbar-inverse{% endif %}"
|
<div class="navbar{% if top_bar_background=="Black" %} navbar-inverse{% endif %}"
|
||||||
style="margin-bottom: 0px;">
|
style="">
|
||||||
<div class="navbar-inner">
|
<div class="navbar-inner">
|
||||||
<a class="brand" href="index">{{ brand_html }}</a>
|
<a class="brand" href="index">{{ brand_html }}</a>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
@ -23,6 +23,15 @@ $(document).ready(function() {
|
|||||||
$("#next-page").click(function() {
|
$("#next-page").click(function() {
|
||||||
blog.get_list();
|
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 = {
|
var blog = {
|
||||||
@ -33,10 +42,13 @@ var blog = {
|
|||||||
url: "server.py",
|
url: "server.py",
|
||||||
data: {
|
data: {
|
||||||
cmd: "website.helpers.blog.get_blog_list",
|
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",
|
dataType: "json",
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
|
if(data.exc) console.log(data.exc);
|
||||||
blog.render(data.message);
|
blog.render(data.message);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -53,11 +65,20 @@ var blog = {
|
|||||||
b.comment_text = b.comments + ' comments.'
|
b.comment_text = b.comments + ' comments.'
|
||||||
}
|
}
|
||||||
|
|
||||||
$(repl('<h2><a href="%(page_name)s">%(title)s</a></h2>\
|
$(repl('<div class="row">\
|
||||||
<div class="help">%(comment_text)s</div>\
|
<div class="span1">\
|
||||||
%(content)s<br />\
|
<div class="avatar avatar-medium" style="margin-top: 6px;">\
|
||||||
<p><a href="%(page_name)s">Read with comments...</a></p>\
|
<img src="%(avatar)s" />\
|
||||||
<hr /><br />', b)).appendTo($wrap);
|
</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);
|
blog.start += (data.length || 0);
|
||||||
if(!data.length) {
|
if(!data.length) {
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="span12">
|
<div class="span12">
|
||||||
<h1>Blog</h1>
|
<h2 id="blog-title">Blog</h2>
|
||||||
<br>
|
<br>
|
||||||
<div id="blog-list">
|
<div id="blog-list">
|
||||||
<!-- blog list will be generated dynamically -->
|
<!-- blog list will be generated dynamically -->
|
||||||
@ -22,4 +22,5 @@
|
|||||||
style="display:none;">More...</button>
|
style="display:none;">More...</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% include 'html/blog_footer.html' %}
|
||||||
{% endblock %}
|
{% endblock %}
|
14
website/templates/pages/writers.html
Normal file
14
website/templates/pages/writers.html
Normal file
@ -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 %}
|
@ -41,7 +41,9 @@ page_map = {
|
|||||||
|
|
||||||
page_settings_map = {
|
page_settings_map = {
|
||||||
"about": "About Us Settings",
|
"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):
|
def render(page_name):
|
||||||
@ -155,6 +157,10 @@ def prepare_args(page_name):
|
|||||||
'name': page_name,
|
'name': page_name,
|
||||||
})
|
})
|
||||||
if page_name in page_settings_map:
|
if page_name in page_settings_map:
|
||||||
|
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
|
args.obj = webnotes.bean(page_settings_map[page_name]).obj
|
||||||
else:
|
else:
|
||||||
args = get_doc_fields(page_name)
|
args = get_doc_fields(page_name)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user