/**
   * Returns SearchResultSelections that are accessible to the specified {@link ToolUser},
   * optionally excluding selections that were created by the user.
   *
   * @param user the {@link ToolUser} for which SearchResultSelections should be returned.
   * @param excludeOwn excludes selections created by the specified {@link ToolUser} if true.
   * @return accessible {@link SearchResultSelection}s for the specified {@link ToolUser}.
   */
  public static List<SearchResultSelection> findAccessibleSelections(
      ToolUser user, boolean excludeOwn) {

    if (user == null) {
      return null;
    }

    Query<SearchResultSelection> query = Query.from(SearchResultSelection.class);

    if (user.getRole() == null) {
      query.where("entities != missing");
    } else {
      query.where("entities = ?", user.getRole());
    }

    if (excludeOwn) {
      query.and("entities != ?", user);
    } else {
      query.or("entities = ?", user);
    }

    return query.selectAll();
  }
예제 #2
0
  @Override
  public void doService(ToolPageContext page) throws IOException, ServletException {
    ToolUser user = page.getUser();
    Dashboard dashboard = user.getDashboard();
    String dashboardId = "user";

    if (dashboard == null) {
      ToolRole role = user.getRole();

      if (role != null) {
        dashboard = role.getDashboard();
        dashboardId = "role";
      }
    }

    if (dashboard == null) {
      dashboard = page.getCmsTool().getDefaultDashboard();
      dashboardId = "tool";
    }

    if (dashboard == null) {
      dashboard = Dashboard.createDefaultDashboard();
      dashboardId = "default";
    }

    page.writeHeader();
    page.writeStart("div", "class", "dashboard-columns");
    List<DashboardColumn> columns = dashboard.getColumns();
    double totalWidth = 0;

    for (DashboardColumn column : columns) {
      double width = column.getWidth();
      totalWidth += width > 0 ? width : 1;
    }

    CmsTool cms = Query.from(CmsTool.class).first();
    Set<String> disabled = cms != null ? cms.getDisabledPlugins() : Collections.emptySet();

    for (int c = 0, cSize = columns.size(); c < cSize; ++c) {
      DashboardColumn column = columns.get(c);
      double width = column.getWidth();

      page.writeStart(
          "div",
          "class",
          "dashboard-column",
          "style",
          page.cssString("width", ((width > 0 ? width : 1) / totalWidth * 100) + "%"));

      List<DashboardWidget> widgets = column.getWidgets();

      for (int w = 0, wSize = widgets.size(); w < wSize; ++w) {
        DashboardWidget widget = widgets.get(w);

        if (disabled.contains(widget.getClass().getName())) {
          continue;
        }

        String widgetUrl =
            page.toolUrl(
                CmsTool.class,
                "/dashboardWidget/"
                    + dashboardId
                    + "/"
                    + widget.getClass().getName()
                    + "/"
                    + widget.getId());

        page.writeStart(
            "div", "class", "frame dashboard-widget", "data-dashboard-widget-url", widgetUrl);
        page.writeStart("a", "href", widgetUrl);
        page.writeEnd();
        page.writeEnd();
      }
      page.writeEnd();
    }
    page.writeEnd();
    page.writeFooter();
  }
  protected void writeTableHtml(Iterable<?> items) throws IOException {
    HttpServletRequest request = page.getRequest();

    page.putOverride(
        Recordable.class,
        (HtmlWriter writer, Recordable object) -> {
          ToolPageContext page = (ToolPageContext) writer;

          page.writeObjectLabel(object);
        });

    page.putOverride(
        Metric.class,
        (HtmlWriter writer, Metric object) -> {
          writer.write(Double.toString(object.getSum()));
        });

    page.putOverride(
        Content.class,
        (HtmlWriter writer, Content content) -> {
          ToolPageContext page = (ToolPageContext) writer;

          page.writeStart(
              "a", "href", page.objectUrl("/content/edit.jsp", content), "target", "_top");
          page.writeObjectLabel(content);
          page.writeEnd();
        });

    page.putOverride(
        StorageItem.class,
        (HtmlWriter writer, StorageItem item) -> {
          ToolPageContext page = (ToolPageContext) writer;

          page.writeElement(
              "img",
              "height",
              100,
              "src",
              ImageEditor.Static.getDefault() != null
                  ? new ImageTag.Builder(item).setHeight(100).toUrl()
                  : item.getPublicUrl());
        });

    page.writeStart("table", "class", "searchResultTable links table-striped pageThumbnails");
    page.writeStart("thead");
    page.writeStart("tr");
    page.writeStart("th");
    page.writeElement("input", "type", "checkbox", "class", "searchResult-checkAll");
    page.writeEnd();

    if (sortField != null && ObjectField.DATE_TYPE.equals(sortField.getInternalType())) {

      page.writeStart("th", "colspan", 2);
      page.writeHtml(sortField.getDisplayName());
      page.writeEnd();
    }

    if (showSiteLabel) {
      page.writeStart("th");
      page.writeHtml(page.localize(ListSearchResultView.class, "label.site"));
      page.writeEnd();
    }

    if (showTypeLabel) {
      page.writeStart("th");
      page.writeHtml(page.localize(ListSearchResultView.class, "label.type"));
      page.writeEnd();
    }

    page.writeStart("th");
    page.writeHtml(page.localize(ListSearchResultView.class, "label.label"));
    page.writeEnd();

    if (sortField != null && !ObjectField.DATE_TYPE.equals(sortField.getInternalType())) {

      page.writeStart("th");
      page.writeHtml(sortField.getDisplayName());
      page.writeEnd();
    }

    ToolUser user = page.getUser();

    if (user != null) {
      ObjectType selectedType = search.getSelectedType();
      List<String> fieldNames =
          user.getSearchResultFieldsByTypeId()
              .get(selectedType != null ? selectedType.getId().toString() : "");

      if (fieldNames == null) {
        for (Class<? extends SearchResultField> c :
            ClassFinder.Static.findClasses(SearchResultField.class)) {
          if (!c.isInterface() && !Modifier.isAbstract(c.getModifiers())) {
            SearchResultField field = TypeDefinition.getInstance(c).newInstance();

            if (field.isDefault(selectedType) && !ObjectUtils.equals(sortField, field)) {
              field.writeTableHeaderCellHtml(page);
            }
          }
        }

        if (selectedType != null) {
          for (ObjectField field : selectedType.getFields()) {
            if (Boolean.TRUE.equals(field.as(ToolUi.class).getDefaultSearchResult())) {
              writeHeaderCell(field);
            }
          }
        }

      } else {
        for (String fieldName : fieldNames) {
          Class<?> fieldNameClass = ObjectUtils.getClassByName(fieldName);

          if (fieldNameClass != null && SearchResultField.class.isAssignableFrom(fieldNameClass)) {
            @SuppressWarnings("unchecked")
            SearchResultField field =
                TypeDefinition.getInstance((Class<? extends SearchResultField>) fieldNameClass)
                    .newInstance();

            if (field.isSupported(selectedType) && !ObjectUtils.equals(sortField, field)) {
              field.writeTableHeaderCellHtml(page);
            }

          } else {
            ObjectField field = null;
            if (selectedType != null) {
              field = selectedType.getField(fieldName);
            }

            if (field == null) {
              field = Database.Static.getDefault().getEnvironment().getField(fieldName);
            }

            if (field != null && !ObjectUtils.equals(sortField, field)) {
              writeHeaderCell(field);
            }
          }
        }
      }
    }
    page.writeEnd();
    page.writeEnd();

    page.writeStart("tbody");
    for (Object item : items) {
      State itemState = State.getInstance(item);
      String permalink = itemState.as(Directory.ObjectModification.class).getPermalink();
      Integer embedWidth = null;

      if (ObjectUtils.isBlank(permalink)) {
        ObjectType type = itemState.getType();

        if (type != null) {
          Renderer.TypeModification rendererData = type.as(Renderer.TypeModification.class);
          int previewWidth = rendererData.getEmbedPreviewWidth();

          if (previewWidth > 0 && !ObjectUtils.isBlank(rendererData.getEmbedPath())) {

            permalink = "/_preview?_embed=true&_cms.db.previewId=" + itemState.getId();
            embedWidth = 320;
          }
        }
      }

      page.writeStart(
          "tr",
          "data-preview-url",
          permalink,
          "data-preview-embed-width",
          embedWidth,
          "class",
          State.getInstance(item).getId().equals(page.param(UUID.class, "id")) ? "selected" : null);

      page.writeStart("td");
      itemWriter.writeCheckboxHtml(page, search, item);
      page.writeEnd();

      if (sortField != null && ObjectField.DATE_TYPE.equals(sortField.getInternalType())) {

        DateTime dateTime = page.toUserDateTime(itemState.getByPath(sortField.getInternalName()));

        if (dateTime == null) {
          page.writeStart("td", "colspan", 2);
          page.writeHtml("N/A");
          page.writeEnd();

        } else {
          String date = page.formatUserDate(dateTime);

          page.writeStart("td", "class", "date");
          if (!ObjectUtils.equals(date, request.getAttribute(PREVIOUS_DATE_ATTRIBUTE))) {
            request.setAttribute(PREVIOUS_DATE_ATTRIBUTE, date);
            page.writeHtml(date);
          }
          page.writeEnd();

          page.writeStart("td", "class", "time");
          page.writeHtml(page.formatUserTime(dateTime));
          page.writeEnd();
        }
      }

      if (showSiteLabel) {
        page.writeStart("td");
        page.writeObjectLabel(itemState.as(Site.ObjectModification.class).getOwner());
        page.writeEnd();
      }

      if (showTypeLabel) {
        page.writeStart("td");
        page.writeTypeLabel(item);
        page.writeEnd();
      }

      page.writeStart("td", "data-preview-anchor", "");
      itemWriter.writeBeforeHtml(page, search, item);
      page.writeObjectLabel(item);
      itemWriter.writeAfterHtml(page, search, item);
      page.writeEnd();

      if (sortField != null && !ObjectField.DATE_TYPE.equals(sortField.getInternalType())) {

        String sortFieldName = sortField.getInternalName();
        Object value = itemState.getByPath(sortFieldName);

        page.writeStart("td");
        if (value instanceof Metric) {
          page.writeStart("span", "style", page.cssString("white-space", "nowrap"));
          Double maxSum = (Double) request.getAttribute(MAX_SUM_ATTRIBUTE);

          if (maxSum == null) {
            Object maxObject = search.toQuery(page.getSite()).sortDescending(sortFieldName).first();
            maxSum =
                maxObject != null
                    ? ((Metric) State.getInstance(maxObject).get(sortFieldName)).getSum()
                    : 1.0;

            request.setAttribute(MAX_SUM_ATTRIBUTE, maxSum);
          }

          Metric valueMetric = (Metric) value;
          Map<DateTime, Double> sumEntries =
              valueMetric.groupSumByDate(
                  new MetricInterval.Daily(),
                  new DateTime().dayOfMonth().roundFloorCopy().minusDays(7),
                  null);

          double sum = valueMetric.getSum();
          long sumLong = (long) sum;

          if (sumLong == sum) {
            page.writeHtml(String.format("%,2d ", sumLong));

          } else {
            page.writeHtml(String.format("%,2.2f ", sum));
          }

          if (!sumEntries.isEmpty()) {
            long minMillis = Long.MAX_VALUE;
            long maxMillis = Long.MIN_VALUE;

            for (Map.Entry<DateTime, Double> sumEntry : sumEntries.entrySet()) {
              long sumMillis = sumEntry.getKey().getMillis();

              if (sumMillis < minMillis) {
                minMillis = sumMillis;
              }

              if (sumMillis > maxMillis) {
                maxMillis = sumMillis;
              }
            }

            double cumulativeSum = 0.0;
            StringBuilder path = new StringBuilder();
            double xRange = maxMillis - minMillis;
            int width = 35;
            int height = 18;

            for (Map.Entry<DateTime, Double> sumEntry : sumEntries.entrySet()) {
              cumulativeSum += sumEntry.getValue();

              path.append('L');
              path.append((sumEntry.getKey().getMillis() - minMillis) / xRange * width);
              path.append(',');
              path.append(height - cumulativeSum / maxSum * height);
            }

            path.setCharAt(0, 'M');

            page.writeStart(
                "svg",
                "xmlns",
                "http://www.w3.org/2000/svg",
                "width",
                width,
                "height",
                height,
                "style",
                page.cssString(
                    "display", "inline-block",
                    "vertical-align", "middle"));

            page.writeStart("path", "fill", "none", "stroke", "#444444", "d", path.toString());
            page.writeEnd();
            page.writeEnd();
          }
          page.writeEnd();

        } else if (value instanceof Recordable) {
          page.writeHtml(((Recordable) value).getState().getLabel());

        } else {
          for (Iterator<Object> i = CollectionUtils.recursiveIterable(value).iterator();
              i.hasNext(); ) {
            Object collectionValue = i.next();

            page.writeObject(collectionValue);

            if (i.hasNext()) {
              page.writeHtml(", ");
            }
          }
        }
        page.writeEnd();
      }

      if (user != null) {
        ObjectType selectedType = search.getSelectedType();
        List<String> fieldNames =
            user.getSearchResultFieldsByTypeId()
                .get(selectedType != null ? selectedType.getId().toString() : "");
        ObjectType itemType = itemState.getType();

        if (fieldNames == null) {
          for (Class<? extends SearchResultField> c :
              ClassFinder.Static.findClasses(SearchResultField.class)) {
            if (!c.isInterface() && !Modifier.isAbstract(c.getModifiers())) {
              SearchResultField field = TypeDefinition.getInstance(c).newInstance();

              if (field.isDefault(itemType) && !ObjectUtils.equals(sortField, field)) {
                field.writeTableDataCellHtml(page, item);
              }
            }
          }

          if (selectedType != null) {
            for (ObjectField field : selectedType.getFields()) {
              if (Boolean.TRUE.equals(field.as(ToolUi.class).getDefaultSearchResult())) {
                writeDataCell(itemState, field.getInternalName());
              }
            }
          }

        } else {
          for (String fieldName : fieldNames) {
            Class<?> fieldNameClass = ObjectUtils.getClassByName(fieldName);

            if (fieldNameClass != null
                && SearchResultField.class.isAssignableFrom(fieldNameClass)) {
              @SuppressWarnings("unchecked")
              SearchResultField field =
                  TypeDefinition.getInstance((Class<? extends SearchResultField>) fieldNameClass)
                      .newInstance();

              if (field.isSupported(itemState.getType()) && !ObjectUtils.equals(sortField, field)) {
                field.writeTableDataCellHtml(page, item);
              }

            } else {
              ObjectField field = itemState.getField(fieldName);

              if (field == null) {
                field = Database.Static.getDefault().getEnvironment().getField(fieldName);
              }

              if (field != null && !ObjectUtils.equals(sortField, field)) {
                writeDataCell(itemState, fieldName);
              }
            }
          }
        }
      }
      page.writeEnd();
    }
    page.writeEnd();
    page.writeEnd();

    page.writeStart("div", "id", page.createId());
    page.writeEnd();

    page.writeStart("script", "type", "text/javascript");
    page.writeRaw(
        "$('#" + page.getId() + "').siblings('.searchResultTable').find('tr').each(function() {");
    page.writeRaw("    if ($(this).find('td > a').size() > 1) {");
    page.writeRaw(
        "        $(this).closest('.searchResultTable').addClass('multipleLinkedColumns');");
    page.writeRaw("        return false;");
    page.writeRaw("    }");
    page.writeRaw(" });");
    page.writeEnd();
  }
