def create_layout_element(lh, name, **kw):

    if settings.SITE.catch_layout_exceptions:
        try:
            de = lh.get_data_elem(name)
        except Exception as e:
            # logger.exception(e) removed 20130422 because it caused
            # disturbing output when running tests
            de = None
            name += " (" + str(e) + ")"
    else:
        de = lh.get_data_elem(name)

    if de is None:
        # If the plugin has been hidden, we want the element to simply
        # disappear, similar as if the user had no view permission.
        s = name.split('.')
        if len(s) == 2:
            if settings.SITE.is_hidden_app(s[0]):
                return None
        # ctx = (lh.layout.__class__, name, ', '.join(dir(lh.layout)))
        # raise Exception(
        #     "Instance of %s has no data element '%s' (names are %s)" % ctx)
        raise Exception("{0} has no data element '{1}'".format(
            lh.layout, name))

    if isinstance(de, type) and issubclass(de, fields.Dummy):
        return None

    if isinstance(de, DummyPanel):
        return None

    if isinstance(de, fields.DummyField):
        lh.add_store_field(de)
        return None

    if isinstance(de, fields.Constant):
        return ConstantElement(lh, de, **kw)

    if isinstance(de, fields.RemoteField):
        return create_field_element(lh, de, **kw)

    if isinstance(de, SingleRelatedObjectDescriptor):
        return SingleRelatedObjectElement(lh, de.related, **kw)

    if isinstance(de, (
            ManyRelatedObjectsDescriptor, ForeignRelatedObjectsDescriptor)):
        e = ManyRelatedObjectElement(lh, de.related, **kw)
        lh.add_store_field(e.field)
        return e

    if isinstance(de, models.ManyToManyField):
        e = ManyToManyElement(lh, de.related, **kw)
        lh.add_store_field(e.field)
        return e

    if AFTER17:
        if isinstance(de, (ManyToManyRel, ManyToOneRel)):
            e = ManyRelatedObjectElement(lh, de, **kw)
            lh.add_store_field(e.field)
            return e

    if isinstance(de, models.Field):
        if isinstance(de, (BabelCharField, BabelTextField)):
            if len(settings.SITE.BABEL_LANGS) > 0:
                elems = [create_field_element(lh, de, **kw)]
                for lang in settings.SITE.BABEL_LANGS:
                    bf = lh.get_data_elem(name + lang.suffix)
                    elems.append(create_field_element(lh, bf, **kw))
                return elems
        return create_field_element(lh, de, **kw)

    if isinstance(de, GenericForeignKey):
        # create a horizontal panel with 2 comboboxes
        de.primary_key = False  # for ext_store.Store()
        lh.add_store_field(de)
        return GenericForeignKeyElement(lh, de, **kw)

    if isinstance(de, type) and issubclass(de, tables.AbstractTable):
        # The data element refers to a slave table. Slave tables make
        # no sense in an insert window because the master does not yet
        # exist.
        kw.update(master_panel=js_code("this"))
        
        if isinstance(lh.layout, FormLayout):
            # When a table is specified in the layout of a
            # DetailWindow, then it will be rendered as a panel that
            # displays a "summary" of that table. The panel will have
            # a tool button to "open that table in its own
            # window". The format of that summary is defined by the
            # `slave_grid_format` of the table. `slave_grid_format` is
            # a string with one of the following values:

            kw.update(tools=[
                js_code("Lino.show_in_own_window_button(Lino.%s)" %
                      de.default_action.full_name())])
            if de.slave_grid_format == 'grid':
                kw.update(hide_top_toolbar=True)
                if de.preview_limit is not None:
                    kw.update(preview_limit=de.preview_limit)
                return GridElement(lh, name, de, **kw)

            elif de.slave_grid_format == 'html':
                if de.editable:
                    a = de.insert_action
                    if a is not None:
                        kw.update(ls_insert_handler=js_code("Lino.%s" %
                                  a.full_name()))
                        kw.update(ls_bbar_actions=[
                            settings.SITE.plugins.extjs.renderer.a2btn(a)])
                field = fields.HtmlBox(verbose_name=de.label)
                field.name = de.__name__
                field.help_text = de.help_text
                field._return_type_for_method = de.slave_as_html_meth()
                lh.add_store_field(field)
                e = HtmlBoxElement(lh, field, **kw)
                e.add_requirements(*de.required_roles)
                return e

            elif de.slave_grid_format == 'summary':
                e = SlaveSummaryPanel(lh, de, **kw)
                lh.add_store_field(e.field)
                return e
            else:
                raise Exception(
                    "Invalid slave_grid_format %r" % de.slave_grid_format)

        else:
            e = SlaveSummaryPanel(lh, de, **kw)
            lh.add_store_field(e.field)
            return e

    if isinstance(de, fields.VirtualField):
        return create_vurt_element(lh, name, de, **kw)

    if callable(de):
        rt = getattr(de, 'return_type', None)
        if rt is not None:
            return create_meth_element(lh, name, de, rt, **kw)

    # Now we tried everything. Build an error message.

    if hasattr(lh, 'rh'):
        msg = "Unknown element '%s' (%r) referred in layout <%s of %s>." % (
            name, de, lh.layout, lh.rh.actor)
        l = [wde.name for wde in lh.rh.actor.wildcard_data_elems()]
        # VirtualTables don't have a model
        model = getattr(lh.rh.actor, 'model', None)
        if getattr(model, '_lino_slaves', None):
            l += [str(rpt) for rpt in list(model._lino_slaves.values())]
        msg += " Possible names are %s." % ', '.join(l)
    else:
        msg = "Unknown element '%s' (%r) referred in layout <%s>." % (
            name, de, lh.layout)
        # if de is not None:
        #     msg += " Cannot handle %r" % de
    raise KeyError(msg)
Create a layout element from the named data element.
dataset/ETHPy150Open lsaffre/lino/lino/modlib/extjs/elems.py/create_layout_element