diff -r 7a9f75c44226 src/widgets/widget/widget.lisp
--- a/src/widgets/widget/widget.lisp	Sat Mar 28 18:53:42 2009 -0400
+++ b/src/widgets/widget/widget.lisp	Sat Mar 28 23:56:48 2009 -0400
@@ -1,14 +1,13 @@
 
 (in-package :weblocks)
 
-(export '(defwidget widget widget-name ensure-widget-methods
-          widget-propagate-dirty widget-rendered-p widget-continuation
-          widget-parent widget-prefix-fn widget-suffix-fn
-          with-widget-header
-          render-widget-body widget-css-classes render-widget mark-dirty
-          widget-dirty-p find-widget-by-path* find-widget-by-path
-          *current-widget*
-          *override-parent-p*))
+(export '(defwidget widget widget-name lookup-widget
+          ensure-widget-methods widget-propagate-dirty
+          widget-rendered-p widget-continuation widget-parent
+          widget-prefix-fn widget-suffix-fn with-widget-header
+          render-widget-body widget-css-classes render-widget
+          mark-dirty widget-dirty-p find-widget-by-path*
+          find-widget-by-path *current-widget* *override-parent-p*))
 
 (defmacro defwidget (name direct-superclasses &body body)
   "A macro used to define new widget classes. Behaves exactly as
@@ -78,8 +77,10 @@
 ;; Process the :name initarg and set the dom-id accordingly. Note that
 ;; it is possible to pass :name nil, which simply means that objects
 ;; will render without id in generated HTML.
-(defmethod initialize-instance :after ((obj widget) &key name &allow-other-keys)
-  (when name (setf (dom-id obj) name)))
+(defmethod initialize-instance :after ((obj widget) &key name dom-id &allow-other-keys)
+  (let ((widget-id (or name dom-id)))
+    (when widget-id
+      (setf (dom-id obj) widget-id))))
 
 (defgeneric widget-name (obj)
   (:documentation "An interface to the DOM id of a widget. Provides
@@ -92,6 +93,19 @@
 
 (defmethod (setf widget-name) (name (obj widget))
   (setf (dom-id obj) name))
+
+;; Index widgets
+(defmethod (setf dom-id) :after (id (obj widget))
+  ;; Add widget to the index
+  (let ((index (or (webapp-session-value 'widget-index)
+                   (setf (webapp-session-value 'widget-index)
+                         (tg:make-weak-hash-table :weakness :value :test 'equalp)))))
+    (setf (gethash id index) obj)))
+
+(defun lookup-widget (id &optional (session *session*) (webapp (current-webapp)))
+  "Looks up widget by its dom-id."
+  (when (webapp-session-value 'widget-index session webapp)
+    (gethash id (webapp-session-value 'widget-index session webapp))))
 
 (defparameter *override-parent-p* nil
   "Allow parent overriding in (SETF COMPOSITE-WIDGETS).")
diff -r 7a9f75c44226 weblocks.asd
--- a/weblocks.asd	Sat Mar 28 18:53:42 2009 -0400
+++ b/weblocks.asd	Sat Mar 28 23:56:48 2009 -0400
@@ -15,7 +15,7 @@
   :description "A Common Lisp web framework."
   :depends-on (:closer-mop :metatilities :hunchentoot :cl-who :cl-ppcre :cl-json :puri :md5
 	       :cl-fad :fare-matcher :cl-cont :parenscript :anaphora :f-underscore
-               :html-template)
+               :html-template :trivial-garbage)
   :components ((:module src
 		:components (
 		 (:file "weblocks")
