From those I've talked to internally, the Knowledge Directory is a historical marriage of theoretically good ideas with the inevitable encroachment of reality. What I mean by that poetic, yet over thought, opening statement is that there are some things that happen in the KD that may make you wonder and scratch your head.
To me, the most obvious problem with the KD is its propensity for naming imported cards as if they must be unique throughout the entire directory. An example: try uploading a card to the directory called Test (doesn't matter how you do it: simple file upload, collab import, etc). Now upload another card named Test in a different folder. Notice anything squirrelly? How about the (1) after the second card? It's almost as if the KD were designed only to have one unique card of each name...
Oh wait. It was. Technically, the designers of the KD imagined users being able to use filters to control content location and naming convention, such that there would only be one document of each name. Alas, the pin of reality punctures even the most fanciful of dreams. Most portal users nowadays would agree with me that there is almost no way this can happen, given the variety of users uploading to the KD, the security constraints that are in place, and sometimes, the vast size of the KD itself.
Enough of that, though. I just wrote three paragraphs explaining why you might want to get rid of the annoying (1), (2), (3), etc after card names. If you want to skip the technical mumbo jumbo, browse to the What You Need to Know part. Otherwise, let's talk shop...
Technical Details
In order to fix the problem, we really can't change the entire back end functionality of the KD (feel free to file support requests with our engineering team, though). The most obvious way to fix the problem is to use the portal's built in Activity Space override ability to rub out the (1)'s wherever they are displayed. That could be a lot of places, though: search results, snapshot queries and the KD itself, to name a few. How can we possibly ensure we've found (and can rewrite code for) every UI space that uses them?
Ah... here's where the back end design of the portal works for us. The portal actually stores *all* models, views, controls and activity spaces in a global set of hash tables, indexed by a string-based name for each. When you call RegisterModel or RegisterView in an activity space, the Space itself actually goes out to these global hash tables, using the string value you provided it, and instantiates the object for that particular space. It doesn't really know what that object is.
What this means to us is that we can replace the object in the hash table with another one, simply by overriding that object and adding it to the CustomActivitySpaces.xml file (see the portal edocs if I've lost you completely). Thus, if we change a model or control, it will change for every page that uses it.
In other words, we can replace models and controls instead of just views. This way, we don't have to mess with the gory display details.
What You Need to Know to Get it Working
I've attached the jar to this post. It has all of the source I'm about to explain. If you're not interested in the rest of the details, simply add allowdups.jar to your portal.war file and edit your $PT_HOME/settings/portal/CustomActivitySpaces.xml to include the line:
<libfile name="allowdups" />
.NET users, I apologize again (maybe I have to retract my claim that .NET is my primary language). The source for this is simple, though, so you should be able to buiild a DLL and do the same thing fairly easily. So what did I do?
All I ended up doing was overriding two classes: com.plumtree.portalpages.browsing.directory.DirModel and com.plumtree.portaluiinfrastructure.search.SearchResultModel. It is these two models that provide card names to every display page in the portal. By inheriting from the original classes and overriding the appropriate methods, I was able to simply write a regular expression (found in the utility class under com.plumtree.utility in this jar) to replace the (#) at the end of cards (yeah, it's a hack). So long as the Create() methods return my object instead of the original class, the pages that output card names will use my models to do it.
That's it.
Final caveat: This won't fix EDK results, or anything else external (it doesn't modify the database schema). As always, use it at your own risk.
Another link to the jar, in case you missed it the first time.