Personal tools
You are here: Home Products Plone Roadmap #132: Return to Icon Flexibility
Document Actions

#132: Return to Icon Flexibility

Contents
  1. Definitions
  2. Motivation
  3. Proposal
  4. Implementation
  5. Risks
by Maik Roeder last modified December 10, 2006 - 22:26
It is much more flexible to use the "getIcon" method to display icons via CSS in Plone than using the "portal_type". If the portal type is used, then there can only be a single icon for a content type, which makes it impossible to change the icon depending on what is contained in the content type. This is a proposal to get some of the flexibility back that was lost while going from Plone 2.0 to Plone 2.1.
Proposed by
Maik Röder
Proposal type
User interface
Assigned to release
State
rejected

Definitions

The following code shows the general way, the icon is fetched to construct the CSS in Plone 2.1:

from Products.CMFCore.utils import getToolByName
pt_tool = getToolByName(context, 'portal_types')
for item in pt_tool.objectValues():
    icon = item.getIcon()

This method is different from the general way the "getIcon" method is indexed on the content itself:

ti = self.getTypeInfo()
return ti.getIcon()

In a Virtual Hosting scenario, where the Plone site is the root, you would find an icon name like this in the "getIcon" metadata:

newsitem_icon.gif

If you are working with the Plone site under the root, like http://localhost:8080/Plone, the following would be indexed in "getIcon":

Plone/newsitem_icon.gif


Here are three examples, of how AttachmentField maps icons to MIME types:

The audio icon is used to group several content types like WAV and MPEG together:

  • audio/mpeg
  • audio/x-wav
  • audio/x-pn-realaudio
  • audio/x-realaudio
  • audio/x-mpegurl

The Autocad is a special case that groups all MIME types related to Autocad:

  • application/acad
  • application/dxf

For HTML the is only one MIME type

  • text/html


Motivation

The motivation for this proposal comes from the AttachmentField product, which is used in PloneExFile and PloneArticle to handle attachments.


Depending on the MIME type of the attachment, the icon is changed by AttachmentField, which makes it possible to indicate the type of Attachment already in the folder contents view.

PDF File in the Plone contents view

In this folder contents view, the PDF icon shows directly what is contained in the PloneExFile.


While this flexibility was still available in Plone 2.0, it was lost in Plone 2.1 by showing the

icon based on the portal type, and no more based on the icon

Proposal

Instead of producing this kind of CSS for documents:

.contenttype-document,
.actionMenu .contenttype-document a:hover {
background-image: url(http:\\localhost:8080/ESS/document_icon.gif);
background-repeat: no-repeat;
background-position: 0% 0%;
}


This kind of CSS would be produced:

.icontype-document-icon,
.actionMenu .icontype-document-icon a:hover {
background-image: url(http:\\localhost:8080/ESS/document_icon.gif);
background-repeat: no-repeat;
background-position: 0% 0%;
}


Then, this would allow us to this for the special case of an Excel sheet in PloneExFile:

.icontype-excel_small.gif,
.actionMenu .icontype-excel a:hover {
background-image: url(http://localhost:8080/ESS/excel_small.gif);
background-repeat: no-repeat;
background-position: 0% 0%;
}

In the HTML, the changes are as follows:


Currently, the rendering of the HTML is:

<div class="contenttype-document">

This would change to:

<div class="contenticon-document">

Then, this would allow us to define classes for the purpose of PloneExFile as:

<div class="contenticon-excel"> 


Implementation

Modification of "generated.css.dtml":

<dtml-in "getPortalTypeList()">
  <dtml-let item=sequence-item
            type_icon_with_extension="normalizeString(item['icon'])"
            type_icon="type_icon_with_extension[:-4]">
    .contenticon-&dtml-type_icon;,
    .actionMenu .contenticon-&dtml-type_icon; a:hover {
        background-image: url(&dtml-portal_url;/&dtml-type_icon;);
        background-repeat: no-repeat;
        background-position: 0% 0%;
    }
    /* Holly hack to prevent items from shifting to the left in IE*/
    * html .contenticon-&dtml-type_icon; {
        height: 1%;
    }
    #portal-sitemap .contenticon-&dtml-type_icon; a:hover,
    #portlet-navigation-tree .contenticon-&dtml-type_icon; a:hover,
    #portlet-navigation-tree .contenticon-&dtml-type_icon; a.navTreeCurrentItem {
        background-image: url(&dtml-portal_url;/&dtml-type_icon_with_extension;);
        background-repeat: no-repeat;
        background-position: 0% 3px;
    }
    #portal-sitemap .contenticon-&dtml-type_id;,
    #portlet-navigation-tree .contenticon-&dtml-type_icon; {
        background-position: 0% 4px;
    }
    * html #portal-sitemap .contenttype-&dtml-type_icon; a:hover,
    * html #portlet-navigation-tree .contenttype-&dtml-type_icon; a:hover,
    * html #portlet-navigation-tree .contenttype-&dtml-type_icon; a.navTreeCurrentItem {
        position: relative;
    }
    .listing .contenticon-&dtml-type_icon; {
        display: block;
    }
  </dtml-let>
