def visit_Subgroup(self, node): if not self._in_dropdown: node_id = sha1(str(id(node)).encode()).hexdigest() li = tags.li(_class='dropdown') if node.active: li['class'] = 'active' a = li.add( tags.a(href='javascript:void(0);', _class='dropdown-toggle')) a.add(tags.i(_class='fa fa-fw fa-arrows-v')) a.add(node.title) a['data-toggle'] = 'collapse' a['data-target'] = '#' + node_id a['role'] = 'button' a['aria-haspopup'] = 'true' a['aria-expanded'] = 'false' if hasattr(node, 'icon') and node.icon != None: a.add(tags.i(_class='fa fa-fw fa-%s' % node.icon)) ul = li.add(tags.ul(_class='collapse', id=node_id)) active = node.active self._in_dropdown = True for item in node.items: ul.add(self.visit(item)) if item.active: active = True self._in_dropdown = False if active == True: li['class'] = 'sub_active' ul['class'] = 'collapse in' return li else: raise RuntimeError('Cannot render nested Subgroups')
def Page(): doc = document() with doc.head: link_("https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css") link_("https://extra-uru1z3cxu.now.sh/css/extra.css") link_( "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.8.2/css/all.css" ) script_( 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js' ) script_('http://intercoolerjs.org/release/intercooler-1.2.2.js') with doc.body: with dom.div(cls=CENTER_FRAME) as CenterFrame: with dom.div(cls=CARD) as Card: with dom.form(UPLOAD_FORM_ATTRS) as UploadForm: dom.i(cls=UPLOAD_ICON, onclick='''$('#fileupload').click()''') dom.p("Find File", id=1, cls="text-gray-500 mt-4") dom.button("Upload", type="submit", cls=BUTTON) dom.input( cls="hidden", type="file", name="image", id="fileupload", onchange= '''$('#1').text(this.value.split("\\\\").pop(-1))''') with dom.div(id="there", cls=RESULT_CONTAINER) as ResultContainer: dom.span(id="here") #新增 return doc.render()
def test_font_styles(self): c = Converter('Man', file='font_styles.man') c.translate() text = c.html.render() text = c.change_special_symbols(text) doc = tags.html(lang='en') doc = add_head(doc) doc_body = doc.add(tags.body()) lines = [ tags.b('one'), '\ntwo', tags.b('three'), tags.b('four'), tags.i('five'), tags.b('six'), '\nseven eight', tags.b('nine'), '\nten eleven twelve', tags.i('13'), tags.b('14'), tags.i('15'), tags.i('file'), '\n.', tags.small('bbbbb'), tags.small('aaaaaa dfghjhg'), tags.b('--posix'), tags.i('file1 file2') ] with doc_body: paragraph = tags.p() for line in lines: paragraph += line self.assertEqual(doc.render(), text)
def page(): doc = document() with doc.head: link_("https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css") link_("https://extra-uru1z3cxu.now.sh/css/extra.css") link_("https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.8.2/css/all.css") script_("https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js") script_("http://intercoolerjs.org/release/intercooler-1.2.2.js") with doc.body: with dom.div(cls=CENTER_FRAME) as CenterFrame: with dom.form(FORM_ATTR): with dom.div(cls=LABEL_CARD): dom.label('Write down your mark here', cls="text-white text-xl") dom.input( cls=LABEL_INPUT, type='text', placeholder='your watermark text here', name='mk-text') with dom.div(cls=IMG_CARD): with dom.div(cls=IMG_FORM): dom.i(cls=UPLOAD_ICON, onclick='''$('#fileupload').click()''') dom.p("Find File", id="file", cls="text-gray-500 mt-4") dom.input(cls="hidden", type="file", name='bg-img', id="fileupload", onchange='''$('#file').text(this.value.split("\\\\").pop(-1))''') dom.button('Upload', cls=BUTTON, type='submit') with dom.div(cls=RESULT_CONTAINER, id="there") as ResultContainer: dom.span(id="here") return doc.render()
def Item(file_name): with dom.div(cls=RESULT_ITEM) as ResultItem: dom.p(f"{ file_name }.jpg", cls="text-xl text-gray-400") with dom.a(href=f"/download?filename={file_name}"): dom.i(cls="fas fa-download text-xl text-gray-400") return ResultItem.render() + dom.span(id="here").render()
def page(): doc = document() with doc.head: link_("https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css") link_("https://extra-uru1z3cxu.now.sh/css/extra.css") link_("https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.8.2/css/all.css") dom.script(src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js') with doc.body: with dom.div(cls=CENTER_FRAME)as CenterFrame: with dom.div(cls=CARD) as Card: with dom.form(cls=UPLOAD_FORM) as UploadForm: dom.i(cls=UPLOAD_ICON,onclick=''' $('#fileupload').click()''') dom.p("Find File",id =1,cls="text-gray-500 mt-4") dom.button("Upload",cls=BUTTON) dom.input(cls='hidden',type="file",id="fileupload",onchange=''' $('#1').text(this.value.split("\\\\").pop(-1))''') with dom.div(cls=RESULT_CONTAINER) as ResultContainer: for _ in range(4): with dom.div(cls=RESULT_ITEM) as ResultItem: dom.p("filename.jpg",cls="text-xl text-gray-400") dom.i(cls="fas fa-download text-xl text-gray-400") with dom.div() as ResultContainer: pass return doc.render()
def _report_links(tests): if not tests: i("None!") return with table(border=1): with tr(): th("Link to report") for test in sorted(tests): with tr(): path = test.relative_to(REPORTS_PATH) td(a(test.name, href=path))
def image(src: Path) -> None: with td(): if src: # open image file image = src.read_bytes() # encode image as base64 image = base64.b64encode(image) # convert output to str image = image.decode() # img(src=src.relative_to(fixture_test_path)) img(src="data:image/png;base64, " + image) else: i("missing")
def report_links(tests, reports_path, actual_hashes=None): if actual_hashes is None: actual_hashes = {} if not tests: i("None!") return with table(border=1): with tr(): th("Link to report") for test in sorted(tests): with tr(data_actual_hash=actual_hashes.get(test.stem, "")): path = test.relative_to(reports_path) td(a(test.name, href=path))
def build_discrepancy_parent_report(discrepancy_reports): version = utils.show_version() doc = dominate.document(title='Audit Engine version: ' + version) report_head(doc) discrepancy_reports.sort(key=itemgetter('discrepancy', 'ballots'), reverse=True) with doc: with div(cls='container'): report_headline(version) with table(cls='table table-striped'): with thead(): with tr(): th('#', scope="col") th('Precinct', scope="col") th('Ballots total', scope="col") th('Discrepancy', scope="col") th('Report', scope="col") with tbody(): for index, report in enumerate(discrepancy_reports): with tr(): report_abs_path = os.path.abspath( report.get('path')) th(index + 1) td(report.get('precinct')) td(report.get('ballots')) td(f"{report.get('discrepancy')}%") td( a(i(cls='far fa-file-alt'), href=report_abs_path, targer='_blank')) return doc
def visit_Subgroup(self, node): if not self._in_dropdown: li = tags.li(_class='dropdown') if node.active: li['class'] = 'active' a = li.add(tags.a(href='#', _class='dropdown-toggle')) if node.icon is not None: a.add(tags.i(_class=str(node.icon))) a.add(tags.span(node.title)) else: a.add_raw_string(node.title) a['data-toggle'] = 'dropdown' a['role'] = 'button' a['aria-haspopup'] = 'true' a['aria-expanded'] = 'false' a.add(tags.span(_class='caret')) ul = li.add(tags.ul(_class='dropdown-menu')) self._in_dropdown = True for item in node.items: ul.add(self.visit(item)) self._in_dropdown = False return li else: raise RuntimeError('Cannot render nested Subgroups')
def post(self, id): context = {u'model': model} data_dict = logic.clean_dict( dictization_functions.unflatten( logic.tuplize_dict(logic.parse_params(request.form)))) data_dict[u'user'] = id try: token = logic.get_action(u'api_token_create')(context, data_dict)[u'token'] except logic.NotAuthorized: base.abort(403, _(u'Unauthorized to create API tokens.')) except logic.ValidationError as e: errors = e.error_dict error_summary = e.error_summary return self.get(id, data_dict, errors, error_summary) copy_btn = dom_tags.button( dom_tags.i(u'', {u'class': u'fa fa-copy'}), { u'type': u'button', u'class': u'btn btn-default btn-xs', u'data-module': u'copy-into-buffer', u'data-module-copy-value': ensure_str(token) }) h.flash_success( _(u"API Token created: <code style=\"word-break:break-all;\">" u"{token}</code> {copy}<br>" u"Make sure to copy it now, " u"you won't be able to see it again!").format( token=ensure_str(token), copy=copy_btn), True) return h.redirect_to(u'user.api_tokens', id=id)
def genrow(self): """Generate the html row.""" tags.td(tags.code(self.format, self.version), align='center', __pretty=False) tags.td(tags.i(raw(self.hexport)), align='center', __pretty=False) tags.td(tags.code(self.himport), align='center', __pretty=False)
def visit_Search(self, node): form = tags.form(target="_blank", method="get", role="search") form['role'] = 'search' form[ 'class'] = 'navbar-form navbar-right' if node.navbar_right else 'navbar-form navbar-left' # action may also have a 'get_url()' method, in which case we render if node.action is not None: if hasattr(node.action, 'get_url'): form['action'] = node.action.get_url() else: form['action'] = node.action div = form.add(tags.div(_class='form-group')) search_input = div.add( tags.input(type="text", _class="form-control", placeholder=node.input_placeholder)) if node.input_id is not None: search_input['id'] = node.input_id if node.input_name is not None: search_input['name'] = node.input_name btn = form.add(tags.button(type="submit", _class="btn btn-default")) if node.icon is not None: btn.add(tags.i(_class=str(node.icon))) if node.btn_text is not None: btn.add(tags.span(node.btn_text)) return form
def page(): doc = document() with doc.head: link_("https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css") link_("https://extra-uru1z3cxu.now.sh/css/extra.css") link_( "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.8.2/css/all.css" ) dom.script( src= 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js' ) with doc.body: with dom.div(cls=CENTER_FRAME) as CenterFrame: with dom.form(action='/file', method='post', enctype='multipart/form-data'): with dom.div(cls=LABEL_CARD): dom.label('Write down your mark here', cls="text-white text-xl") dom.input(cls=LABEL_INPUT, type='text', placeholder='your watermark text here', name='mk-text') with dom.div(cls=IMG_CARD): with dom.div(cls=IMG_FORM): dom.i(cls=UPLOAD_ICON, onclick='''$('#fileupload').click()''') dom.p("Find File", id="file", cls="text-gray-500 mt-4") dom.input( cls="hidden", type="file", name='bg-img', id="fileupload", onchange= '''$('#file').text(this.value.split("\\\\").pop(-1))''' ) dom.button('Upload', cls=BUTTON, type='submit') with dom.div(cls=RESULT_CONTAINER) as ResultContainer: for _ in range(4): with dom.div(cls=RESULT_ITEM) as ResultItem: dom.p("filename.jpg", cls="text-xl text-gray-400") dom.i(cls="fas fa-download text-xl text-gray-400") return doc.render()
def visit_View(self, node): item = tags.li() a = item.add(tags.a(node.text, href=node.get_url(), title=node.text)) if hasattr(node, 'icon') and node.icon != None: a.add(tags.i(_class='fa fa-fw fa-%s' % node.icon)) if node.active: item['class'] = 'active' return item
def clubmembers_filters(): pretablehtml = div() with pretablehtml: # hide / show hidden rows with filtercontainerdiv(style='margin-bottom: 4px;'): datefilter = filterdiv('fsrcmembers-external-filter-asof', 'As Of') with datefilter: with span(id='spinner', style='display:none;'): i(cls='fas fa-spinner fa-spin') input(type='text', id='effective-date', name='effective-date') button('Today', id='todays-date-button') cachetime = TableUpdateTime.query.filter_by( interest=localinterest(), tablename='member').one().lastchecked span(f'(last update time {cachet.dt2asc(cachetime)})') # filterdiv('members-external-filter-level', 'Levels') return pretablehtml.render()
def image(src: Path, image_width: Optional[int] = None) -> None: with td(): if src: # open image file image = src.read_bytes() # encode image as base64 image = base64.b64encode(image) # convert output to str image = image.decode() # img(src=src.relative_to(fixture_test_path)) img( src="data:image/png;base64, " + image, style=f"width: {image_width}px; image-rendering: pixelated;" if image_width else "", ) else: i("missing")
def visit_Link(self, node): a = tags.a(href=node.get_url()) if node.icon is not None: a.add(tags.i(_class=str(node.icon))) a.add(tags.span(node.text)) else: a.add_raw_string(node.text) li = tags.li() li.add(a) return li
def index(): removed = list((REPORTS_PATH / "removed").iterdir()) added = list((REPORTS_PATH / "added").iterdir()) diff = list((REPORTS_PATH / "diff").iterdir()) title = "UI changes from master" doc = dominate.document(title=title) with doc: h1("UI changes from master") hr() h2("Removed:", style="color: red;") i("UI fixtures that have been removed:") html.report_links(removed, REPORTS_PATH) br() hr() h2("Added:", style="color: green;") i("UI fixtures that have been added:") html.report_links(added, REPORTS_PATH) br() hr() h2("Differs:", style="color: grey;") i("UI fixtures that have been modified:") html.report_links(diff, REPORTS_PATH) return html.write(REPORTS_PATH, doc, "index.html")
def visit_View(self, node): a = tags.a(href=node.get_url(), title=node.text) if node.icon is not None: a.add(tags.i(_class=str(node.icon))) a.add(tags.span(node.text)) else: a.add_raw_string(node.text) item = tags.li() item.add(a) if node.active: item['class'] = 'active' return item
def get_html(self): """overrides the base class function""" html_string = super(GenericFileMetaDataMixin, self).get_html() if not self.has_metadata: no_metadata_message = div(id="#fb-metadata-default", cls="text-center text-muted", role="alert") with no_metadata_message: div("No file level metadata exists for the selected file.") hr() i_tag = i(cls="fa fa-eye-slash fa-2x") i_tag['aria-hidden'] = 'true' html_string = no_metadata_message.render() else: if self.temporal_coverage: html_string += self.temporal_coverage.get_html() if self.spatial_coverage: html_string += self.spatial_coverage.get_html() template = Template(html_string) context = Context({}) return template.render(context)
def report_footer(self, message='', **kwargs): """ Returns the footer object. Supports social media :param str message: A message in the footer :param str twitter: Kwarg Twitter link :param str github: Kwarg Github link :param str linkedin: Kwarg LinkedIn link :param str email: Kwarg email address :param str custom_html: Insert raw html to be added to the end of the section Example with some social media: >>> r += report.report_footer(message='securisec', twitter='https://twitter.com/securisec') """ # creates the footer with tag.footer(_class="page-footer reportng-footer-class") as footer: with tag.div(_class="container"): with tag.div(_class="row"): with tag.div(_class="mb-4"): # Looks through valid kwargs and creates appropiate a tag for key, value in sorted(kwargs.items()): if key == 'twitter': tag.a( _class="icons-sm tw-ic", href=value, target="_blank" ).add( tag. i(_class= "fab fa-twitter fa-2x white-text mr-md-4" )) elif key == 'github': tag.a( _class="icons-sm gh-ic", href=value, target="_blank" ).add( tag. i(_class= "fab fa-github fa-2x white-text mr-md-4") ) elif key == 'linkedin': tag.a( _class="icons-sm li-ic", href=value, target="_blank" ).add( tag. i(_class= "fab fa-linkedin fa-2x white-text mr-md-4" )) elif key == 'email': tag.a(_class="icons-sm", href=value).add( tag.i( _class= "fas fa-at fa-2x white-text mr-md-4")) # i tag for user message tag.span(message, style="font-size: 125%;") if 'custom_html' in kwargs: raw(kwargs.get('custom_html')) return str(footer)
def visualization_html(header, data, metrics): challenges = data.keys() # geometry_options = { # "margin": "1.5in", # "headheight": "20pt", # "headsep": "10pt", # "includeheadfoot": True # } # doc = Document(header, page_numbers=True, geometry_options=geometry_options) file_path = os.path.join(os.getcwd(), 'evaluation_results.html') if os.path.isfile(file_path): os.remove(file_path) doc1 = dominate.document(title='Tracking Evaluator') with doc1: with div(): attr(cls='body') h1('Evaluation Results') with div(): h2('Results table') tags.style(".calendar_table{width:880px;}") tags.style("body{font-family:Helvetica}") tags.style("h1{font-size:x-large}") tags.style("h2{font-size:large}") tags.style("table{border-collapse:collapse}") tags.style( "th{font-size:small;border:1px solid gray;padding:4px;background-color:#DDD}" ) tags.style( "td{font-size:small;text-align:center;border:1px solid gray;padding:4px}" ) with tags.table(): with tags.thead(): tags.th("Challenge", style="color:#ffffff;background-color:#6A75F2") tags.th("Tracker", style="color:#ffffff;background-color:#6A75F2") for m in metrics: tags.th(m, style="color:#ffffff;background-color:#6A75F2") with tags.tbody(): for c in challenges: with tags.tr(): #New row Challenges tags.td( c, style= "font-size:small;text-align:center;padding:4px" ) for t in trackers: if data[c][t]: with tags.tr(): #New row Data per tracker tags.td( ' ', style= "font-size:small;text-align:center;padding:4px" ) tags.td( t, style= "font-size:small;text-align:center;padding:4px" ) if 'Accuracy' in metrics: tags.td( data[c][t]['tracker_acc'], style= "font-size:small;text-align:center;padding:4px" ) if 'Robustness' in metrics: tags.td( data[c][t]['tracker_robust'], style= "font-size:small;text-align:center;padding:4px" ) if 'Precision(Center Location Error)' in metrics: tags.td( data[c][t]['tracker_precision'], style= "font-size:small;text-align:center;padding:4px" ) with div(): h2('Graphs') for graph in plot_list: tags.img(src=graph, style='max-width:700px;margin-top: 50px;') tags.br() if frame_list: for c in challenges: if frame_list[c]: for t in frame_list[c].keys(): with figure(): h3('Low Frames for tracker: %s' % t + ' challenge: %s' % c) for i in range(len(frame_list[c][t])): tags.img(src=frame_list[c][t][i][0], style="width:340px;margin-top: 50px") tags.i(frame_list[c][t][i][1]) f = open(file_path, 'w') f.write(doc1.render()) f.close()
def profile_to_html(profile_info): html_body = body() with html_body: with section(_class="leading animated fadeInDown"): with a(href='/'): p(profile_info['personal_info']['name'], _class="leading-bigtext") p(profile_info['personal_info']['summary'][:-4], _class="leading-text") for section_title in ['education', 'jobs', 'volunteering']: with section(_class=f"cards animated fadeInUp {section_title}"): div(section_title, _class='section-title') roles = profile_info['experiences'][section_title] for role in roles: if len(set(role.values())) > 1: with article(): with div(_class='cventry'): if section_title == "jobs": with div(_class='entry-header'): div(role['title'], _class='entry-title') div(role['date_range'], _class='entry-date') with div(_class="entry-subheader"): div(role['company'], _class='entry-organisation') div(role['location'], _class='entry-location') with div(_class='entry-body'): split = role['description'].split('- ') if len(split) > 1: with ul(): for para in split[1:]: li(para) else: p(role['description']) elif section_title == "education": with div(_class='entry-header'): div(role['name'], _class='entry-title') div(role['date_range'], _class='entry-date') with div(_class="entry-subheader"): div(role['field_of_study'], _class='entry-organisation') with div(_class='entry-location'): span(role['degree']) if role['grades'] != '' and role[ 'degree'] != '': span(', ') i(f"{role['grades']}", style="font-weight:300") with div(_class='entry-body'): split = role['description'].split('- ') if len(split) > 1: with ul(): for para in split[1:]: li(para) else: p(role['description']) elif section_title == "volunteering": with div(_class='entry-header'): div(role['title'], _class='entry-title') div(role['date_range'], _class='entry-date') with div(_class="entry-subheader"): div(role['company'], _class='entry-organisation') # div(role['cause'], _class='entry-location') with div(_class='entry-body'): split = role['description'].split('- ') if len(split) > 1: with ul(): for para in split[1:]: li(para) else: p(role['description']) with section(_class="cards animated fadeInDown skills"): div('skills', _class='section-title') with article(): for skill in profile_info['skills']: div(skill['name'], _class='skill') return str(html_body)
def i(n): return tags.i(cls=f"fas fa-{n}")
def add_italics(self, line): self.add_paragraph() self.paragraph += tags.i(self.remove_operator(line))
def getHTML(title, info=None, body=None, style=None, state=None, theme=None, icon=None): """Provide HTML object :param str title: short name of the notification, e.g.: server error :param str info: some short description if needed, e.g.: It looks like the server is not responding :param body: it can be string or dominate tag object, e.g.: from dominate import tags as dom return getHTML('server error', body=dom.pre(dom.code(result['Message'])) :param str style: additional css style if needed, e.g.: '.card{color:red;}' :param int state: response state code, if needed, e.g.: 404 :param str theme: message color theme, the same that in bootstrap 5, e.g.: 'warning' :param str icon: awesome icon name, e.g.: 'users' :return: str -- HTML document """ html = document("DIRAC - %s" % title) # select the color to the state code if state in [400, 401, 403, 404]: theme = theme or "warning" elif state in [500]: theme = theme or "danger" elif state in [200]: theme = theme or "success" # select the icon to the theme if theme in ["warning", "warn"]: theme = "warning" icon = icon or "exclamation-triangle" elif theme == "info": icon = icon or "info" elif theme == "success": icon = icon or "check" elif theme in ["error", "danger"]: theme = "danger" icon = icon or "times" else: theme = theme or "secondary" icon = icon or "flask" # If body is text wrap it with tags if body and isinstance(body, six.string_types): body = dom.pre( dom.code(traceback.format_exc() if body == "traceback" else body), cls="mt-5") try: diracLogo = collectMetadata(ignoreErrors=True).get("logoURL", "") except Exception: diracLogo = "" # Create head with html.head: # Meta tags dom.meta(charset="utf-8") dom.meta(name="viewport", content="width=device-width, initial-scale=1") # Favicon dom.link(rel="shortcut icon", href="/static/core/img/icons/system/favicon.ico", type="image/x-icon") # Provide awesome icons # https://fontawesome.com/v4.7/license/ dom.script( src= "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/js/all.min.js" ) # Enable bootstrap 5 # https://getbootstrap.com/docs/5.0/getting-started/introduction/ # https://getbootstrap.com/docs/5.0/about/license/ dom.link( rel="stylesheet", integrity= "sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC", href= "https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css", crossorigin="anonymous", ) dom.script( src= "https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js", integrity= "sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM", crossorigin="anonymous", ) # Provide additional css style = ".card{transition:.3s;}.card:hover{transform:scale(1.03);}" + ( style or "") dom.style(style) # Create body with html: # Background image dom.i( cls="position-absolute bottom-0 start-0 translate-middle-x m-5 fa " "fa-%s text-%s" % (icon, theme), style="font-size:40vw;z-index:-1;", ) # A4 page with align center with dom.div( cls= "row vh-100 vw-100 justify-content-md-center align-items-center m-0" ): with dom.div(cls="container", style="max-width:600px;") as page: # Main panel with dom.div(cls="row align-items-center"): # Logo dom.div(dom.img(src=diracLogo, cls="card-img px-2"), cls="col-md-6 my-3") # Information card with dom.div(cls="col-md-6 my-3"): # Show response state number if state and state != 200: dom.div(dom.h1( state, cls="text-center badge bg-%s text-wrap" % theme), cls="row py-2") # Message title with dom.div(cls="row"): dom.div(dom.i(cls="fa fa-%s text-%s" % (icon, theme)), cls="col-auto") dom.div(title, cls="col-auto ps-0 pb-2 fw-bold") # Description if info: dom.small(dom.i(cls="fa fa-info text-info")) dom.small(info, cls="ps-1") # Add content if body: page.add(body) return html.render()