def _get_element(self, **kwargs) -> htmler.Element: cont = htmler.TagLessElement() cont.append_child(htmler.H2(lang.t('theming@installed_themes'))) table = cont.append_child( htmler.Table(css='table table-striped table-bordered table-hover')) t_head = table.append_child(htmler.Tr()) t_head.append_child(htmler.Th(lang.t('theming@name'))) t_head.append_child(htmler.Th(lang.t('theming@version'))) t_head.append_child(htmler.Th(lang.t('theming@author'))) t_head.append_child(htmler.Th(lang.t('theming@url'))) t_head.append_child(htmler.Th(lang.t('theming@actions'))) t_body = table.append_child(htmler.Tbody()) for theme in _api.get_all().values(): tr = t_body.append_child(htmler.Tr()) tr.append_child(htmler.Td(theme.name)) tr.append_child(htmler.Td(theme.version)) tr.append_child( htmler.Td( htmler.A(theme.author['name'], href=theme.author['url'], target='_blank'))) tr.append_child( htmler.Td(htmler.A(theme.url, href=theme.url, target='_blank'))) actions = htmler.TagLessElement(child_sep=' ') if _api.get().name != theme.name: # 'Switch' button btn_switch = htmler.A( title=lang.t('theming@switch_to_this_theme'), href='#', role='button', css='btn btn-default btn-light btn-sm button-switch', data_package_name=theme.package_name) btn_switch.append_child(htmler.I(css='fa fas fa-power-off')) actions.append_child(btn_switch) # 'Uninstall' button btn_delete = htmler.A( title=lang.t('theming@uninstall_theme'), href='#', role='button', css='btn btn-danger btn-sm button-uninstall', data_package_name=theme.package_name) btn_delete.append_child(htmler.I(css='fa fas fa-trash')) actions.append_child(btn_delete) tr.append_child(htmler.Td(actions)) return cont
def _get_element(self, **kwargs) -> htmler.Element: """Render the widget. :param **kwargs: """ lng = self.value['lng'] lat = self.value['lat'] address = self.value['address'] address_components = json.dumps(self.value['address_components']) inputs = htmler.TagLessElement() inputs.append_child(htmler.Input(type='text', name=self._uid + '[search]', css='form-control', value=address, placeholder=self._placeholder)) inputs.append_child(htmler.Input(type='hidden', name=self._uid + '[lng]', value=lng)) inputs.append_child(htmler.Input(type='hidden', name=self._uid + '[lat]', value=lat)) inputs.append_child(htmler.Input(type='hidden', name=self._uid + '[address]', value=address)) inputs.append_child( htmler.Input(type='hidden', name=self._uid + '[address_components]', value=address_components)) if self._autodetect: self._data['autodetect'] = self._autodetect if self._types: self._data['types'] = json.dumps(self._types) if self._component_restrictions: self._data['component_restrictions'] = json.dumps({'country': self._component_restrictions}) return inputs
def _get_element(self, **kwargs): """Hook """ container = htmler.TagLessElement() container.append_child(htmler.Input( type='hidden', name=self.name)) # It is important to have an empty input! for entity in self._get_entities(): container.append_child(self._item_renderer(entity)) return container
def _get_element(self, **kwargs) -> htmler.Element: """Get widget's HTML element """ # Root element r = htmler.TagLessElement() # Append toolbar r.append_child(self._toolbar) r.append_child(htmler.Div(css='widget-component')) return r
def render(self, entities: Iterable[Union[str, _model.Menu]]) -> htmler.Element: # Currently Bootstrap does not support sub-dropdowns, so we too. While. # https://github.com/twbs/bootstrap/issues/21026 root = htmler.TagLessElement() for e in entities: # type: _model.Menu child = self._render_dropdown(e) if e.has_children else self._render_item(e) if child: root.append_child(child) return root
def _get_element(self, **kwargs) -> htmler.Element: """Render the widget. :param **kwargs: """ container = htmler.TagLessElement() container.append_child( htmler.Input(type='hidden', uid=self.uid, name=self.name, value=self.value)) container.append_child( htmler.P(self._text, css='form-control-static', title=self._title)) return container
def _get_element(self, **kwargs) -> htmler.Element: self._css += ' layout-{}'.format(self._layout) self._data.update({ 'url': http_api.url('file_ui@post'), 'max_files': self._max_files, 'max_file_size': self._max_file_size, 'accept_files': self._accept_files, 'slot_css': self._slot_css, 'show_numbers': self._show_numbers, 'dnd': self._dnd, 'preview_images': self._preview_images, 'thumb_width': self._thumb_width, 'thumb_height': self._thumb_height, }) return htmler.TagLessElement( tpl.render('file_ui@file_upload_widget', {'widget': self}))
def _get_element(self, **kwargs): self._data['img_class'] = self._img_css self._data['width'] = self._width self._data['height'] = self._height self._data['img_url'] = router.url('https://maps.googleapis.com/maps/api/staticmap', query={ 'center': '{},{}'.format(self._point.lat, self._point.lng), 'zoom': self._zoom, 'scale': self._scale, 'markers': '|'.join(x for x in self._markers), 'key': google_maps.helpers.get_google_api_key(), }) if self._linked: self._data['link'] = google_maps.maps.link(self._point, zoom=self._zoom) self._data['link_target'] = self._link_target return htmler.TagLessElement()
def _get_element(self, **kwargs) -> htmler.Element: """Hook """ em = htmler.TagLessElement() if len(self._header): header = htmler.Div(self._header, css='card-header panel-heading') header.add_css(self._header_css) em.append_child(header) body = em.append_child(htmler.Div( css='card-body panel-body children')) # type: htmler.Element body.add_css(self._body_css) if len(self._footer): footer = htmler.Div(self._footer, css='card-footer panel-footer') footer.add_css(self._footer_css) em.append_child(footer) return em
def _get_element(self, **kwargs) -> htmler.Element: """Render the widget. :param **kwargs: """ inputs = htmler.TagLessElement() inputs.append_child( htmler. P(f'Longitude: {self.value["lng"]}, latitude: {self.value["lat"]}', css='text')) self._data['autodetect'] = self._autodetect for k in ('lng', 'lat', 'coordinates', 'accuracy', 'alt', 'alt_accuracy', 'heading', 'speed'): inp_val = self._value[k] if k in self._value else '' inputs.append_child( htmler.Input(type='hidden', css=k, name=self._uid + '[' + k + ']', value=inp_val)) return inputs
def _get_element(self, **kwargs) -> htmler.Element: """Get HTML element of the widget. :param **kwargs: """ wrapper = htmler.TagLessElement() wrapper.append_child( widget.input.Text( uid='{}[bot_token]'.format(self._uid), label=lang.t('content_export_telegram@bot_token'), required=True, value=self._bot_token, ).renderable()) wrapper.append_child( widget.input.Text( uid='{}[chat_id]'.format(self._uid), label=lang.t('content_export_telegram@chat_id'), required=True, value=self._chat_id, ).renderable()) return wrapper
def renderable(self, **kwargs) -> htmler.Element: """Get an HTML element representation of the widget """ cid = [] cur_cls = self.__class__ while cur_cls is not Abstract: cid.append(cur_cls.cid()) cur_cls = cur_cls.__bases__[0] if not self._inherit_cid: # Breaks after first iteration break # Wrapper div self._wrap_em.set_attr('data_cid', ' '.join(reversed(cid))) self._wrap_em.set_attr('data_uid', self._uid) self._wrap_em.set_attr('data_weight', self._weight) self._wrap_em.set_attr('data_form_area', self._form_area) self._wrap_em.set_attr('data_hidden', self._hidden) self._wrap_em.set_attr('data_enabled', self._enabled) self._wrap_em.set_attr('data_parent_uid', self._parent.uid if self._parent else None) # Replaces if self._replaces: self._wrap_em.set_attr('data_replaces', self._replaces) # Get widget's HTML element em = self._get_element(**kwargs) if not em: return htmler.TagLessElement() # Validate element's type if not isinstance(em, htmler.Element): raise TypeError('{} expected, got {}'.format( htmler.Element, type(em))) # Wrapper CSS cls_css = self.__class__.__name__.lower() cid_css = self.cid().lower().replace('_', '-').replace('.', '-') wrap_css = 'pytsite-widget widget-{} widget-{} widget-uid-{} {}'.format( cls_css, cid_css, self._uid, self._css) if self._form_group: wrap_css += ' form-group' if self._hidden: wrap_css += ' hidden sr-only' if self._has_messages: if self._has_success: wrap_css += ' has-success' if self._has_warning: wrap_css += ' has-warning' if self._has_error: wrap_css += ' has-error' self._wrap_em.set_attr('css', wrap_css) # Set widget's data attributes if isinstance(self._data, dict): for k, v in self._data.items(): self._wrap_em.set_attr('data_' + k, v) # Wrap into size container h_sizer = None if self._h_size: h_sizer = htmler.Div(css='h-sizer ' + self._h_size) em = em.wrap(h_sizer) em = em.wrap(htmler.Div(css='row ' + self._h_size_row_css)) # Append label element if self._label and not self._label_disabled: label = htmler.Label(self._label, label_for=self.uid) if self._h_size and self._h_size_label: label = label.wrap(htmler.Div(css='h-sizer ' + self._h_size)) label = label.wrap( htmler.Div(css='row ' + self._h_size_row_css)) if self._label_hidden: label.set_attr('css', 'sr-only') self._wrap_em.append_child(label) # Append widget's element self._wrap_em.append_child(em) # Append help block if self._help: self._wrap_em.append_child( htmler.Small(self._help, css='help-block form-text text-muted')) # Append messages placeholder if self._has_messages: messages = htmler.Div(css='widget-messages') if h_sizer: h_sizer.append_child(messages) else: self._wrap_em.append_child(messages) return self._wrap_em
def _get_element(self, **kwargs) -> htmler.Element: """Get table HTML skeleton """ c_lang = lang.get_current() if c_lang == 'ru': locale = 'ru-RU' elif c_lang == 'uk': locale = 'uk-UA' else: locale = 'en-US' # Table skeleton table = htmler.Table( css='hidden sr-only', data_locale=locale, data_url=self._rows_url, data_show_refresh='true', data_search=str(self._search).lower(), data_pagination='true', data_side_pagination='server', data_page_size='10', data_striped='true', data_sort_name=self._default_sort_field, data_sort_order=self._default_sort_order, data_cookie='true', data_cookie_id_table=self.uid, data_cookies_enabled= "[bs.table.sortOrder,bs.table.sortName,bs.table.pageNumber,bs.table.pageList]", data_cookie_expire='1y', data_cookie_storage='localStorage', ) t_head = htmler.Thead() t_body = htmler.Tbody() table.append_child(t_head) table.append_child(t_body) # Table head row t_head_row = htmler.Tr() t_head.append_child(t_head_row) # Checkbox column if self._checkbox: t_head_row.append_child( htmler.Th(data_field='__state', data_checkbox='true', css='td-row-actions')) # Head row's cells for f in self._data_fields: t_head_row.append_child( htmler.Th( f[1], data_field=f[0], data_sortable='true' if f[2] else 'false', css='td-field-' + f[0], )) r = htmler.TagLessElement() r.append_child(self._toolbar) r.append_child(table) return r
def get_rows(self, args: routing.ControllerArgs) -> dict: """Get browser rows. """ # Instantiate finder finder = odm.find(self._model) # Check if the user can modify/delete any entity if not odm_auth.check_model_permissions(self._model, [PERM_MODIFY, PERM_DELETE]) and \ odm_auth.check_model_permissions(self._model, [PERM_MODIFY_OWN, PERM_DELETE_OWN]): # Show only entities owned by user finder.mock.has_field('author') and finder.eq( 'author', self._current_user) # Let model to finish finder setup _api.dispense_entity(self._model).odm_ui_browser_setup_finder( finder, args) # Sort sort_order = odm.I_DESC if args.get( 'order', self.default_sort_order) in (-1, 'desc') else odm.I_ASC sort_field = args.get('sort') if sort_field and finder.mock.has_field(sort_field): finder.sort([(sort_field, sort_order)]) elif self.default_sort_field: finder.sort([(self.default_sort_field, sort_order)]) # Get root elements first finder.add_sort('_parent', pos=0) # Prepare result r = {'total': finder.count(), 'rows': []} # Build table rows cursor = finder.skip(args.get('offset', 0)).get(args.get('limit', 0)) for entity in cursor: row = entity.odm_ui_browser_row() events.fire('odm_ui@browser_row.{}'.format(self._model), entity=entity, row=row) if not row: continue # Build row's cells fields_data = { '__id': str(entity.id), '__parent': str(entity.parent.id) if entity.parent else None, } if not isinstance(row, dict): raise TypeError( '{}.odm_ui_browser_row() must return dict, got {}'.format( entity.__class__.__name__, type(row))) for df in self.data_fields: fields_data[df[0]] = row.get(df[0], ' ') # Action buttons if self._model_class.odm_ui_entity_actions_enabled() and \ (self._model_class.odm_ui_modification_allowed() or self._model_class.odm_ui_deletion_allowed()): actions = htmler.TagLessElement(child_sep=' ') for btn_data in entity.odm_ui_browser_entity_actions(self): color = 'btn btn-sm btn-' + btn_data.get( 'color', 'default btn-light') title = btn_data.get('title', '') url = btn_data.get('url') if not url: rule = btn_data.get('rule') url = router.rule_url( rule, {'ids': str(entity.id)}) if rule else '#' btn = htmler.A(href=url, css=color + ' ' + btn_data.get('css', ''), title=title, role='button') if btn_data.get('disabled'): btn.set_attr('aria_disabled', 'true') btn.add_css('disabled') btn.append_child( htmler.I(css=btn_data.get('icon', 'fa fas fa-fw fa-question'))) actions.append_child(btn) fields_data['entity-actions'] = actions.render() r['rows'].append(fields_data) return r
def test_tagless(self): """Test of rendering of the TagLessElement """ for cls in _get_elements_classes(): child = cls() assert htmler.TagLessElement(child).render() == child.render()
def _get_element(self, **kwargs) -> htmler.Element: """Render the widget. :param **kwargs: """ return htmler.TagLessElement(tpl.render(self._tpl, {'widget': self}))