How to add a Bookmark Folder
A product version is available for download on maenner-club.de
The current developement version is available in the collective cvs.
Implemetation
DO NOT TEST ON PRODUCTION SITES! Backup your data.fs! Allthough this is simple enough, try it on a test site first, make sure it works, and then implement it on your production site.
OK having said this, lets get started. In the ZMI goto your SiteRoot? and open portal_types. Add a Factory-based Type. Id: bookmark_folder, Use default type information: CMFPlone PloneFolder
Go to your newly created bookmark_folder Type. Alter the title, description, Product meta type and icon.
Select Image, bookmark_folder, favorites and Links as Allowed content types and check
Filter content types?.
Select the actions tab of your bookmark_folder.
In the Actions with id view and folderlisting change the Actions to string:${folder_url}/addBookmark.
Images are used to categorize your Links and are displayed with their description inline. you can use HTML-Markup in your Description. It will get rendered, but note this is not Dublin-Core conformant.
Add the addBookmark.pt to a Folder in your /portal_skins (normally custom):
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"
lang="en"
metal:use-macro="here/main_template/macros/master"
i18n:domain="plone">
<body>
<div metal:fill-slot="main"
tal:define="portal_discussion nocall:here/portal_discussion;
isDiscussionAllowedFor nocall:portal_discussion/isDiscussionAllowedFor;
getDiscussionFor nocall:portal_discussion/getDiscussionFor;">
<h1 tal:content="here/title_or_id" class="documentFirstHeading">
Title or id
</h1>
<div metal:use-macro="here/document_actions/macros/document_actions">
Document actions (print, sendto etc)
</div>
<a href=""
class="link-parent"
tal:define="parent_url python:here.navigationParent(here, template.getId())"
tal:condition="parent_url"
tal:attributes="href parent_url"
i18n:translate="go_to_parent_url">
Up one level
</a>
<div class="documentDescription" tal:content="structure here/Description">
description
</div>
<metal:listingmacro define-macro="listing">
<tal:foldercontents define="folderContents python:here.getFolderListingFolderContents(suppressHiddenFiles=1)">
<tal:listing condition="folderContents"
define="global getObjSize nocall:here/getObjSize;
global toPortalTime nocall:here/toPortalTime;
linkAnchor python:request.get('a', '');
linkTitle python:request.get('t', '');">
<dl>
<tal:entry tal:repeat="obj folderContents">
<dt metal:define-macro="listitem"
tal:define="url python: obj.absolute_url()+test(obj.isPrincipiaFolderish,'/','');
icon python: obj.getIcon(1)">
<!--icon for folder -->
<a href="#" tal:attributes="href string:${url}/addBookmark?a=$linkAnchor&t=$linkTitle"
tal:condition="python: test(obj.isPrincipiaFolderish, True, False)">
<img src="" alt=""
tal:attributes="src string:${utool}/${icon};alt here/title" />
</a>
<!-- display Image inline -->
<span style=" float:left">
<img src="" alt="" tal:condition="python: obj.portal_type == 'Image'"
tal:attributes="src string:$url" />
</span>
<!-- Links, Favorites -->
<a href="#" tal:attributes="href obj/getRemoteUrl;"
tal:condition="python: obj.portal_type in ['Link', 'Favorite']">
<img src="" alt=""
tal:attributes="src string:${utool}/${icon};alt here/title" />
</a>
<a href="#" tal:condition="python: obj.portal_type in ['bookmark_folder']"
tal:attributes="href string:${url}/addBookmark?a=$linkAnchor&t=$linkTitle"
tal:content="obj/title_or_id" />
<a href="#"
tal:condition="python: obj.portal_type in ['Link', 'Favorite']"
tal:attributes="href obj/getRemoteUrl;"
class="link-plain"
tal:content="obj/title_or_id" />
</dt>
<dd>
<span tal:content="structure python:test(obj.Description(), obj.Description(), ' ')"> description </span>
</dd>
<ul class="bookmarkFooter" tal:define="is_discussable python: isDiscussionAllowedFor(obj);
url python: obj.absolute_url()"
tal:condition="python: obj.portal_type in ['Link', 'Favorite']">
<li>
<a href="/view" tal:attributes="href url" i18n:translate="read_more">
Read More</a>
</li>
<tal:discussable condition="is_discussable">
<li tal:attributes="class python: test(has_replies, 'visualCommentAlign link-comment','visualCommentAlign');"
tal:define="talkback python: getDiscussionFor(obj);
has_replies python: talkback.hasReplies(obj);">
<a href=""
tal:define="reply_count python:talkback.replyCount(obj)"
tal:condition="reply_count"
tal:attributes="href string:${url}#comments;">
(<span tal:replace="python: reply_count" />)</a>
</li>
</tal:discussable>
</ul>
</tal:entry>
</dl>
</tal:listing>
<p class="discreet"
tal:condition="not: folderContents" i18n:translate="description_no_items_in_folder">
There are currently no items in this folder.
</p>
</tal:foldercontents>
</metal:listingmacro>
<tal:block tal:condition="not:here/portal_membership/isAnonymousUser">
<h3> Link hinzufügen </h3>
<p i18n:translate="description_edit_link_item"
tal:define="linkAnchor python:request.get('a', '');"
tal:condition="python: linkAnchor != ''">
A link is a pointer to a location on the internet or intranet.
Enter the relevant details below, and press 'Save'.
</p>
<form name="edit_form"
action="bookmarkAdd"
method="post"
enctype="multipart/form-data"
tal:define="linkAnchor python:request.get('a', '');
linkTitle python:request.get('t', '')"
tal:condition="python: linkAnchor != ''">
<fieldset>
<legend i18n:translate="legend_link_details">Link Details</legend>
<div class="field"
tal:condition="python:member.getProperty('visible_ids', None)"
tal:define="error errors/id | nothing;
id python:request.get('id', test(here.show_id(),here.getId(),''));"
tal:attributes="class python:test(error, 'field error', 'field')">
<label for="id" i18n:translate="label_short_name">Short Name</label>
<div class="formHelp" i18n:translate="help_shortname">
Short Name is part of the item's web address.
For accessibility reasons, do not use spaces, upper case,
underscores, or special characters.
</div>
<div tal:content="error">Validation error output</div>
<input type="text"
id="id"
name="id"
value=""
size="40"
tabindex=""
tal:define="newId python: 'lnk_' + str(int( context.ZopeTime()))"
tal:attributes="value newId;
tabindex tabindex/next;"
/>
</div>
<!--generate ids if not visible -->
<input type="hidden"
name="id"
tal:condition="python:not member.getProperty('visible_ids', '')"
tal:define="newId python: 'lnk_' + str(int( context.ZopeTime()))"
tal:attributes="value newId"
/>
<div class="field"
tal:define="error errors/title|nothing;
Title request/title | here/Title;"
tal:attributes="class python:test(error, 'field error', 'field')">
<label for="title" i18n:translate="label_title">Title</label>
<span class="fieldRequired" title="Required"
i18n:attributes="title"
i18n:translate="label_required">(Required)</span>
<div tal:content="error">Validation error output</div>
<input type="text"
id="title"
name="title"
value=""
size="40"
tabindex=""
tal:attributes="value linkTitle;
tabindex tabindex/next;"
/>
</div>
<div class="field"
tal:define="description request/description | here/Description ">
<label for="description" i18n:translate="label_description">Description</label>
<div class="formHelp" i18n:translate="help_description_link">
A brief description of the item.
</div>
<textarea cols="80"
rows="5"
tabindex=""
id="description"
name="description"
tal:attributes="tabindex tabindex/next;"
></textarea>
</div>
<div class="field"
tal:define="error errors/remote_url | nothing;
remote_url request/remote_url | here/remote_url | nothing;"
tal:attributes="class python:test(error, 'field error', 'field')">
<label for="uri" i18n:translate="label_url">URL</label>
<span class="fieldRequired" title="Required"
i18n:attributes="title"
i18n:translate="label_required">(Required)</span>
<div class="formHelp" i18n:translate="help_url">
Prefix is optional; if not provided, the link will be relative.
</div>
<div tal:content="error">Validation error output</div>
<input type="text"
id="uri"
name="remote_url"
size="30"
value=""
tabindex=""
tal:attributes="value linkAnchor;
tabindex tabindex/next;"
/>
</div>
<div class="formControls"
tal:define="process_creation request/process_creation|nothing;">
<img src="" class="context"
tal:define="locked portal_object/lock_icon.gif;"
tal:condition="isLocked"
tal:replace="structure python:locked.tag(title='This item is locked')"
alt="Object locked"
i18n:attributes="alt"/>
<input class="context"
tabindex=""
type="submit"
name="form.button.Save"
value="Save"
i18n:attributes="value"
tal:attributes="tabindex tabindex/next;
disabled python:test(isLocked, 'disabled', None);" />
<input class="standalone"
tabindex=""
type="reset"
name="form.button.Cancel"
value="Cancel"
i18n:attributes="value"
tal:attributes="tabindex tabindex/next;" />
</div>
</fieldset>
<input type="hidden" name="form.submitted" value="1" />
</form>
<hr/>
<p>Fügen Sie die Zeile <b>
<strong tal:replace="string: javascript:void(win=window.open ('${here/absolute_url}/addBookmark?a=' + location.href + '&t=' + document.title))"> javascipt </strong>
</b> ihren Bookmarks hinzu um hier ihre Lesezeichen zu verwalten.
</p>
</tal:block>
</div>
</body>
</html>
Next we need a Python Script to add our links
create a bookmarkAdd Python Script to your Custom Folder. The Parameter List is: remote_url, id= '' , title=None, description=None, subject=None :
from Products.PythonScripts.standard import html_quote
request = container.REQUEST
RESPONSE = request.RESPONSE
context.invokeFactory( 'Link', id=id, title=title, remote_url=remote_url, description=description)
view_url = '%s/%s' % (context.absolute_url(),
context.getTypeInfo().getActionById('view')
)
msg = 'portal_status_message=\'%s\' has been added as a Bookmark' % title
return RESPONSE.redirect('%s?%s' % (view_url, msg))
Add a bookmark_folder to your Site. Go to this folder i.e. www.example.test/links/addBookmark. There you will find the javascipt e.g.:
javascript:void(win=window.open ('http://www.maenner-club.de/Links/linux/addBookmark?a=' + location.href + '&t=' + document.title))
you will have to add to your favorites (in your browser Bookmarks/Manage Bookmarks.
Now every time you click on that bookmark a new window opens that lets
you add that Bookmark to your Plonefolder. The URI and Title are taken
from the bookmarked page. Its an good idea to provide an description,
especially when you are maintaining a public accessible Bookmark
Folder. If you want to have your bookmarks in a subfolder just click on
this folder the values for Link and title will get propagated to it.
The Cancel - Button in the form just resets the changes you made manually to the Input-Fields.
In the ZMI goto /portal_properties/site_properties. Add bookmark_folder to the
use_folder_tabs
Have a look at my personal Bookmarks on www.maenner-club.de
Replace the Favorites folder with a bookmark_folder
The Favorits Folder in Plone is a nice thing but not really of much use. In none of the Sites I have set up members are really using it.
If you want to replace that special folder with a bookmark_folder all you have to do is to customize the addtoFavorites Python Script and replace Folder with bookmark_folder i.e:
if not hasattr(homeFolder, 'Favorites'):
homeFolder.invokeFactory('bookmark_folder', id='Favorites')
Note that this does not effect any previously created Favorites Folders, you will have to rename or remove them and then hit the add to Favorites Icon to create a bookmark_folder. You can cut and paste the contents from your old Favorites into that new bookmarkfolder then.
Have Fun! Christian Ledermann
[More HowTos by nan]?
more to come --nan, Thu, 08 Jul 2004 13:15:30 -0500 reply
this is an alfa version, there are some features to be added, depending
on my needs or feature requests ;) so don't hesitate to comment!
done --nan, Fri, 23 Jul 2004 12:40:12 -0500 reply
I think this is pretty complete now, so think of it as (at least) beta.
A product version is available for download on maenner-club.de
Plone 2 --paulbhartzog, Tue, 17 Aug 2004 02:50:31 -0500 reply
well, for others who have a difficult time with this like I did, here's some help:
when you add the addBookmark.pt, you can just name it addBookmark and make sure it is a Page Template
would be nice if it could file them into folders, or somehow organize them, but hey, it werks :-)
file them into folders --nan, Wed, 18 Aug 2004 07:02:02 -0500 reply
What do you exacly want to do with them? Export to mozilla Bookmarks?
I removed that <div> in the template that was giving you headaches.
Product version --nan, Sat, 04 Sep 2004 05:21:35 -0500 reply
If you use the Product version you do not have to follow the steps
described in this howto, you may just install it as any other product,
it should work out of the Box.
The reason this Hoeto still is online is to demonstrate how one can develop products without having access to the Filesystem (usefull if you have an account on a free Plone hosting like objectis)
