def dynatree_renderer(widget, data): tag = data.tag value = fetch_value(widget, data) if isinstance(value, (list, tuple)): value = '|'.join(value) input_attrs = { 'type': 'hidden', 'value': value, 'name_': widget.dottedpath, 'id': cssid(widget, 'input') } result = tag('input', **input_attrs) source = attr_value('source', widget, data) if isinstance(source, dict): source_type = 'local' ulid = cssid(widget, 'dynatree-source'); result += build_inline_dynatree(source, fetch_value(widget, data), tag, ulid=ulid) elif isinstance(source, basestring): source_type = 'remote' result += tag('div', source, **{'class': 'dynatree-source hiddenStructure'}) else: raise ValueError, 'resulting source must be [o]dict or string' p_keys = ['selectMode', 'minExpandLevel', 'rootVisible', 'autoCollapse', 'checkbox'] params = [('%s,%s' % (_, attr_value(_, widget, data))) \ for _ in parameter_keys] params.append('type,%s' % source_type) if source_type == 'local': params.append(('initId,%s' % ulid)) result += tag('div', '|'.join(params), **{'class': 'dynatree-params hiddenStructure'}) result += tag('div','', **{'class': 'yafowil-widget-dynatree-tree'}) return tag('div', result, **{'class': 'yafowil-widget-dynatree'})
def div_renderer(widget, data): attrs = { 'id': attr_value('id', widget, data), 'class_': cssclasses(widget, data) } attrs.update(as_data_attrs(attr_value('data', widget, data))) return data.tag('div', data.rendered, **attrs)
def render_time_input(widget, data, value, postfix=None, css_class=False): tag = data.tag widgetname = widget.dottedpath if postfix: widgetname = '%s.%s' % (widgetname, postfix) if value is True: value = '' if not value and data.request: value = data.request.get(widgetname) disabled = attr_value('disabled', widget, data) and 'disabled' or None attrs = { 'type': 'text', 'value': value, 'name_': widgetname, 'id': cssid(widget, 'input', postfix), 'size': 5, 'disabled': disabled, } class_ = '' timepicker = attr_value('timepicker', widget, data) if timepicker and not disabled: class_ = attr_value('timepicker_class', widget, data) if css_class: additional = class_ and [class_] or list() attrs['class_'] = cssclasses(widget, data, additional=additional) elif class_: attrs['class_'] = class_ return tag('input', **attrs)
def slider_edit_renderer(widget, data): value = fetch_value(widget, data) content = '' range = attr_value('range', widget, data) if range is True: lower_input_attrs = { 'type': 'text', 'name': '%s.lower' % widget.dottedpath, 'id': cssid(widget, 'input-lower'), 'style': 'display:none;', 'class': 'lower_value', 'value': value and value[0], } content += data.tag('input', **lower_input_attrs) upper_input_attrs = { 'type': 'text', 'name': '%s.upper' % widget.dottedpath, 'id': cssid(widget, 'input-upper'), 'style': 'display:none;', 'class': 'upper_value', 'value': value and value[1], } content += data.tag('input', **upper_input_attrs) else: input_attrs = { 'type': 'text', 'name': widget.dottedpath, 'id': cssid(widget, 'input'), 'style': 'display:none;', 'class': 'slider_value', 'value': value, } content += data.tag('input', **input_attrs) show_value = attr_value('show_value', widget, data) if show_value: unit = attr_value('unit', widget, data) if unit: content += data.tag('span', '%s: ' % unit, **{'class': 'unit'}) if range is True: content += data.tag('span', value[0], **{'class': 'lower_value'}) content += ' - ' content += data.tag('span', value[1], **{'class': 'upper_value'}) else: content += data.tag('span', value, **{'class': 'slider_value'}) slider_attrs = {'class': 'slider'} if attr_value('orientation', widget, data) == 'vertical': height = attr_value('height', widget, data) if height: slider_attrs['style'] = 'height:%spx;' % height content += data.tag('div', ' ', **slider_attrs) wrapper_attrs = data_attrs_helper(widget, data, js_options) wrapper_attrs['class'] = cssclasses(widget, data) html_data = widget.attrs['data'] data_keys = html_data.keys() for key in data_keys: if key in js_options: raise ValueError(u"Additional data dict contains reserved " u"attribute name '%s'" % key) wrapper_attrs['data-%s' % key] = html_data[key] return data.tag('div', content, **wrapper_attrs)
def render_time_input(widget, data, value, postfix=None, css_class=False): tag = data.tag widgetname = widget.dottedpath if postfix: widgetname = '{}.{}'.format(widgetname, postfix) if value is True: value = '' if not value and data.request: value = data.request.get(widgetname) disabled = 'disabled' if attr_value('disabled', widget, data) else None attrs = { 'type': 'text', 'value': value, 'name_': widgetname, 'id': cssid(widget, 'input', postfix), 'size': 5, 'disabled': disabled, } class_ = [attr_value('timeinput_class', widget, data)] timepicker = attr_value('timepicker', widget, data) if timepicker and not disabled: class_.append(attr_value('timepicker_class', widget, data)) if css_class: attrs['class_'] = cssclasses(widget, data, additional=class_) else: attrs['class_'] = ' '.join(class_) return tag('input', **attrs)
def time_data_defs(widget, data): format = attr_value('format', widget, data) if format not in ['number', 'string', 'tuple']: raise ValueError(u"Unknown format '{}'".format(format)) unit = attr_value('unit', widget, data) if unit not in ['minutes', 'hours']: raise ValueError(u"Unknown unit '{}'".format(unit)) return format, unit
def time_data_defs(widget, data): format = attr_value('format', widget, data) if format not in ['number', 'string', 'tuple']: raise ValueError(u"Unknown format '%s'" % format) unit = attr_value('unit', widget, data) if unit not in ['minutes', 'hours']: raise ValueError(u"Unknown unit '%s'" % unit) return format, unit
def dict_label(widget, data, name, bc_name): label = attr_value(name, widget, data) if not label: # B/C label = callable_value( attr_value('head', widget, data, default={}).get(bc_name, ' '), widget, data ) return label
def image_display_renderer(widget, data): src = attr_value('src', widget, data) if src: tag = data.tag img_attrs = { 'src': src, 'alt': attr_value('alt', widget, data), } return tag('img', **img_attrs) return ''
def th_renderer(widget, data): attrs = { 'id': attr_value('id', widget, data), 'class_': cssclasses(widget, data), 'colspan': attr_value('colspan', widget, data), 'rowspan': attr_value('rowspan', widget, data), } contents = attr_value('label', widget, data) if not contents: contents = data.rendered return data.tag('th', contents, **attrs)
def td_renderer(widget, data): attrs = { 'id': attr_value('id', widget, data), 'class_': cssclasses(widget, data), 'colspan': attr_value('colspan', widget, data), 'rowspan': attr_value('rowspan', widget, data), } if len(widget): rendered = compound_renderer(widget, data) else: rendered = data.rendered return data.tag('td', rendered, **attrs)
def form_edit_renderer(widget, data): method = attr_value('method', widget, data) enctype = method == 'post' and attr_value('enctype', widget, data) or None noval = attr_value('novalidate', widget, data) and 'novalidate' or None form_attrs = { 'action': attr_value('action', widget, data), 'method': method, 'enctype': enctype, 'novalidate': noval, 'class_': cssclasses(widget, data), 'id': 'form-{0}'.format('-'.join(widget.path)), } return data.tag('form', data.rendered, **form_attrs)
def time_extractor(widget, data): format, unit = time_data_defs(widget, data) extracted = data.extracted if extracted == UNSET or extracted == '': return UNSET if len(extracted) > 5: message = _('input_not_valid_time', default=u'Not a valid time input.') raise ExtractionError(message) elif len(extracted) == 5: hours = extracted[:2] minutes = extracted[3:] elif len(extracted) == 4 and extracted.find(':') == -1: hours = extracted[:2] minutes = extracted[2:] else: extracted = extracted.split(':') if len(extracted) != 2: message = _('failed_to_parse_time', default=u'Failed to parse time input.') raise ExtractionError(message) hours, minutes = extracted try: hours = int(hours) except ValueError: message = _('hours_not_a_number', default=u'Hours not a number.') raise ExtractionError(message) try: minutes = int(minutes) except ValueError: message = _('minutes_not_a_number', default=u'Minutes not a number.') raise ExtractionError(message) daytime = attr_value('daytime', widget, data) timepicker = attr_value('timepicker', widget, data) if daytime or timepicker: if hours < 0 or hours > 23: message = _('invalid_hours_range', default=u'Hours must be in range 0..23.') raise ExtractionError(message) if minutes < 0 or minutes > 59: message = _('invalid_minutes_range', default=u'Minutes must be in range 0..59.') raise ExtractionError(message) if format == 'string': return '%02i:%02i' % (hours, minutes) if format == 'tuple': return (hours, minutes) if unit == 'hours': return hours + (minutes / 60.0) return hours * 60 + minutes
def select2_extractor(widget, data): if attr_value('inputtag', widget, data): extracted = generic_extractor(widget, data) if extracted is UNSET: return extracted if not extracted: if attr_value('multiple', widget, data): return [] return '' if attr_value('inputtag', widget, data): if attr_value('multiple', widget, data): extracted = extracted.split(',') return extracted return select_extractor(widget, data)
def datetime_extractor(widget, data): time = None if attr_value('time', widget, data): time = data.request.get('{}.time'.format(widget.dottedpath)) required = attr_value('required', widget, data) if not required and not data.extracted and not time: return '' locale = attr_value('locale', widget, data) tzinfo = attr_value('tzinfo', widget, data) try: return convert(data.extracted, time=time, tzinfo=tzinfo, locale=locale) except DateTimeConversionError: message = _('input_not_valid_date', default=u'Not a valid date input.') raise ExtractionError(message)
def form_edit_renderer(widget, data): method = attr_value('method', widget, data) enctype = method == 'post' and attr_value('enctype', widget, data) or None noval = attr_value('novalidate', widget, data) and 'novalidate' or None form_attrs = { 'action': attr_value('action', widget, data), 'method': method, 'enctype': enctype, 'novalidate': noval, 'class_': cssclasses(widget, data), 'id': 'form-{0}'.format('-'.join(widget.path)), } form_attrs.update(as_data_attrs(attr_value('data', widget, data))) return data.tag('form', data.rendered, **form_attrs)
def time_extractor(widget, data): format, unit = time_data_defs(widget, data) extracted = data.extracted if extracted == UNSET or extracted == '': return UNSET if len(extracted) > 5: message = _('input_not_valid_time', default=u'Not a valid time input.') raise ExtractionError(message) elif len(extracted) == 5: hours = extracted[:2] minutes = extracted[3:] elif len(extracted) == 4 and extracted.find(':') == -1: hours = extracted[:2] minutes = extracted[2:] else: extracted = extracted.split(':') if len(extracted) != 2: message = _('failed_to_parse_time', default=u'Failed to parse time input.') raise ExtractionError(message) hours, minutes = extracted try: hours = int(hours) except ValueError: message = _('hours_not_a_number', default=u'Hours not a number.') raise ExtractionError(message) try: minutes = int(minutes) except ValueError: message = _('minutes_not_a_number', default=u'Minutes not a number.') raise ExtractionError(message) daytime = attr_value('daytime', widget, data) timepicker = attr_value('timepicker', widget, data) if daytime or timepicker: if hours < 0 or hours > 23: message = _('invalid_hours_range', default=u'Hours must be in range 0..23.') raise ExtractionError(message) if minutes < 0 or minutes > 59: message = _('invalid_minutes_range', default=u'Minutes must be in range 0..59.') raise ExtractionError(message) if format == 'string': return '{:02d}:{:02d}'.format(hours, minutes) if format == 'tuple': return (hours, minutes) if unit == 'hours': return hours + (minutes / 60.0) return hours * 60 + minutes
def datetime_extractor(widget, data): time = None if attr_value('time', widget, data): time = data.request.get('%s.time' % widget.dottedpath) required = attr_value('required', widget, data) if not required and not data.extracted and not time: return '' locale = attr_value('locale', widget, data) tzinfo = attr_value('tzinfo', widget, data) try: return convert(data.extracted, time=time, tzinfo=tzinfo, locale=locale) except DateTimeConversionError: message = _('input_not_valid_date', default=u'Not a valid date input.') raise ExtractionError(message)
def datetime_edit_renderer(widget, data): locale = attr_value('locale', widget, data) delim = attr_value('delimiter', widget, data) time = attr_value('time', widget, data) date = None if data.value and isinstance(data.value, datetime): date = format_date(data.value, locale, delim) if time: time = format_time(data.value) if data.extracted and isinstance(data.extracted, datetime): date = format_date(data.extracted, locale, delim) if time: time = format_time(data.extracted) if not date: date = fetch_value(widget, data) return render_datetime_input(widget, data, date, time)
def cron_extractor(widget, data): # instanciate subwidgets widget() # extract subwidgets compound_extractor(widget, data) minute = data['minute'] # if one subwidget is UNSET, whole widget not found on request if minute.extracted is UNSET: return UNSET minute = data['minute'].extracted hour = data['hour'].extracted dom = data['dom'].extracted month = data['month'].extracted dow = data['dow'].extracted year = data['year'].extracted # if all values missing, we have no cron rule if not minute and not hour and not dom \ and not month and not dow and not year: return attr_value('emptyvalue', widget, data, EMPTY_VALUE) # if one value missing, we have an invalid cron rule if not (minute and hour and dom and month and dow and year): raise ExtractionError( _('invalid_cron_rule', default=('Invalid cron rule. You must at least ' 'select one item for each criteria'))) return '{0} {1} {2} {3} {4} {5}'.format(minute, hour, dom, month, dow, year)
def cron_display_renderer(widget, data): value = fetch_value(widget, data) attrs = { 'id': cssid(widget, 'display'), 'class_': 'display-%s' % attr_value('class', widget, data) } return data.tag('div', data.tag('code', value), **attrs)
def compound_renderer(widget, data): """Delegates rendering to children. """ value = widget.getter result = u'' for childname in widget: child = widget[childname] if attr_value('structural', child, data): subdata = data if value is not UNSET and child.getter is UNSET: child.getter = value else: subdata = data.get(childname, None) if callable(value): value = value(widget, data) if value is not UNSET and childname in value: if child.getter is UNSET: child.getter = value[childname] else: raise ValueError( u"Both compound and compound member " u"provide a value for '{0}'".format(childname) ) if subdata is None: result += child(request=data.request) else: result += child(data=subdata) return result
def compound_renderer(widget, data): """Delegates rendering to children. """ value = widget.getter result = u'' for childname in widget: child = widget[childname] if attr_value('structural', child, data): subdata = data if value is not UNSET and child.getter is UNSET: child.getter = value else: subdata = data.get(childname, None) if callable(value): value = value(widget, data) if value is not UNSET and childname in value: # XXX: if compound renderer is called multiple times on the # same widget within one form processing cycle # ``child.getter`` has been set, so the condition is True # and ``ValueError`` is raised. Think about widget # instance annotations to mark value delegation already # processed. if child.getter is UNSET: child.getter = value[childname] else: raise ValueError( u"Both compound and compound member " u"provide a value for '{0}'".format(childname) ) if subdata is None: result += child(request=data.request) else: result += child(data=subdata) return result
def dynatree_extractor(widget, data): if data.extracted is UNSET: return data.extracted if attr_value('selectMode', widget, data) == 1: return data.extracted.strip('|') value = [_ for _ in data.extracted.split('|')if _] return value
def dynatree_extractor(widget, data): if data.extracted is UNSET: return data.extracted if attr_value('selectMode', widget, data) == 1: return data.extracted.strip('|') value = [_ for _ in data.extracted.split('|') if _] return value
def slider_extractor(widget, data): # extract range tuple if attr_value('range', widget, data) is True: lower_value_name = '%s.lower' % widget.dottedpath upper_value_name = '%s.upper' % widget.dottedpath lower_value = UNSET if lower_value_name in data.request: lower_value = data.request[lower_value_name] if lower_value: lower_value = int(lower_value) else: lower_value = UNSET upper_value = UNSET if upper_value_name in data.request: upper_value = data.request[upper_value_name] if upper_value: upper_value = int(upper_value) else: upper_value = UNSET return [lower_value, upper_value] # regular value extraction if widget.dottedpath in data.request: val = data.request[widget.dottedpath] if val: return int(val) return UNSET
def image_edit_renderer(widget, data): src = attr_value('src', widget, data) if not src: return data.rendered if src.find('?') > -1: src = src + '&nocache=%i' % time.time() else: src = src + '?nocache=%i' % time.time() tag = data.tag img_attrs = { 'src': src, 'alt': attr_value('alt', widget, data), 'id': cssid(widget, 'image-preview'), 'class': 'image-preview', } img = tag('img', **img_attrs) return img + data.rendered
def fetch_value(widget, data): """Fetch extracted, either form-data, value or default . """ if data.extracted is not UNSET: return data.extracted if data.value is not UNSET: return data.value return attr_value('default', widget, data)
def static_dict_required_extractor(widget, data): extracted = data.extracted if extracted is UNSET: return extracted required = attr_value('required', widget, data) if not (required and attr_value('static', widget, data)): return extracted for value in extracted.values(): if value: continue if isinstance(required, STR_TYPE): raise ExtractionError(required) raise ExtractionError(_( 'dict_values_required', default='Dict values must not be empty' )) return extracted
def select2_edit_renderer(widget, data): if attr_value('inputtag', widget, data): extracted = UNSET reset_extracted = False if data.extracted is not UNSET: extracted = data.extracted if isinstance(extracted, list) or isinstance(extracted, tuple): reset_extracted = True data.extracted = u','.join(extracted) value = UNSET reset_value = False if data.value is not UNSET: value = data.value if isinstance(value, list) or isinstance(value, tuple): reset_value = True data.value = u','.join(value) else: reset_value = True data.value = u'' # force widget vocabulary as dict to make JS happy vocab = vocabulary(attr_value('vocabulary', widget, data, [])) if vocab: # Use ordered dict to ensure order in tests dict_vocab = OrderedDict() for key, term in vocab: dict_vocab[key] = term widget.attrs['vocabulary'] = dict_vocab custom_attrs = data_attrs_helper( widget, data, ['ajaxurl', 'vocabulary'] + select2_options) renderer = input_generic_renderer rendered = renderer(widget, data, custom_attrs=custom_attrs) if reset_extracted: data.extracted = extracted if reset_value: data.value = value else: multiple = attr_value('multiple', widget, data) if multiple: widget.attrs['multivalued'] = True del widget.attrs['multiple'] custom_attrs = data_attrs_helper( widget, data, ['ajaxurl'] + select2_options) renderer = select_edit_renderer rendered = renderer(widget, data, custom_attrs=custom_attrs) return rendered
def select2_edit_renderer(widget, data): if attr_value('inputtag', widget, data): extracted = UNSET reset_extracted = False if data.extracted is not UNSET: extracted = data.extracted if isinstance(extracted, list) or isinstance(extracted, tuple): reset_extracted = True data.extracted = u','.join(extracted) value = UNSET reset_value = False if data.value is not UNSET: value = data.value if isinstance(value, list) or isinstance(value, tuple): reset_value = True data.value = u','.join(value) else: reset_value = True data.value = u'' # force widget vocabulary as dict to make JS happy vocab = vocabulary(attr_value('vocabulary', widget, data, [])) if vocab: # Use ordered dict to ensure order in tests dict_vocab = OrderedDict() for key, term in vocab: dict_vocab[key] = term widget.attrs['vocabulary'] = dict_vocab custom_attrs = data_attrs_helper( widget, data, ['ajaxurl', 'vocabulary'] + select2_options) renderer = input_generic_renderer rendered = renderer(widget, data, custom_attrs=custom_attrs) if reset_extracted: data.extracted = extracted if reset_value: data.value = value else: multiple = attr_value('multiple', widget, data) if multiple: widget.attrs['multivalued'] = True del widget.attrs['multiple'] custom_attrs = data_attrs_helper(widget, data, ['ajaxurl'] + select2_options) renderer = select_edit_renderer rendered = renderer(widget, data, custom_attrs=custom_attrs) return rendered
def fetch_reference_value(widget, data): if data.extracted is not UNSET: return data.extracted if data.value is not UNSET: if widget.attrs.get('multivalued'): return data.value else: return data.value[0] return attr_value('default', widget, data)
def time_display_renderer(widget, data): format, unit = time_data_defs(widget, data) value = data.value if not value: return u'' attrs = { 'id': cssid(widget, 'display'), 'class_': 'display-%s' % attr_value('class', widget, data) } return data.tag('div', time_value(format, unit, value), **attrs)
def div_renderer(widget, data): attrs = { 'id': attr_value('id', widget, data), 'class_': cssclasses(widget, data), } if len(widget): rendered = compound_renderer(widget, data) else: rendered = data.rendered return data.tag('div', rendered, **attrs)
def fieldset_renderer(widget, data): fs_attrs = { 'id': cssid(widget, 'fieldset'), 'class_': cssclasses(widget, data) } rendered = data.rendered legend = attr_value('legend', widget, data) if legend: rendered = data.tag('legend', legend) + rendered return data.tag('fieldset', rendered, **fs_attrs)
def hybrid_renderer(widget, data): """This renderer can be used if a blueprint can act as compound or leaf. """ if len(widget) and not attr_value('leaf', widget, data): rendered = compound_renderer(widget, data) else: rendered = data.rendered if data.rendered is None: rendered = u'' return rendered
def time_display_renderer(widget, data): format, unit = time_data_defs(widget, data) value = data.value if not value: return u'' attrs = { 'id': cssid(widget, 'display'), 'class_': 'display-{}'.format(attr_value('class', widget, data)) } return data.tag('div', time_value(format, unit, value), **attrs)
def recaptcha_edit_renderer(widget, data): recaptcha_attrs = { 'id': cssid(widget, 'recaptcha'), 'class': ' '.join([cssclasses(widget, data)]), } data_attrs = ['theme', 'lang', 'public_key'] recaptcha_attrs.update(data_attrs_helper(widget, data, data_attrs)) recaptcha = data.tag('div', ' ', **recaptcha_attrs) public_key = attr_value('public_key', widget, data) return recaptcha + NO_SCRIPT_TEMPLATE.format(public_key=public_key)
def autocomplete_renderer(widget, data): result = data.rendered tag = data.tag source = attr_value('source', widget, data) if isinstance(source, (list, tuple)): source = '|'.join(source) source_type = 'local' elif isinstance(source, basestring): source_type = 'remote' else: raise ValueError, 'resulting source must be tuple/list or string' result += tag('div', source, **{'class': 'autocomplete-source hiddenStructure'}) params = [('%s,%s' % (_, attr_value(_, widget, data))) \ for _ in ['delay', 'minLength']] params.append('type,%s' % source_type) result += tag('div', '|'.join(params), **{'class': 'autocomplete-params hiddenStructure'}) return tag('div', result, **{'class': 'yafowil-widget-autocomplete'})
def compound_extractor(widget, data): """Delegates extraction to children. """ for child in widget.values(): # regular child widget, extract if not attr_value('structural', child, data): child.extract(data.request, parent=data) continue # structural child widget, go one level deeper for subchild in child.values(): # sub child widget may be structural as well structural = attr_value('structural', subchild, data) # use compound extractor if sub child widget has children and is # structural if len(subchild) and structural: compound_extractor(subchild, data) # call extract on sub child widget directly if not structural elif not structural: subchild.extract(data.request, parent=data) return odict([(k, v.extracted) for k, v in data.items()])
def render_datetime_input(widget, data, date, time): tag = data.tag timeinput = '' if time: timeinput = render_time_input(widget, data, time, postfix='time') additional_classes = [attr_value('dateinput_class', widget, data)] datepicker = attr_value('datepicker', widget, data) disabled = attr_value('disabled', widget, data) if datepicker and not disabled: datepicker_class = attr_value('datepicker_class', widget, data) additional_classes.append(datepicker_class) attrs = { 'type': 'text', 'value': date, 'name_': widget.dottedpath, 'id': cssid(widget, 'input'), 'class_': cssclasses(widget, data, additional=additional_classes), 'size': 10, 'disabled': 'disabled' if disabled else None, } return tag('input', **attrs) + timeinput
def array_display_proxy_renderer(widget, data): """B/C. Use ``display_proxy`` widget attribute. """ input_attrs = { 'type': 'hidden', 'value': fetch_value(widget, data), 'name_': widget.dottedpath, 'id': cssid(widget, 'input'), 'class_': cssclasses(widget, data), 'required': attr_value('required', widget, data) and 'required' or None } return data.tag('input', **input_attrs) + data.rendered
def dynatree_renderer(widget, data): tag = data.tag value = fetch_value(widget, data) if isinstance(value, (list, tuple)): value = '|'.join(value) input_attrs = { 'type': 'hidden', 'value': value, 'name_': widget.dottedpath, 'id': cssid(widget, 'input') } result = tag('input', **input_attrs) source = attr_value('source', widget, data) if isinstance(source, dict): source_type = 'local' ulid = cssid(widget, 'dynatree-source').decode() result += build_inline_dynatree(source, fetch_value(widget, data), tag, ulid=ulid) elif isinstance(source, STR_TYPE): source_type = 'remote' result += tag('div', source, **{'class': 'dynatree-source hiddenStructure'}) else: raise ValueError('resulting source must be [o]dict or string') p_keys = [ 'selectMode', 'minExpandLevel', 'rootVisible', 'autoCollapse', 'checkbox' ] params = [('%s,%s' % (_, attr_value(_, widget, data))) \ for _ in parameter_keys] params.append('type,%s' % source_type) if source_type == 'local': params.append(('initId,%s' % ulid)) result += tag('div', '|'.join(params), **{'class': 'dynatree-params hiddenStructure'}) result += tag('div', '', **{'class': 'yafowil-widget-dynatree-tree'}) return tag('div', result, **{'class': 'yafowil-widget-dynatree'})
def multivalued_reference_vocab(widget, data): vocab = list() bc_vocab = attr_value('bc_vocabulary', widget, data) if bc_vocab: for uuid_, label in vocabulary(bc_vocab): vocab.append((uuid_, label)) return vocab if widget.dottedpath in data.request: value = data.request[widget.dottedpath] if isinstance(value, compat.STR_TYPE): value = [value] else: if callable(widget.getter): value = widget.getter(widget, data) else: value = widget.getter if not value: value = list() lookup = attr_value('lookup', widget, data) for uuid_ in value: vocab.append((uuid_, lookup(uuid_) if lookup else uuid_)) return vocab
def datetime_display_renderer(widget, data, value=None): """Note: This renderer function optionally accepts value as parameter, which is used in favor of data.value if defined. Thus it can be used as utility function inside custom blueprints with the need of datetime display rendering. """ value = value if value else data.value if not value: return u'' format = widget.attrs['format'] if callable(format): value = format(widget, data) else: value = value.strftime(format) attrs = { 'id': cssid(widget, 'display'), 'class_': 'display-{}'.format(attr_value('class', widget, data)) } return data.tag('div', value, **attrs)
def tr_renderer(widget, data): attrs = { 'id': attr_value('id', widget, data), 'class_': cssclasses(widget, data), } return data.tag('tr', data.rendered, **attrs)
def cron_value_edit_action_renderer(widget, data): """Renders cron value edit button. """ return data.rendered + data.tag( 'button', attr_value('label', widget, data), class_='btn btn-sm edit')
def cron_edit_renderer(widget, data): value = fetch_value(widget, data) if value is not UNSET and value is not attr_value('emptyvalue', widget, data, EMPTY_VALUE): value = [it.strip() for it in value.split(' ') if it.strip()] if len(value) == 5: value.append('*') if len(value) < 6: raise ValueError('Invalid cron rule') value = { 'minute': value[0], 'hour': value[1], 'dom': value[2], 'month': value[3], 'dow': value[4], 'year': value[5] } container = widget['container'] = factory( 'div', name='cron', value=value, props={ 'structural': True, 'id': cssid(widget, 'input'), 'class': cssclasses(widget, data), 'data': { 'lang': attr_value('lang', widget, data), 'start_year': attr_value('start_year', widget, data), 'end_year': attr_value('end_year', widget, data) } }) container['minute'] = factory('div:cron_value_edit_action:hidden', props={ 'persist': False, 'label': _('label_minute', default='Minute'), 'div.class': 'cron-value minute' }) container['hour'] = factory('div:cron_value_edit_action:hidden', props={ 'persist': False, 'label': _('label_hour', default='Hour'), 'div.class': 'cron-value hour' }) container['dom'] = factory('div:cron_value_edit_action:hidden', props={ 'persist': False, 'label': _('label_dom', default='Day of Month'), 'div.class': 'cron-value dom' }) container['month'] = factory('div:cron_value_edit_action:hidden', props={ 'persist': False, 'label': _('label_month', default='Month'), 'div.class': 'cron-value month' }) container['dow'] = factory('div:cron_value_edit_action:hidden', props={ 'persist': False, 'label': _('label_dow', default='Day of Week'), 'div.class': 'cron-value dow' }) container['year'] = factory('div:cron_value_edit_action:hidden', props={ 'persist': False, 'label': _('label_year', default='Year'), 'div.class': 'cron-value year' }) container['editarea'] = factory('div', props={ 'structural': True, 'class': 'editarea', })
def test_attr_value(self): # Test attr_value widget = AttributedNode() data = AttributedNode() widget.attrs['attr'] = 'value' self.assertEqual(attr_value('attr', widget, data), 'value') def func_callback(widget, data): return 'func_callback value' widget.attrs['attr'] = func_callback self.assertEqual(attr_value('attr', widget, data), 'func_callback value') def failing_func_callback(widget, data): raise Exception('failing_func_callback') widget.attrs['attr'] = failing_func_callback err = self.expect_error(Exception, attr_value, 'attr', widget, data) self.assertEqual(str(err), 'failing_func_callback') def bc_func_callback(): return 'bc_func_callback value' widget.attrs['attr'] = bc_func_callback self.assertEqual(attr_value('attr', widget, data), 'bc_func_callback value') def failing_bc_func_callback(): raise Exception('failing_bc_func_callback') widget.attrs['attr'] = failing_bc_func_callback err = self.expect_error(Exception, attr_value, 'attr', widget, data) self.assertEqual(str(err), 'failing_bc_func_callback') class FormContext(object): def instance_callback(self, widget, data): return 'instance_callback' def failing_instance_callback(self, widget, data): raise Exception('failing_instance_callback') def instance_bc_callback(self): return 'instance_bc_callback' def failing_instance_bc_callback(self, widget, data): raise Exception('failing_instance_bc_callback') context = FormContext() widget.attrs['attr'] = context.instance_callback self.assertEqual(attr_value('attr', widget, data), 'instance_callback') widget.attrs['attr'] = context.failing_instance_callback err = self.expect_error(Exception, attr_value, 'attr', widget, data) self.assertEqual(str(err), 'failing_instance_callback') widget.attrs['attr'] = context.instance_bc_callback self.assertEqual(attr_value('attr', widget, data), 'instance_bc_callback') widget.attrs['attr'] = context.failing_instance_bc_callback err = self.expect_error(Exception, attr_value, 'attr', widget, data) self.assertEqual(str(err), 'failing_instance_bc_callback')
def hybrid_extractor(widget, data): """This extractor can be used if a blueprint can act as compound or leaf. """ if len(widget) and not attr_value('leaf', widget, data): return compound_extractor(widget, data) return data.extracted
def select2_display_renderer(widget, data): multiple = attr_value('multiple', widget, data) multivalued = attr_value('multivalued', widget, data) if multiple and not multivalued: widget.attrs['multivalued'] = True return select_display_renderer(widget, data)