예제 #4
0
  @Override
  protected void doService(ToolPageContext page) throws IOException, ServletException {
    ToolUser user = page.getUser();
    Collection<String> includeFields = Arrays.asList("returnToDashboardOnSave");
    Object object = Query.from(Object.class).where("_id = ?", page.param(UUID.class, "id")).first();
    State state = State.getInstance(object);
    ContentLock contentLock = null;

    if (object != null) {
      contentLock = ContentLock.Static.lock(object, null, user);
    }

    if (page.isFormPost()) {
      if (page.param(String.class, "action-edits") != null) {
        if (state != null) {
          Date newPublishDate = page.param(Date.class, "publishDate");

          if (newPublishDate != null) {
            Content.ObjectModification contentData = state.as(Content.ObjectModification.class);
            DateTimeZone timeZone = page.getUserDateTimeZone();
            newPublishDate =
                new Date(
                    DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")
                        .withZone(timeZone)
                        .parseMillis(new DateTime(newPublishDate).toString("yyyy-MM-dd HH:mm:ss")));

            contentData.setPublishUser(page.getUser());
            contentData.setPublishDate(newPublishDate);
            state.save();
          }
        }

      } else if (page.param(String.class, "action-unlock") != null) {
        contentLock.delete();

        page.writeStart("script", "type", "text/javascript");
        page.writeRaw("window.location.reload();");
        page.writeEnd();

      } else if (page.param(String.class, "action-settings") != null) {
        try {
          page.include("/WEB-INF/objectPost.jsp", "object", user, "includeFields", includeFields);
          user.save();

        } catch (Exception error) {
          page.getErrors().add(error);
        }
      }
    }

    String returnUrl = page.param(String.class, "returnUrl");

    page.writeHeader();
    page.writeStart("style", "type", "text/css");
    page.writeCss(".cms-contentTools th", "width", "25%;");
    page.writeEnd();

    page.writeStart("div", "class", "widget cms-contentTools");
    page.writeStart("h1", "class", "icon icon-wrench");
    page.writeHtml("Tools");
    page.writeEnd();

    page.writeStart("div", "class", "tabbed");
    page.writeStart("div", "class", "fixedScrollable", "data-tab", "For Editors");
    if (object != null) {
      Content.ObjectModification contentData = state.as(Content.ObjectModification.class);
      Date publishDate = contentData.getPublishDate();
      ToolUser publishUser = contentData.getPublishUser();
      Date updateDate = contentData.getUpdateDate();
      ToolUser updateUser = contentData.getUpdateUser();

      page.writeStart("table", "class", "table-striped");
      page.writeStart("tbody");
      if (publishDate != null || publishUser != null) {
        page.writeStart("tr");
        page.writeStart("th");
        page.writeHtml("Published");
        page.writeEnd();

        page.writeStart("td");
        if (publishDate != null) {
          page.writeHtml(page.formatUserDateTime(publishDate));
        }
        page.writeEnd();

        page.writeStart("td");
        if (publishUser != null) {
          page.writeObjectLabel(publishUser);
        }
        page.writeEnd();
        page.writeEnd();
      }

      if (updateDate != null || updateUser != null) {
        page.writeStart("tr");
        page.writeStart("th");
        page.writeHtml("Last Updated");
        page.writeEnd();

        page.writeStart("td");
        if (updateDate != null) {
          page.writeHtml(page.formatUserDateTime(updateDate));
        }
        page.writeEnd();

        page.writeStart("td");
        if (updateUser != null) {
          page.writeObjectLabel(updateUser);
        }
        page.writeEnd();
        page.writeEnd();
      }
      page.writeEnd();
      page.writeEnd();

      page.writeStart("h2");
      page.writeHtml("Advanced Edits");
      page.writeEnd();

      if (page.isFormPost() && page.param(String.class, "action-edits") != null) {
        if (page.getErrors().isEmpty()) {
          page.writeStart("div", "class", "message message-success");
          page.writeHtml("Advanced edits successfully saved.");
          page.writeEnd();

        } else {
          page.include("/WEB-INF/errors.jsp");
        }
      }

      page.writeStart("form", "method", "post", "action", page.url(""));

      page.writeStart("div", "class", "inputContainer");
      page.writeStart("div", "class", "inputLabel");
      page.writeStart("label", "for", page.createId());
      page.writeHtml("New Publish Date");
      page.writeEnd();
      page.writeEnd();

      page.writeStart("div", "class", "inputSmall");
      page.writeElement(
          "input",
          "type",
          "text",
          "class",
          "date",
          "name",
          "publishDate",
          "value",
          page.formatUserDateTime(publishDate));
      page.writeEnd();
      page.writeEnd();

      page.writeStart("div", "class", "actions");
      page.writeStart(
          "button", "class", "icon icon-action-save", "name", "action-edits", "value", true);
      page.writeHtml("Save");
      page.writeEnd();
      page.writeEnd();
      page.writeEnd();

      if (!user.equals(contentLock.getOwner())) {
        page.writeStart("h2");
        page.writeHtml("Content Lock");
        page.writeEnd();

        page.writeStart("div", "class", "message message-warning");
        page.writeStart("p");
        page.writeHtml("Locked by ");
        page.writeObjectLabel(contentLock.getOwner());
        page.writeHtml(" since ");
        page.writeHtml(page.formatUserDateTime(contentLock.getCreateDate()));
        page.writeHtml(".");
        page.writeEnd();
        page.writeEnd();

        page.writeStart("form", "method", "post", "action", page.url(""));
        page.writeStart("div", "class", "actions");
        page.writeStart(
            "button", "class", "icon icon-unlock", "name", "action-unlock", "value", true);
        page.writeHtml("Unlock");
        page.writeEnd();
        page.writeEnd();
        page.writeEnd();
      }
    }

    page.writeStart("h2");
    page.writeHtml("Settings");
    page.writeEnd();

    if (page.isFormPost() && page.param(String.class, "action-settings") != null) {
      if (page.getErrors().isEmpty()) {
        page.writeStart("div", "class", "message message-success");
        page.writeHtml("Settings successfully saved.");
        page.writeEnd();

      } else {
        page.include("/WEB-INF/errors.jsp");
      }
    }

    page.writeStart("form", "method", "post", "action", page.url(""), "style", "margin-bottom:0;");
    page.include("/WEB-INF/objectForm.jsp", "object", user, "includeFields", includeFields);

    page.writeStart("div", "class", "actions");
    page.writeStart(
        "button", "class", "icon icon-action-save", "name", "action-settings", "value", true);
    page.writeHtml("Save");
    page.writeEnd();
    page.writeEnd();
    page.writeEnd();
    page.writeEnd();

    page.writeStart("div", "class", "fixedScrollable", "data-tab", "For Developers");
    page.writeStart("ul");
    if (object != null) {
      page.writeStart("li");
      page.writeStart("a", "target", "_blank", "href", page.objectUrl("/contentRaw", object));
      page.writeHtml("View Raw Data");
      page.writeEnd();
      page.writeEnd();
    }

    if (!ObjectUtils.isBlank(returnUrl)) {
      page.writeStart("li");
      if (ObjectUtils.to(
          boolean.class, StringUtils.getQueryParameterValue(returnUrl, "deprecated"))) {
        page.writeStart(
            "a",
            "target",
            "_top",
            "href",
            StringUtils.addQueryParameters(returnUrl, "deprecated", null));
        page.writeHtml("Hide Deprecated Fields");
        page.writeEnd();

      } else {
        page.writeStart(
            "a",
            "target",
            "_top",
            "href",
            StringUtils.addQueryParameters(returnUrl, "deprecated", true));
        page.writeHtml("Show Deprecated Fields");
        page.writeEnd();
      }
      page.writeEnd();
    }
    page.writeEnd();

    if (object != null) {
      ObjectType type = state.getType();

      page.writeStart("table", "class", "table-striped");
      page.writeStart("tbody");
      if (type != null) {
        Class<?> objectClass = type.getObjectClass();

        if (objectClass != null) {
          page.writeStart("tr");
          page.writeStart("th");
          page.writeStart("label", "for", page.createId());
          page.writeHtml("Class");
          page.writeEnd();
          page.writeEnd();

          page.writeStart("td");
          page.writeJavaClassLink(objectClass);
          page.writeEnd();
          page.writeEnd();
        }
      }

      page.writeStart("tr");
      page.writeStart("th");
      page.writeStart("label", "for", page.createId());
      page.writeHtml("ID");
      page.writeEnd();
      page.writeEnd();

      page.writeStart("td");
      page.writeElement(
          "input",
          "type",
          "text",
          "id",
          page.getId(),
          "class",
          "code",
          "value",
          state.getId(),
          "readonly",
          "readonly",
          "style",
          "width:100%;",
          "onclick",
          "this.select();");
      page.writeEnd();
      page.writeEnd();

      page.writeStart("tr");
      page.writeStart("th");
      page.writeStart("label", "for", page.createId());
      page.writeHtml("URL");
      page.writeEnd();
      page.writeEnd();

      page.writeStart("td");
      page.writeElement(
          "input",
          "type",
          "text",
          "id",
          page.getId(),
          "value",
          JspUtils.getAbsoluteUrl(
              page.getRequest(), page.cmsUrl("/content/edit.jsp", "id", state.getId())),
          "readonly",
          "readonly",
          "style",
          "width:100%;",
          "onclick",
          "this.select();");
      page.writeEnd();
      page.writeEnd();
      page.writeEnd();
      page.writeEnd();
    }

    if (object != null) {
      ObjectType type = state.getType();

      if (type != null) {
        if (!ObjectUtils.isBlank(type.as(Renderer.TypeModification.class).getEmbedPath())) {
          String permalink = state.as(Directory.ObjectModification.class).getPermalink();

          if (!ObjectUtils.isBlank(permalink)) {
            String siteUrl = Application.Static.getInstance(CmsTool.class).getDefaultSiteUrl();
            StringBuilder embedCode = new StringBuilder();

            embedCode.append("<script type=\"text/javascript\" src=\"");
            embedCode.append(
                StringUtils.addQueryParameters(
                    StringUtils.removeEnd(siteUrl, "/") + permalink,
                    "_embed",
                    true,
                    "_format",
                    "js"));
            embedCode.append("\"></script>");

            page.writeHtml("Embed Code:");
            page.writeElement("br");
            page.writeStart(
                "textarea",
                "class",
                "code",
                "data-expandable-class",
                "code",
                "readonly",
                "readonly",
                "onclick",
                "this.select();");
            page.writeHtml(embedCode);
            page.writeEnd();
          }
        }

        String defaultPath = type.as(Renderer.TypeModification.class).getPath();
        Map<String, String> paths = type.as(Renderer.TypeModification.class).getPaths();

        if (!ObjectUtils.isBlank(defaultPath) || !ObjectUtils.isBlank(paths)) {
          page.writeStart("h2");
          page.writeHtml("Renderers");
          page.writeEnd();

          page.writeStart("table", "class", "table-striped");
          page.writeStart("tbody");
          if (!ObjectUtils.isBlank(defaultPath)) {
            page.writeStart("tr");
            page.writeStart("th");
            page.writeStart("code");
            page.writeHtml("Default");
            page.writeEnd();
            page.writeEnd();

            page.writeStart("td");
            page.writeStart("code");
            page.writeStart(
                "a",
                "target",
                "_blank",
                "href",
                DebugFilter.Static.getServletPath(
                    page.getRequest(),
                    "code",
                    "action",
                    "edit",
                    "type",
                    "JSP",
                    "servletPath",
                    defaultPath));
            page.writeHtml(defaultPath);
            page.writeEnd();
            page.writeEnd();
            page.writeEnd();
            page.writeEnd();
          }

          for (Map.Entry<String, String> entry : paths.entrySet()) {
            page.writeStart("tr");
            page.writeStart("th");
            page.writeStart("code");
            page.writeHtml(entry.getKey());
            page.writeEnd();
            page.writeEnd();

            page.writeStart("td");
            page.writeStart("code");
            page.writeStart(
                "a",
                "target",
                "_blank",
                "href",
                DebugFilter.Static.getServletPath(
                    page.getRequest(),
                    "code",
                    "action",
                    "edit",
                    "type",
                    "JSP",
                    "servletPath",
                    entry.getValue()));
            page.writeHtml(entry.getValue());
            page.writeEnd();
            page.writeEnd();
            page.writeEnd();
            page.writeEnd();
          }
          page.writeEnd();
          page.writeEnd();
        }

        Class<?> objectClass = type.getObjectClass();

        if (objectClass != null) {
          Static.writeJavaAnnotationDescriptions(page, objectClass);
        }
      }
    }
    page.writeEnd();
    page.writeEnd();
    page.writeEnd();
    page.writeFooter();
  }