</dtml-in>

Modification of "RTL.css.dtml":

<dtml-in "getPortalTypeList()">
  <dtml-let type_icon="normalizeString(_['sequence-item']['icon'][:-4])">
.contenticon-&dtml-type_icon;,
#objectMenu .contenticon-&dtml-type_icon; a:hover {
    background-position: 100% 0%;
}
#portlet-navigation-tree .contenticon-&dtml-type_icon; a:hover,
#portlet-navigation-tree .contenticon-&dtml-type_icon; a.navTreeCurrentItem {
    background-position: 100% 3px; margin-right: -1px; margin-left: 0;
}
#portlet-navigation-tree .contenticon-&dtml-type_icon; {
    background-position: 100% 4px;
}
  </dtml-let>
</dtml-in>

Modification of "folder_listing.pt", "folder_summary_view.pt", "folder_tabular_view.pt", "folder_factories.pt", "search.pt", "portlet_navigation.pt", "portlet_navtree_macro.pt", "portlet_recent.pt", "portlet_review.pt", "folder_contents.pt", "global_contentmenu.pt" and "recently_modified.pt":

<tal:level define="item_icon_class     python: 'contenticon-' + normalizeString(item['getIcon'][:-4]);">


Risks

No impact on Plone

For Plone, the only thing that changes is the class name in the HTML code

<div class="contenttype-document">

becomes

<div class="contenticon-document">

All the standard Plone CSS has to do is to generate classes for "contenticon-document" instead of "contenttype-document".

If a Plone site has been customized using these classes, they would only need to be renamed.

Moderate growth of CSS for the example of AttachmentField

The content type icon part of the Plone CSS from Plone.org is about 1500 lines long. With the current AttachmentField implementation, the CSS would grow by 500 lines. This is a moderate growth, which is due to the fact that icons are grouped. For example, the icon image.gif is used for the following MIME types:

  • image/gif
  • image/jpeg
  • image/jpg
  • image/png
  • image/xpm
  • image/bmp
  • image/x-windows-bmp


+1

Posted by Geir Baekholt at August 3, 2006 - 09:10
As long as we first clean up in obviously insane assumptions like "type_icon_with_extension[:-4]" (…that getIcon()always returns four extra characters…) , this is a good approach and i am in favor.

+1 on intention, -1 on implementing it this way

Posted by Alexander Limi at August 22, 2006 - 06:40
I think the 2.1/2.5 way of doing it is flawed, and I'm fully ready to admit it was a mistake.

If all browsers adhered to the spec, and we could do this in a saner way with less markup, it would have been a somewhat good idea. What we ended up with was a suboptimal implementation that did grew the CSS size a lot, and introduced a lot of unnnecessary markup.

The way to do this, is in my opinion:

- Go back to using getIcon to show these icons

- Put the getIcon result in the catalog, so we don't have to wake up the object to read it (it's just a path string!)

This way, content type icons can be infinitely flexible, even down to a per-instance basis (issue trackers with different icons depending on state, anyone?)

I'd hate to see this become more complex than it already is. Sometimes, it's time to admit that the original implementation was better than the new one, and go back. I believe this is the case here.

I only wanted to do it via CSS because of the switch to the catalog-backed listings. Because of some miscommunication, I believed that having the getIcon result in the catalog would be inefficient, and we came up with the CSS approach. I now know that I was wrong in my assumptions.

Let's go back to using getIcon, but let's use the catalog instead of waking up the object. I can't see any compelling use case that the CSS approach would solve, but this would not.

(It kind of has a parallel to the way the logo image is implemented in current Plone - it's very clever, and 98% of people have no idea where the logo comes from. Sometimes Plone is a bit too smart for its own good. ;)

See PLIP 178 for the other way

Posted by Alexander Limi at August 28, 2006 - 05:03
There is now a PLIP for returning to the getIcon + catalog approach:

http://plone.org/products/plone/roadmap/178

+1 on intention, -1 on implementation

Posted by Shaun Hills at October 2, 2006 - 02:47
I like this idea, but two of my pet dislikes in Plone are:

1) The way the logo's handled (it's smart, it's hard to grok, and there's a little too much of this in Plone sometimes)

2) Dynamically generated CSS ;)

This PLIP seems to be moving further down this path, and FWIW I think that's Double-Plus Ungood.

We ended up doing it differently than the PLIP states

Posted by Alexander Limi at October 2, 2006 - 02:57
I believe the consensus is to remove the magic here and go back to getIcon, like my comment says.

1) Logo handling is going away (I have said many times, I believe even in my tutorial about theming Plone, that it's trying to be too smart)

2) We're going to reduce the amount of dynamically generated CSS (if you're talking about the DTML for colors etc, that is - the collapsing and compression of CSS/JS is not going away)

For any issues with the web site functionality, please file a ticket.

Please consult the policy on plone.org content if you want your content published on this site.

Servers and hosting by