Commit 93db5acc by Calen Pennington

Make display_name defaulting explicit

parent e4dea025
......@@ -135,7 +135,7 @@ def index(request):
return render_to_response('index.html', {
'new_course_template': Location('i4x', 'edx', 'templates', 'course', 'Empty'),
'courses': [(course.lms.display_name,
'courses': [(course.display_name,
reverse('course_index', args=[
course.location.org,
course.location.course,
......@@ -319,7 +319,7 @@ def edit_unit(request, location):
if category in component_types:
#This is a hack to create categories for different xmodules
component_templates[category].append((
template.lms.display_name,
template.display_name_with_default,
template.location.url(),
hasattr(template, 'markdown') and template.markdown != '',
template.cms.empty,
......@@ -534,7 +534,7 @@ def get_preview_module(request, preview_id, descriptor):
preview_id (str): An identifier specifying which preview this module is used for
location: A Location
"""
return load_preview_module(request, preview_id, descriptor)
......@@ -757,7 +757,7 @@ def clone_item(request):
# replace the display name with an optional parameter passed in from the caller
if display_name is not None:
new_item.lms.display_name = display_name
new_item.display_name = display_name
get_modulestore(template).update_metadata(new_item.location.url(), own_metadata(new_item))
......@@ -978,7 +978,7 @@ def reorder_static_tabs(request):
for tab in course.tabs:
if tab['type'] == 'static_tab':
reordered_tabs.append({'type': 'static_tab',
'name': tab_items[static_tab_idx].lms.display_name,
'name': tab_items[static_tab_idx].display_name,
'url_slug': tab_items[static_tab_idx].location.name})
static_tab_idx += 1
else:
......
......@@ -6,10 +6,10 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>
<%block name="title"></%block> |
<%block name="title"></%block> |
% if context_course:
<% ctx_loc = context_course.location %>
${context_course.display_name} |
${context_course.display_name_with_default} |
% endif
edX Studio
</title>
......@@ -22,7 +22,7 @@
<link rel="stylesheet" type="text/css" href="${static.url('js/vendor/markitup/sets/wiki/style.css')}" />
<link rel="stylesheet" type="text/css" href="${static.url('css/vendor/symbolset.ss-symbolicons-block.css')}" />
<link rel="stylesheet" type="text/css" href="${static.url('css/vendor/symbolset.ss-standard.css')}" />
<%block name="header_extras"></%block>
</head>
......
......@@ -22,7 +22,7 @@
<article class="subsection-body window" data-id="${subsection.location}">
<div class="subsection-name-input">
<label>Display Name:</label>
<input type="text" value="${subsection.lms.display_name | h}" class="subsection-display-name-input" data-metadata-name="display_name"/>
<input type="text" value="${subsection.display_name_with_default | h}" class="subsection-display-name-input" data-metadata-name="display_name"/>
</div>
<div class="sortable-unit-list">
<label>Units:</label>
......@@ -59,11 +59,11 @@
</div>
% if subsection.lms.start != parent_item.lms.start and subsection.lms.start:
% if parent_start_date is None:
<p class="notice">The date above differs from the release date of ${parent_item.lms.display_name}, which is unset.
<p class="notice">The date above differs from the release date of ${parent_item.display_name_with_default}, which is unset.
% else:
<p class="notice">The date above differs from the release date of ${parent_item.lms.display_name} – ${parent_start_date.strftime('%m/%d/%Y')} at ${parent_start_date.strftime('%H:%M')}.
<p class="notice">The date above differs from the release date of ${parent_item.display_name_with_default} – ${parent_start_date.strftime('%m/%d/%Y')} at ${parent_start_date.strftime('%H:%M')}.
% endif
<a href="#" class="sync-date no-spinner">Sync to ${parent_item.lms.display_name}.</a></p>
<a href="#" class="sync-date no-spinner">Sync to ${parent_item.display_name_with_default}.</a></p>
% endif
</div>
......
......@@ -8,7 +8,7 @@
<div>${module_type}</div>
<div>
% for template in module_templates:
<a class="save" data-template-id="${template.location.url()}">${template.lms.display_name}</a>
<a class="save" data-template-id="${template.location.url()}">${template.display_name_with_default}</a>
% endfor
</div>
</div>
......
......@@ -154,9 +154,9 @@
<div class="item-details" data-id="${section.location}">
<h3 class="section-name">
<span data-tooltip="Edit this section's name" class="section-name-span">${section.lms.display_name}</span>
<span data-tooltip="Edit this section's name" class="section-name-span">${section.display_name_with_default}</span>
<form class="section-name-edit" style="display:none">
<input type="text" value="${section.lms.display_name | h}" class="edit-section-name" autocomplete="off"/>
<input type="text" value="${section.display_name_with_default | h}" class="edit-section-name" autocomplete="off"/>
<input type="submit" class="save-button edit-section-name-save" value="Save" />
<input type="button" class="cancel-button edit-section-name-cancel" value="Cancel" />
</form>
......@@ -196,7 +196,7 @@
<a href="#" data-tooltip="Expand/collapse this subsection" class="expand-collapse-icon expand"></a>
<a href="${reverse('edit_subsection', args=[subsection.location])}">
<span class="folder-icon"></span>
<span class="subsection-name"><span class="subsection-name-value">${subsection.lms.display_name}</span></span>
<span class="subsection-name"><span class="subsection-name-value">${subsection.display_name_with_default}</span></span>
</a>
</div>
......
......@@ -44,7 +44,7 @@
</div>
<div class="main-column">
<article class="unit-body window">
<p class="unit-name-input"><label>Display Name:</label><input type="text" value="${unit.lms.display_name | h}" class="unit-display-name-input" /></p>
<p class="unit-name-input"><label>Display Name:</label><input type="text" value="${unit.display_name_with_default | h}" class="unit-display-name-input" /></p>
<ol class="components">
% for id in components:
<li class="component" data-id="${id}"/>
......@@ -153,7 +153,7 @@
% if release_date is not None:
on <strong>${release_date}</strong>
% endif
with the subsection <a href="${reverse('edit_subsection', kwargs={'location': subsection.location})}">"${subsection.lms.display_name}"</a></p>
with the subsection <a href="${reverse('edit_subsection', kwargs={'location': subsection.location})}">"${subsection.display_name_with_default}"</a></p>
</div>
<div class="row unit-actions">
<a href="#" class="delete-draft delete-button">Delete Draft</a>
......@@ -168,12 +168,12 @@
<div><input type="text" class="url" value="/courseware/${section.url_name}/${subsection.url_name}" disabled /></div>
<ol>
<li>
<a href="#" class="section-item">${section.lms.display_name}</a>
<a href="#" class="section-item">${section.display_name_with_default}</a>
<ol>
<li>
<a href="${reverse('edit_subsection', args=[subsection.location])}" class="section-item">
<span class="folder-icon"></span>
<span class="subsection-name"><span class="subsection-name-value">${subsection.lms.display_name}</span></span>
<span class="subsection-name"><span class="subsection-name-value">${subsection.display_name_with_default}</span></span>
</a>
${units.enum_units(subsection, actions=False, selected=unit.location)}
</li>
......
......@@ -12,12 +12,12 @@
<h2 class="sr">Current Course:</h2>
<a href="${reverse('course_index', kwargs=dict(org=ctx_loc.org, course=ctx_loc.course, name=ctx_loc.name))}">
<span class="course-org">${ctx_loc.org}</span><span class="course-number">${ctx_loc.course}</span>
<span class="course-title" title="${context_course.lms.display_name}">${context_course.lms.display_name}</span>
<span class="course-title" title="${context_course.display_name_with_default}">${context_course.display_name_with_default}</span>
</a>
</div>
<nav class="nav-course primary nav-dropdown" role="navigation">
<h2 class="sr">${context_course.lms.display_name}'s Navigation:</h2>
<h2 class="sr">${context_course.display_name_with_default}'s Navigation:</h2>
<ol>
<li class="nav-item nav-course-courseware">
......
......@@ -40,7 +40,7 @@
<a href="#" class="module-edit"
data-id="${child.location.url()}"
data-type="${child.js_module_name}"
data-preview-type="${child.module_class.js_module_name}">${child.lms.display_name}</a>
data-preview-type="${child.module_class.js_module_name}">${child.display_name_with_default}</a>
<a href="#" class="draggable">handle</a>
</li>
%endfor
......
......@@ -22,7 +22,7 @@ This def will enumerate through a passed in subsection and list all of the units
<div class="section-item ${selected_class}">
<a href="${reverse('edit_unit', args=[unit.location])}" class="${unit_state}-item">
<span class="${unit.category}-icon"></span>
<span class="unit-name">${unit.lms.display_name}</span>
<span class="unit-name">${unit.display_name_with_default}</span>
</a>
% if actions:
<div class="item-actions">
......@@ -39,7 +39,7 @@ This def will enumerate through a passed in subsection and list all of the units
</a>
</li>
</ol>
</%def>
</%def>
......@@ -317,7 +317,7 @@ def change_enrollment(request):
if not has_access(user, course, 'enroll'):
return {'success': False,
'error': 'enrollment in {} not allowed at this time'
.format(course.lms.display_name)}
.format(course.display_name_with_default)}
org, course_num, run = course_id.split("/")
statsd.increment("common.student.enrollment",
......
......@@ -82,7 +82,7 @@ class XModuleCourseFactory(Factory):
# This metadata code was copied from cms/djangoapps/contentstore/views.py
if display_name is not None:
new_course.lms.display_name = display_name
new_course.display_name = display_name
new_course.data_dir = uuid4().hex
new_course.lms.start = gmtime()
......@@ -145,7 +145,7 @@ class XModuleItemFactory(Factory):
# replace the display name with an optional parameter passed in from the caller
if display_name is not None:
new_item.lms.display_name = display_name
new_item.display_name = display_name
store.update_metadata(new_item.location.url(), new_item.own_metadata)
......
......@@ -33,7 +33,7 @@ def wrap_xmodule(get_html, module, template, context=None):
def _get_html():
context.update({
'content': get_html(),
'display_name': module.lms.display_name,
'display_name': module.display_name,
'class_': module.__class__.__name__,
'module_name': module.js_module_name
})
......
......@@ -103,7 +103,7 @@ class AnnotatableModule(XModule):
def get_html(self):
""" Renders parameters to template. """
context = {
'display_name': self.display_name,
'display_name': self.display_name_with_default,
'element_id': self.element_id,
'instructions_html': self.instructions,
'content_html': self._render_content()
......
......@@ -367,7 +367,7 @@ class CapaModule(XModule):
else:
check_button = False
content = {'name': self.display_name,
content = {'name': self.display_name_with_default,
'html': html,
'weight': self.descriptor.weight,
}
......
......@@ -497,7 +497,7 @@ class MongoModuleStore(ModuleStoreBase):
existing_tabs = course.tabs or []
existing_tabs.append({
'type': 'static_tab',
'name': item.lms.display_name,
'name': item.display_name,
'url_slug': item.location.name
})
course.tabs = existing_tabs
......
......@@ -41,7 +41,7 @@ class XModuleCourseFactory(Factory):
# This metadata code was copied from cms/djangoapps/contentstore/views.py
if display_name is not None:
new_course.lms.display_name = display_name
new_course.display_name = display_name
new_course.start = gmtime()
......@@ -101,7 +101,7 @@ class XModuleItemFactory(Factory):
# replace the display name with an optional parameter passed in from the caller
if display_name is not None:
new_item.lms.display_name = display_name
new_item.display_name = display_name
store.update_metadata(new_item.location.url(), own_metadata(new_item))
......
......@@ -473,7 +473,7 @@ class XMLModuleStore(ModuleStoreBase):
if category == "static_tab":
for tab in course_descriptor.tabs or []:
if tab.get('url_slug') == slug:
module.lms.display_name = tab['name']
module.display_name = tab['name']
module.data_dir = course_dir
self.modules[course_descriptor.id][module.location] = module
except Exception, e:
......
......@@ -18,14 +18,6 @@ log = logging.getLogger(__name__)
class_priority = ['video', 'problem']
def display_name(module):
if hasattr(module, 'display_name'):
return module.display_name
if hasattr(module, 'lms'):
return module.lms.display_name
class SequenceModule(XModule):
''' Layout module which lays out content in a temporal sequence
'''
......@@ -89,9 +81,9 @@ class SequenceModule(XModule):
childinfo = {
'content': child.get_html(),
'title': "\n".join(
display_name(grand_child)
grand_child.display_name
for grand_child in child.get_children()
if display_name(grand_child)
if grand_child.display_name is not None
),
'progress_status': Progress.to_js_status_str(progress),
'progress_detail': Progress.to_js_detail_str(progress),
......@@ -99,7 +91,7 @@ class SequenceModule(XModule):
'id': child.id,
}
if childinfo['title'] == '':
childinfo['title'] = display_name(child)
childinfo['title'] = child.display_name_with_default
contents.append(childinfo)
params = {'items': contents,
......
......@@ -243,8 +243,8 @@ class ImportTestCase(BaseCourseTestCase):
toy_ch = toy.get_children()[0]
two_toys_ch = two_toys.get_children()[0]
self.assertEqual(toy_ch.lms.display_name, "Overview")
self.assertEqual(two_toys_ch.lms.display_name, "Two Toy Overview")
self.assertEqual(toy_ch.display_name, "Overview")
self.assertEqual(two_toys_ch.display_name, "Two Toy Overview")
# Also check that the grading policy loaded
self.assertEqual(two_toys.grade_cutoffs['C'], 0.5999)
......@@ -303,7 +303,7 @@ class ImportTestCase(BaseCourseTestCase):
cloc = course.location
loc = Location(cloc.tag, cloc.org, cloc.course, 'html', 'secret:toylab')
html = modulestore.get_instance(course_id, loc)
self.assertEquals(html.lms.display_name, "Toy lab")
self.assertEquals(html.display_name, "Toy lab")
def test_url_name_mangling(self):
"""
......
......@@ -142,7 +142,7 @@ class VideoModule(XModule):
'position': self.position,
'source': self.source,
'track': self.track,
'display_name': self.display_name,
'display_name': self.display_name_with_default,
'caption_asset_path': caption_asset_path,
'show_captions': self.show_captions,
'start': self.start_time,
......
......@@ -137,7 +137,7 @@ class VideoAlphaModule(XModule):
'sub': self.sub,
'sources': self.sources,
'track': self.track,
'display_name': self.display_name,
'display_name': self.display_name_with_default,
# TODO (cpennington): This won't work when we move to data that isn't on the filesystem
'data_dir': getattr(self, 'data_dir', None),
'caption_asset_path': caption_asset_path,
......
......@@ -9,7 +9,7 @@ from pkg_resources import resource_listdir, resource_string, resource_isdir
from xmodule.modulestore import Location
from xmodule.modulestore.exceptions import ItemNotFoundError
from xblock.core import XBlock
from xblock.core import XBlock, Scope, String
log = logging.getLogger(__name__)
......@@ -99,6 +99,12 @@ class XModule(HTMLSnippet, XBlock):
# in the module
icon_class = 'other'
display_name = String(
help="Display name for this module",
scope=Scope.settings,
default=None,
)
def __init__(self, system, location, descriptor, model_data):
'''
Construct a new xmodule
......@@ -123,6 +129,17 @@ class XModule(HTMLSnippet, XBlock):
self._model_data = model_data
self._loaded_children = None
@property
def display_name_with_default(self):
'''
Return a display name for the module: use display_name if defined in
metadata, otherwise convert the url name.
'''
name = self.display_name
if name is None:
name = self.url_name.replace('_', ' ')
return name
def get_children(self):
'''
Return module instances for all the children of this module.
......@@ -335,6 +352,12 @@ class XModuleDescriptor(HTMLSnippet, ResourceTemplates, XBlock):
FoldIt, which posts grade-changing updates through a separate API.
"""
display_name = String(
help="Display name for this module",
scope=Scope.settings,
default=None,
)
# ============================= STRUCTURAL MANIPULATION ===================
def __init__(self,
system,
......@@ -365,6 +388,17 @@ class XModuleDescriptor(HTMLSnippet, ResourceTemplates, XBlock):
self._child_instances = None
@property
def display_name_with_default(self):
'''
Return a display name for the module: use display_name if defined in
metadata, otherwise convert the url name.
'''
name = self.display_name
if name is None:
name = self.url_name.replace('_', ' ')
return name
def get_required_module_descriptors(self):
"""Returns a list of XModuleDescritpor instances upon which this module depends, but are
not children of this module"""
......
......@@ -95,7 +95,7 @@ def course_wiki_redirect(request, course_id):
root,
course_slug,
title=course_slug,
content="This is the wiki for **{0}**'s _{1}_.".format(course.org, course.lms.display_name),
content="This is the wiki for **{0}**'s _{1}_.".format(course.org, course.display_name_with_default),
user_message="Course page automatically created.",
user=None,
ip_address=None,
......
......@@ -178,9 +178,7 @@ def get_course_about_section(course, section_key):
key=section_key, url=course.location.url()))
return None
elif section_key == "title":
if course.display_name is None:
return course.url_name
return course.display_name
return course.display_name_with_default
elif section_key == "university":
return course.location.org
elif section_key == "number":
......
......@@ -81,8 +81,8 @@ def get_courseware_with_tabs(course_id):
course = get_course_by_id(course_id)
chapters = [chapter for chapter in course.get_children() if not chapter.lms.hide_from_toc]
courseware = [{'chapter_name': c.display_name,
'sections': [{'section_name': s.display_name,
courseware = [{'chapter_name': c.display_name_with_default,
'sections': [{'section_name': s.display_name_with_default,
'clickable_tab_count': len(s.get_children()) if (type(s) == seq_module.SequenceDescriptor) else 0,
'tabs': [{'children_count': len(t.get_children()) if (type(t) == vertical_module.VerticalDescriptor) else 0,
'class': t.__class__.__name__}
......
......@@ -115,7 +115,7 @@ def answer_distributions(request, course):
for problem_id in capa_module.lcp.student_answers:
# Answer can be a list or some other unhashable element. Convert to string.
answer = str(capa_module.lcp.student_answers[problem_id])
key = (capa_module.url_name, capa_module.display_name, problem_id)
key = (capa_module.url_name, capa_module.display_name_with_default, problem_id)
counts[key][answer] += 1
return counts
......@@ -153,7 +153,7 @@ def grade(student, request, course, model_data_cache=None, keep_raw_scores=False
format_scores = []
for section in sections:
section_descriptor = section['section_descriptor']
section_name = section_descriptor.lms.display_name
section_name = section_descriptor.display_name_with_default
should_grade_section = False
# If we haven't seen a single problem in the section, we don't have to grade it at all! We can assume 0%
......@@ -195,7 +195,7 @@ def grade(student, request, course, model_data_cache=None, keep_raw_scores=False
#We simply cannot grade a problem that is 12/0, because we might need it as a percentage
graded = False
scores.append(Score(correct, total, graded, module_descriptor.lms.display_name))
scores.append(Score(correct, total, graded, module_descriptor.display_name_with_default))
section_total, graded_total = graders.aggregate_scores(scores, section_name)
if keep_raw_scores:
......@@ -311,15 +311,15 @@ def progress_summary(student, request, course, model_data_cache):
continue
scores.append(Score(correct, total, graded,
module_descriptor.lms.display_name))
module_descriptor.display_name_with_default))
scores.reverse()
section_total, graded_total = graders.aggregate_scores(
scores, section_module.lms.display_name)
scores, section_module.display_name_with_default)
format = section_module.lms.format
sections.append({
'display_name': section_module.lms.display_name,
'display_name': section_module.display_name_with_default,
'url_name': section_module.url_name,
'scores': scores,
'section_total': section_total,
......@@ -328,8 +328,8 @@ def progress_summary(student, request, course, model_data_cache):
'graded': graded,
})
chapters.append({'course': course.lms.display_name,
'display_name': chapter_module.lms.display_name,
chapters.append({'course': course.display_name_with_default,
'display_name': chapter_module.display_name_with_default,
'url_name': chapter_module.url_name,
'sections': sections})
......
......@@ -101,7 +101,7 @@ def toc_for_course(user, request, course, active_chapter, active_section, model_
section.url_name == active_section)
if not section.lms.hide_from_toc:
sections.append({'display_name': section.lms.display_name,
sections.append({'display_name': section.display_name_with_default,
'url_name': section.url_name,
'format': section.lms.format,
'due': section.lms.due,
......@@ -109,7 +109,7 @@ def toc_for_course(user, request, course, active_chapter, active_section, model_
'graded': section.lms.graded,
})
chapters.append({'display_name': chapter.lms.display_name,
chapters.append({'display_name': chapter.display_name_with_default,
'url_name': chapter.url_name,
'sections': sections,
'active': chapter.url_name == active_chapter})
......
......@@ -282,7 +282,7 @@ def index(request, course_id, chapter=None, section=None,
context = {
'csrf': csrf(request)['csrf_token'],
'accordion': render_accordion(request, course, chapter, section, model_data_cache),
'COURSE_TITLE': course.lms.display_name,
'COURSE_TITLE': course.display_name_with_default,
'course': course,
'init': '',
'content': '',
......
......@@ -128,7 +128,7 @@ def manage_modulestores(request, reload_dir=None, commit_id=None):
for cdir, course in def_ms.courses.items():
html += '<hr width="100%"/>'
html += '<h2>Course: %s (%s)</h2>' % (course.display_name, cdir)
html += '<h2>Course: %s (%s)</h2>' % (course.display_name_with_default, cdir)
html += '<p>commit_id=%s</p>' % get_commit_id(course)
......
......@@ -10,7 +10,7 @@ def _message(reqm, message):
return message.format(link="<a href={url}>{url_name}</a>".format(
url = reverse('jump_to', kwargs=dict(course_id=get_course_id(reqm),
location=reqm.location.url())),
url_name = reqm.display_name))
url_name = reqm.display_name_with_default))
%>
% if message:
% for reqm in module.required_modules:
......
<h2>${chapter_module.lms.display_name}</h2>
<h2>${chapter_module.display_name_with_default}</h2>
<p>You were most recently in <a href="${prev_section_url}">${prev_section.lms.display_name}</a>. If you're done with that, choose another section on the left.</p>
<p>You were most recently in <a href="${prev_section_url}">${prev_section.display_name_with_default}</a>. If you're done with that, choose another section on the left.</p>
......@@ -216,7 +216,7 @@
% endif
</p>
<h2 class="university">${get_course_about_section(course, 'university')}</h2>
<h3><a href="${course_target}">${course.number} ${course.lms.display_name}</a></h3>
<h3><a href="${course_target}">${course.number} ${course.display_name_with_default}</a></h3>
</hgroup>
<%
......
......@@ -26,7 +26,7 @@
<div class="sidebar"></div>
<div class="discussion-column">
<div class="discussion-article blank-slate">
<h1>${course.lms.display_name} Discussion</h1>
<h1>${course.display_name_with_default} Discussion</h1>
</div>
</div>
......
......@@ -41,7 +41,7 @@ site_status_msg = get_site_status_msg(course_id)
<h1 class="logo"><a href="${reverse('root')}"><img src="${static.url(branding.get_logo_url(request.META.get('HTTP_HOST')))}"/></a></h1>
% if course:
<h2><span class="provider">${course.org}:</span> ${course.number} ${course.lms.display_name}</h2>
<h2><span class="provider">${course.org}:</span> ${course.number} ${course.display_name_with_default}</h2>
% endif
<ol class="left find-courses-button">
......
......@@ -93,7 +93,7 @@
<section class="introduction">
<header>
<hgroup>
<h2><a href="${reverse('dashboard')}">${get_course_about_section(course, 'university')} ${course.number} ${course.lms.display_name}</a></h2>
<h2><a href="${reverse('dashboard')}">${get_course_about_section(course, 'university')} ${course.number} ${course.display_name_with_default}</a></h2>
% if registration:
<h1>Your Pearson VUE Proctored Exam Registration</h1>
......@@ -457,7 +457,7 @@
% if exam_info is not None:
<ul>
<li>
<span class="label">Exam Name:</span> <span class="value">${exam_info.display_name}</span>
<span class="label">Exam Name:</span> <span class="value">${exam_info.display_name_with_default}</span>
</li>
<li>
<span class="label">First Eligible Appointment Date:</span> <span class="value">${exam_info.first_eligible_appointment_date_text}</span>
......
......@@ -27,11 +27,6 @@ class LmsNamespace(Namespace):
default='',
)
display_name = String(
help="Display name for this module",
scope=Scope.settings,
computed_default=lambda module: module.url_name.replace('_', ' ')
)
start = Date(help="Start time when this module is visible", scope=Scope.settings)
due = String(help="Date that this problem is due by", scope=Scope.settings, default='')
source_file = String(help="DO NOT USE", scope=Scope.settings)
......
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