Commit daf2b39c authored by Vincent Pelletier's avatar Vincent Pelletier

Add a local fork of Base_getFieldDescription because it's incompatible with the one in erp5_core.

ERP5XhtmlStyle_getFormGroupTitleAndId:
  compute all group titles & derivatives in one call and cache the whole result.
developper_shortcut_render:
  Tests of developper mode is not done in the macros any more, they must be done by the callers.
  Variable containing a reference to this page template must not be named "template" any longer, but developper_shortcut_render.
  A new variable is expected when translator mode macro is called, field_description - with a safe fallback if none is provided.
  "field" macro is splitted in 2 parts, "field_developper" ad "field_translator".
configure_list_dialog, sort_list_dialog, quad_form_view, form_render, form_dialog:
  Adapt to changes in developper mode macros.
form_render, form_dialog:
  Remove useless variables.
  Adapt to changes in ERP5XhtmlStyle_getFormGroupTitleAndId.
  Factorise page template gathering in the loop for "field_render".
form_dialog:
  Remove "clear" tag which is useless since commit #10683.
field_render:
  Adapt to changes in ERP5XhtmlStyle_getFormGroupTitleAndId.
  Factorise field attribute gathering.


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@10693 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 360e4151
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<tuple>
<tuple>
<string>Products.PythonScripts.PythonScript</string>
<string>PythonScript</string>
</tuple>
<none/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Python_magic</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>__ac_local_roles__</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>from Products.ERP5Type.Cache import CachingMethod\n
\n
field_id = field.getId()\n
\n
def getFieldDescription():\n
desc = field.get_value(\'description\')\n
if desc in (\'\', None):\n
id = field_id.split(\'_\', 1)\n
if id[0] == \'my\':\n
try:\n
properties = context.propertyMap()\n
except AttributeError: # If context has no propertyMap, give up\n
properties = []\n
for property in properties:\n
if id[1] == property[\'id\']:\n
return property.get(\'description\', \'\')\n
return desc\n
\n
getFieldDescription = CachingMethod(getFieldDescription, (\'getFieldDescription\', form_id, field_id), cache_duration=None)\n
\n
return getFieldDescription()\n
</string> </value>
</item>
<item>
<key> <string>_code</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_filepath</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>form_id, field</string> </value>
</item>
<item>
<key> <string>errors</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>func_code</string> </key>
<value>
<object>
<klass>
<global name="FuncCode" module="Shared.DC.Scripts.Signature"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>co_argcount</string> </key>
<value> <int>2</int> </value>
</item>
<item>
<key> <string>co_varnames</string> </key>
<value>
<tuple>
<string>form_id</string>
<string>field</string>
<string>Products.ERP5Type.Cache</string>
<string>CachingMethod</string>
<string>_getattr_</string>
<string>field_id</string>
<string>getFieldDescription</string>
<string>None</string>
</tuple>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>func_defaults</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Base_getFieldDescription</string> </value>
</item>
<item>
<key> <string>warnings</string> </key>
<value>
<tuple/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -91,40 +91,37 @@
, \'left webcontent (The Fantastic Group (and (funky) lisp-like parenthesis)) extra\'\n
)\n
"""\n
from Products.ERP5Type.Cache import CachingMethod\n
\n
if not same_type(original_group_id, \'string\'):\n
return None\n
def getFormGroupTitleAndId():\n
res = []\n
for original_group_id in form.get_groups(include_empty=0):\n
# Separate the group id and the group title using parenthesis as marker from the original form group id\n
o_gid_list = original_group_id.strip().split(\'(\')\n
# Get the first part of the group id (which is the part before the first opened parenthesis)\n
group_id = o_gid_list[0]\n
# Get the end of the list (which is the part just after the first opened parenthesis)\n
group_title_list = \'(\'.join(o_gid_list[1:]).split(\')\')\n
# Get the last part of the group id (the part which stand after the last closing parenthesis)\n
group_id += group_title_list[-1]\n
# Normalize the group id (suppress unecessary multiple-space)\n
group_id_list = []\n
for group_word in group_id.split(\' \'):\n
if len(group_word):\n
group_id_list.append(group_word)\n
group_id = \' \'.join(group_id_list)\n
# Generate the group title\n
group_title = \')\'.join(group_title_list[:-1]).strip()\n
# Return the group id if no title found\n
if len(group_title) == 0:\n
group_title = group_id\n
res.append({\'gid\': group_id, \'gtitle\': group_title, \'goid\': original_group_id})\n
return res\n
\n
# Separate the group id and the group title using parenthesis as marker from the original form group id\n
o_gid_list = original_group_id.strip().split(\'(\')\n
\n
# Get the first part of the group id (which is the part before the first opened parenthesis)\n
group_id = o_gid_list[0]\n
\n
# Get the end of the list (which is the part just after the first opened parenthesis)\n
group_title_list = \'(\'.join(o_gid_list[1:]).split(\')\')\n
\n
# Get the last part of the group id (the part which stand after the last closing parenthesis)\n
group_id += group_title_list[-1]\n
\n
# Normalize the group id (suppress unecessary multiple-space)\n
group_id_list = []\n
for group_word in group_id.split(\' \'):\n
if len(group_word):\n
group_id_list.append(group_word)\n
group_id = \' \'.join(group_id_list)\n
\n
# Generate the group title\n
group_title = \')\'.join(group_title_list[:-1]).strip()\n
\n
# Return the group id if no title found\n
if len(group_title) == 0:\n
group_title = group_id\n
\n
return ( group_id\n
, group_title\n
, original_group_id\n
)\n
getFormGroupTitleAndId = CachingMethod(getFormGroupTitleAndId,\n
("ERP5XhtmlStyle_getFormGroupTitleAndId", form.id),\n
cache_duration=None)\n
return getFormGroupTitleAndId()\n
</string> </value>
</item>
<item>
......@@ -141,7 +138,7 @@ return ( group_id\n
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>original_group_id=None</string> </value>
<value> <string>form</string> </value>
</item>
<item>
<key> <string>errors</string> </key>
......@@ -167,19 +164,12 @@ return ( group_id\n
<key> <string>co_varnames</string> </key>
<value>
<tuple>
<string>original_group_id</string>
<string>same_type</string>
<string>None</string>
<string>form</string>
<string>Products.ERP5Type.Cache</string>
<string>CachingMethod</string>
<string>getFormGroupTitleAndId</string>
<string>_getattr_</string>
<string>o_gid_list</string>
<string>_getitem_</string>
<string>group_id</string>
<string>group_title_list</string>
<string>group_id_list</string>
<string>_getiter_</string>
<string>group_word</string>
<string>len</string>
<string>group_title</string>
<string>None</string>
</tuple>
</value>
</item>
......@@ -191,9 +181,7 @@ return ( group_id\n
<item>
<key> <string>func_defaults</string> </key>
<value>
<tuple>
<none/>
</tuple>
<none/>
</value>
</item>
<item>
......
......@@ -78,8 +78,8 @@ XXX: uses hardcoded indices values to access fields\n
<tal:block metal:use-macro="here/dialog_main/macros/master">\n
<tal:block metal:fill-slot="main">\n
<div class="dialog_box">\n
<tal:block tal:define="template python: here.developper_shortcut_render">\n
<tal:block metal:use-macro="template/macros/form" />\n
<tal:block tal:condition="preferred_html_style_developper_mode">\n
<tal:block metal:use-macro="developper_shortcut_render/macros/form"/>\n
</tal:block>\n
<table tal:define="selection_name request/selection_name;\n
base_form python: getattr(here, request[\'form_id\']);\n
......
......@@ -75,56 +75,55 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n
\n
\n
<tal:block metal:define-macro="edit_link">\n
<a tal:condition="python: preferred_html_style_developper_mode and hasattr(object, \'meta_type\')"\n
tal:attributes="href python: \'%s/%s\' % (\'/\'.join(object.getPhysicalPath()[len(object.getPortalObject().getPhysicalPath()):]), manage) # XXX: quick hack to get path;\n
<a tal:condition="python: hasattr(object, \'meta_type\')"\n
tal:attributes="href python: \'%s/manage_main\' % (\'/\'.join(object.getPhysicalPath()[len(object.getPortalObject().getPhysicalPath()):])) # XXX: quick hack to get path;\n
title info;"><img tal:attributes="src python: \'%s/images/%s\' % (portal_path, image);\n
alt info;"/></a>\n
</tal:block>\n
\n
\n
<tal:block metal:define-macro="translate_link">\n
<tal:block tal:condition="preferred_html_style_translator_mode">\n
<a tal:define="image image | python: \'translate.png\'"\n
tal:attributes="href python: \'%s/manage_messages?regex=^%s%%24&amp;lang=%s\' % (\'/\'.join(here.Localizer.erp5_ui.getPhysicalPath()[len(here.Localizer.erp5_ui.getPortalObject().getPhysicalPath()):]), message, selected_language);\n
title info;"><img tal:attributes="src python: \'%s/images/%s\' % (portal_path, image);\n
alt info;"/></a>\n
</tal:block>\n
<a tal:define="image image | python: \'translate.png\'"\n
tal:attributes="href python: \'%s/manage_messages?regex=^%s%%24&amp;lang=%s\' % (\'/\'.join(here.Localizer.erp5_ui.getPhysicalPath()[len(here.Localizer.erp5_ui.getPortalObject().getPhysicalPath()):]), message, selected_language);\n
title info;"><img tal:attributes="src python: \'%s/images/%s\' % (portal_path, image);\n
alt info;"/></a>\n
</tal:block>\n
\n
\n
<tal:block metal:define-macro="form" tal:condition="not: is_web_mode | nothing">\n
<tal:block metal:define-macro="form">\n
<tal:block tal:define="image python: \'editform.png\';\n
info python: \'Edit this form\';\n
object python: form;\n
manage python: \'manage\'">\n
<tal:block metal:use-macro="template/macros/edit_link"/>\n
object nocall: form;">\n
<tal:block metal:use-macro="developper_shortcut_render/macros/edit_link"/>\n
</tal:block>\n
<tal:block tal:define="image python: \'editformaction.png\';\n
info python: \'Edit this form\\\'s action\';\n
object python: getattr(here, form.action, None);\n
manage python: \'manage_main\'">\n
<tal:block metal:use-macro="template/macros/edit_link"/>\n
object python: getattr(here, form.action, None);">\n
<tal:block metal:use-macro="developper_shortcut_render/macros/edit_link"/>\n
</tal:block>\n
</tal:block>\n
\n
\n
<tal:block metal:define-macro="field" tal:condition="not: is_web_mode | nothing">\n
<tal:block metal:define-macro="field_developper">\n
<tal:block tal:define="image python: \'editfield.png\';\n
info python: \'Edit this field\';\n
object python: field;\n
manage python: \'manage_main\'">\n
<tal:block metal:use-macro="template/macros/edit_link"/>\n
object nocall: field;">\n
<tal:block metal:use-macro="developper_shortcut_render/macros/edit_link"/>\n
</tal:block>\n
</tal:block>\n
<tal:block metal:define-macro="field_translator">\n
<tal:block tal:define="info python: \'Translate this field title\';\n
message python: field[\'title\'];\n
image python: \'translate.png\'">\n
<tal:block metal:use-macro="template/macros/translate_link"/>\n
<tal:block metal:use-macro="developper_shortcut_render/macros/translate_link"/>\n
</tal:block>\n
<tal:block tal:define="message python: here.Base_getFieldDescription(field);\n
info python: \'Translate this field description\';\n
image python: \'translate_tooltip.png\'"\n
tal:condition="python: message not in (None, \'\')">\n
<tal:block metal:use-macro="template/macros/translate_link"/>\n
<tal:block tal:condition="field_description | nothing">\n
<tal:block tal:define="message field_description;\n
info python: \'Translate this field description\';\n
image python: \'translate_tooltip.png\'"\n
tal:condition="python: message not in (None, \'\')">\n
<tal:block metal:use-macro="developper_shortcut_render/macros/translate_link"/>\n
</tal:block>\n
</tal:block>\n
</tal:block>
......
......@@ -74,25 +74,34 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n
\n
<tal:block metal:define-macro="field_render">\n
<tal:block tal:condition="python: field.meta_type != \'HiddenStringField\'"\n
tal:define="value python: request.get(field.id, None);\n
tal:define="field_id field/id;\n
value python: request.get(field_id, None);\n
field_errors python: request.get(\'field_errors\', {});\n
html_render python: field.render_htmlgrid(value, request)">\n
<div tal:repeat="html_tuple html_render"\n
tal:attributes="title python: here.Localizer.translate(\'erp5_ui\', here.Base_getFieldDescription(field));\n
class python: \' \'.join([x for x in [\'field\', field.is_required() and \'required\' or None, field_errors.has_key(field.id) and \'error\' or None, field.get_value(\'css_class\') or None] if x is not None])">\n
<label>\n
<tal:block tal:content="structure python: html_tuple[0]"\n
i18n:translate="" i18n:domain="ui"/>\n
<tal:block tal:define="template python: here.developper_shortcut_render">\n
<tal:block metal:use-macro="template/macros/field"/>\n
</tal:block>\n
</label>\n
<div class="input" tal:content="structure python: html_tuple[1]"/>\n
<span tal:condition="python: field_errors.has_key(field.id)"\n
class="error"\n
tal:content="python: field_errors[field.id].error_text"\n
i18n:translate="" i18n:domain="ui"/>\n
<p class="clear"></p>\n
field_has_error python: field_errors.has_key(field_id);\n
global form_id form_id | python: form.id;\n
field_description python: here.Base_getFieldDescription(form_id=form_id, field=field)">\n
<div tal:define="html_render python: field.render_htmlgrid(value, request)"\n
tal:attributes="title field_description;\n
class python: \' \'.join([x for x in [\'field\', field.is_required() and \'required\' or None, field_has_error and \'error\' or None, field.get_value(\'css_class\') or None] if x is not None])"\n
i18n:attributes="title" i18n:domain="ui">\n
<tal:block tal:repeat="html_tuple html_render">\n
<label>\n
<tal:block tal:content="structure python: html_tuple[0]"\n
i18n:translate="" i18n:domain="ui"/>\n
<tal:block tal:condition="preferred_html_style_developper_mode">\n
<tal:block metal:use-macro="developper_shortcut_render/macros/field_developper"/>\n
</tal:block>\n
<tal:block tal:condition="preferred_html_style_translator_mode">\n
<tal:block metal:use-macro="developper_shortcut_render/macros/field_translator"/>\n
</tal:block>\n
</label>\n
<div class="input" tal:content="structure python: html_tuple[1]"/>\n
<span tal:condition="python: field_has_error"\n
class="error"\n
tal:content="python: field_errors[field_id].error_text"\n
i18n:translate="" i18n:domain="ui"/>\n
<p class="clear"></p>\n
</tal:block>\n
</div>\n
</tal:block>\n
</tal:block>
......
......@@ -80,9 +80,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n
left_group python: form.get_fields_in_group(\'left\');\n
right_group python: form.get_fields_in_group(\'right\');\n
center_group python: form.get_fields_in_group(\'center\');\n
dialog_actions python: actions.get(dialog_category, [])">\n
<tal:block tal:define="template python: here.developper_shortcut_render">\n
<tal:block metal:use-macro="template/macros/form" />\n
dialog_actions python: actions.get(dialog_category, []);\n
field_render here/field_render/macros/field_render">\n
<tal:block tal:condition="preferred_html_style_developper_mode">\n
<tal:block metal:use-macro="developper_shortcut_render/macros/form" />\n
</tal:block>\n
<div tal:condition="python: len(left_group) or len(right_group) or len(center_group) or len(dialog_actions)>1"\n
class="dialog_box">\n
......@@ -111,22 +112,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n
</button>\n
</div>\n
<div class="content"\n
tal:define="group_list python: [];\n
dummy python: group_list.extend([here.ERP5XhtmlStyle_getFormGroupTitleAndId(x) for x in form.get_groups(include_empty=0) if x != \'bottom\']);\n
gid_list python: \' \'.join([x[0] for x in group_list]);">\n
tal:define="group_list python: here.ERP5XhtmlStyle_getFormGroupTitleAndId(form);\n
gid_list python: \' \'.join([x[\'gid\'] for x in group_list if x not in (\'bottom\', \'hidden\')]);">\n
<tal:block tal:repeat="group group_list">\n
<tal:block tal:define="gid python: group[0];\n
gtitle python: group[1];\n
goid python: group[2];">\n
<fieldset tal:condition="python: gid.find(\'hidden\') < 0"\n
tal:attributes="class python: gid;\n
id python: \'fieldset_\' + gid.replace(\' \', \'_\');">\n
<legend tal:content="python: gtitle" class="group_title"/>\n
<tal:block tal:repeat="field python: form.get_fields_in_group(goid)">\n
<tal:block metal:use-macro="here/field_render/macros/field_render"/>\n
<tal:block tal:define="gid group/gid">\n
<fieldset tal:condition="python: \'hidden\' not in gid and \'bottom\' not in gid"\n
tal:attributes="class gid;\n
id python: \'fieldset_\' + gid.replace(\' \', \'_\');">\n
<legend tal:content="group/gtitle" class="group_title"/>\n
<tal:block tal:repeat="field python: form.get_fields_in_group(group[\'goid\'])">\n
<tal:block metal:use-macro="field_render"/>\n
</tal:block>\n
</fieldset>\n
<p tal:condition="python: gid.find(\'right\') >= 0 or (gid.find(\'left\') >= 0 and \'right\' not in gid_list)" class="clear"/>\n
</tal:block>\n
</tal:block>\n
<p class="clear"></p>\n
......@@ -139,13 +136,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n
dummy python: request.set(\'here\', here);\n
bottom_group python: form.get_fields_in_group(\'bottom\')">\n
<div tal:condition="python: len(bottom_group) > 0"\n
class="bottom">\n
class="bottom">\n
<tal:block tal:repeat="field bottom_group">\n
<tal:block tal:define="template python: here.developper_shortcut_render">\n
<tal:block metal:use-macro="template/macros/field" />\n
<tal:block tal:condition="preferred_html_style_developper_mode">\n
<tal:block metal:use-macro="developper_shortcut_render/macros/field_developper"/>\n
</tal:block>\n
<tal:block tal:define="field_description python: here.Base_getFieldDescription(form_id=form.id, field=field)"\n
tal:condition="preferred_html_style_translator_mode">\n
<tal:block metal:use-macro="developper_shortcut_render/macros/field_translator"/>\n
</tal:block>\n
<tal:block tal:define="value python:request.get(field.id, None)"\n
tal:replace="structure python:field.render(value, request)" />\n
tal:replace="structure python:field.render(value, request)" />\n
</tal:block>\n
</div>\n
</tal:block>\n
......
......@@ -105,29 +105,27 @@ It is possible to specify a group id and a group title by naming a group followi
<tal:block\n
tal:define="field_errors python: request.get(\'field_errors\', {});\n
dummy python: request.set(\'here\', here);\n
group_list python: [];\n
dummy python: group_list.extend([here.ERP5XhtmlStyle_getFormGroupTitleAndId(x) for x in form.get_groups(include_empty=0)]);\n
gid_list python: \' \'.join([x[0] for x in group_list]);">\n
group_list python: here.ERP5XhtmlStyle_getFormGroupTitleAndId(form);\n
gid_list python: \' \'.join([x[\'gid\'] for x in group_list if x!=\'hidden\']);\n
field_render nocall: here/field_render/macros/field_render">\n
\n
<tal:block tal:define="template python: here.developper_shortcut_render">\n
<tal:block metal:use-macro="template/macros/form"/>\n
<tal:block tal:condition="preferred_html_style_developper_mode">\n
<tal:block metal:use-macro="developper_shortcut_render/macros/form"/>\n
</tal:block>\n
\n
<tal:block tal:repeat="group group_list">\n
<tal:block tal:define="gid python: group[0];\n
gtitle python: group[1];\n
goid python: group[2];">\n
<tal:block tal:define="gid group/gid;">\n
<fieldset tal:condition="python: gid.find(\'hidden\') < 0"\n
tal:attributes="class python: gid;\n
id python: \'fieldset_\' + gid.replace(\' \', \'_\');">\n
<legend tal:content="python: gtitle" class="group_title"/>\n
<tal:block tal:repeat="field python: form.get_fields_in_group(goid)">\n
<tal:block metal:use-macro="here/field_render/macros/field_render"/>\n
tal:attributes="class gid;\n
id python: \'fieldset_%s\' % (gid.replace(\' \', \'_\'), );">\n
<legend tal:content="group/gtitle" class="group_title"/>\n
<tal:block tal:repeat="field python: form.get_fields_in_group(group[\'goid\'])">\n
<tal:block metal:use-macro="field_render"/>\n
</tal:block>\n
</fieldset>\n
</tal:block>\n
</tal:block>\n
\n
<p class="clear"></p>\n
</tal:block>\n
</tal:block>
......
......@@ -82,8 +82,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n
center_right_group python: form.get_fields_in_group(\'center_right\');\n
bottom_group python: form.get_fields_in_group(\'bottom\');\n
field_render nocall: here/field_render/macros/field_render">\n
<tal:block tal:define="template python: here.developper_shortcut_render">\n
<tal:block metal:use-macro="template/macros/form" />\n
<tal:block tal:condition="preferred_html_style_developper_mode">\n
<tal:block metal:use-macro="developper_shortcut_render/macros/form" />\n
</tal:block>\n
<div tal:condition="python: len(left_group) > 0 or len(right_group) > 0"\n
class="top_group">\n
......
......@@ -76,8 +76,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n
<tal:block metal:use-macro="here/dialog_main/macros/master">\n
<tal:block metal:fill-slot="main">\n
<div class="dialog_box">\n
<tal:block tal:define="template python: here.developper_shortcut_render">\n
<tal:block metal:use-macro="template/macros/form" />\n
<tal:block tal:condition="preferred_html_style_developper_mode">\n
<tal:block metal:use-macro="developper_shortcut_render/macros/form"/>\n
</tal:block>\n
<div class="content"\n
tal:define="items python:here.portal_selections.getSelectionSortOrder(request[\'selection_name\'], REQUEST=request);\n
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment