docs: private void buildField(
          Map<String, CmsClientProperty> ownProps,
          final String propName,
          CmsClientProperty.Mode mode,
          CmsUUID id) {
  
          CmsXmlContentProperty propDef = m_propertyConfig.get(propName);
  
          if (propDef == null) {
              String widget = CmsClientProperty.PROPERTY_TEMPLATE.equals(propName) ? "template" : "string";
              propDef = new CmsXmlContentProperty(
                  propName,
                  "string",
                  widget,
                  "",
                  null,
                  null,
                  null,
                  null,
                  null,
                  null,
                  null);
          }
  
          if (mode != Mode.effective) {
              propDef = propDef.withNiceName(propName);
          }
  
          CmsClientProperty ownProp = ownProps.get(propName);
          CmsPathValue pathValue = CmsClientProperty.getPathValue(ownProp, mode).prepend(id + "/" + propName + "/");
  
          //CHECK: should fields other than NavText be really automatically allowed to be empty in navigation mode?
          CmsBasicFormField field = CmsBasicFormField.createField(
              propDef,
              pathValue.getPath(),
              this,
              Collections.<String, String> emptyMap(),
              true);
  
          CmsPair<String, String> defaultValueAndOrigin = getDefaultValueToDisplay(ownProp, mode);
          String defaultValue = "";
          String origin = "";
          if (defaultValueAndOrigin != null) {
              defaultValue = defaultValueAndOrigin.getFirst();
              origin = defaultValueAndOrigin.getSecond();
          }
          Widget w = (Widget)field.getWidget();
          I_CmsStringModel model = getStringModel(pathValue);
          field.bind(model);
          boolean ghost = CmsStringUtil.isEmptyOrWhitespaceOnly(pathValue.getValue());
          String initialValue = pathValue.getValue();
          if (w instanceof I_CmsHasGhostValue) {
              ((I_CmsHasGhostValue)w).setGhostValue(defaultValue, ghost);
              if (ghost) {
                  initialValue = null;
              }
          }
  
          boolean isShowingGhost = ghost && !CmsStringUtil.isEmpty(defaultValue);
  
          if (isShowingGhost) {
              field.getLayoutData().put("info", origin);
          }
          if (!ghost || isShowingGhost) {
              field.getLayoutData().put(CmsPropertyPanel.LD_DISPLAY_VALUE, "true");
          }
          field.getLayoutData().put(CmsPropertyPanel.LD_PROPERTY, propName);
          m_form.addField(field, initialValue);
      }