diff --git a/modules/comment/views/comments.html.php b/modules/comment/views/comments.html.php
index fc54e3d2..c8236997 100644
--- a/modules/comment/views/comments.html.php
+++ b/modules/comment/views/comments.html.php
@@ -22,8 +22,9 @@
              width="40"
              height="40" />
       
-      = t('on %date 
 said',
             array("date" => date("Y-M-d H:i:s", $comment->created),
+                  "url" => user_profile::url($comment->author_id),
                   "name" => html::clean($comment->author_name()))); ?>
     
     
diff --git a/modules/gallery/controllers/user_profile.php b/modules/gallery/controllers/user_profile.php
new file mode 100644
index 00000000..808531da
--- /dev/null
+++ b/modules/gallery/controllers/user_profile.php
@@ -0,0 +1,80 @@
+id == $id;
+    $display_all =  $active_user->admin || ($is_current_active && !$active_user->guest);
+
+    $v = new Theme_View("page.html", "other", "profile");
+    $v->page_title = t("%name Profile", array("name" => $user->display_name()));
+    $v->content = new View("user_profile.html");
+
+    // @todo modify user_home to supply a link to their album,
+    // @todo add list of watches
+    // @todo add all comments
+    // @todo add rest api key
+    $v->content->user = $user;
+    $v->content->height = 250;
+    $v->content->not_current = !$is_current_active;
+    $v->content->editable = identity::is_writable() && $display_all;
+    $v->content->return = SafeString::of(Input::instance()->get("return"));
+
+    $fields = array("name" => t("Name"), "locale" => t("Locale"), "email" => t("Email"),
+                    "full_name" => t("Full name"), "url" => "Web site");
+    if (!$display_all) {
+      $fields = array("name" => t("Name"), "full_name" => t("Full name"), "url" => "Web site");
+    }
+    $v->content->fields = array();
+    foreach ($fields as $field => $label) {
+      if (!empty($user->$field)) {
+        $v->content->fields[(string)$label->for_html()] = $user->$field;
+      }
+    }
+
+    print $v;
+  }
+
+  public function contact($id) {
+    $user = identity::lookup_user($id);
+    print user_profile::get_contact_form($user);
+  }
+
+  public function send($id) {
+    $user = identity::lookup_user($id);
+    $form = user_profile::get_contact_form($user);
+    if ($form->validate()) {
+      Sendmail::factory()
+        ->to($user->email)
+        ->subject($form->message->subject->value)
+        ->header("Mime-Version", "1.0")
+        ->header("Content-type", "text/html; charset=iso-8859-1")
+        ->reply_to($form->message->reply_to->value)
+        ->message($form->message->message->value)
+        ->send();
+      message::success(t("Sent message to %user_name", array("user_name" => $user->display_name())));
+      print json_encode(array("result" => "success"));
+    } else {
+      print json_encode(array("result" => "error", "form" => (string)$form));
+    }
+  }
+}
diff --git a/modules/gallery/helpers/gallery_event.php b/modules/gallery/helpers/gallery_event.php
index 6175e049..29940ac6 100644
--- a/modules/gallery/helpers/gallery_event.php
+++ b/modules/gallery/helpers/gallery_event.php
@@ -111,11 +111,11 @@ class gallery_event_Core {
                       ->label(t("Login")));
       } else {
         $csrf = access::csrf_token();
-        $menu->append(Menu::factory("dialog")
+        $menu->append(Menu::factory("link")
                       ->id("user_menu_edit_profile")
                       ->css_id("g-user-profile-link")
                       ->view("login_current_user.html")
-                      ->url(url::site("form/edit/user/{$user->id}"))
+                      ->url(user_profile::url($user->id))
                       ->label($user->display_name()));
         $menu->append(Menu::factory("link")
                       ->id("user_menu_logout")
diff --git a/modules/gallery/helpers/user_profile.php b/modules/gallery/helpers/user_profile.php
new file mode 100644
index 00000000..018e1bd1
--- /dev/null
+++ b/modules/gallery/helpers/user_profile.php
@@ -0,0 +1,55 @@
+id}", "", "post",
+                      array("id" => "g-user-profile-contact-form"));
+    $group = $form->group("message")
+      ->label(t("Compose message to %name", array("name" => $user->display_name())));
+    $group->input("reply_to")
+      ->label(t("From:"))
+      ->rules("required|length[1, 256]|valid_email")
+      ->error_messages("required", t("Field is required"))
+      ->error_messages("max_length", t("Field exceeds 256 bytes"))
+      ->error_messages("valid_email", t("Field is not a valid email address"));
+    $group->input("subject")
+      ->label(t("Subject:"))
+      ->rules("required|length[1, 256]")
+      ->error_messages("required", t("Field is required"))
+      ->error_messages("max_length", t("Field exceeds 256 bytes"));
+    $group->textarea("message")
+      ->label(t("Message:"))
+      ->rules("required")
+      ->error_messages("required", t("Field is required"));
+    module::event("user_profile_contact_form", $form);
+    $group->submit("")->value(t("Send"));
+    return $form;
+  }
+}
diff --git a/modules/gallery/views/admin_block_log_entries.html.php b/modules/gallery/views/admin_block_log_entries.html.php
index 780ff2d0..90ce88a7 100644
--- a/modules/gallery/views/admin_block_log_entries.html.php
+++ b/modules/gallery/views/admin_block_log_entries.html.php
@@ -2,7 +2,7 @@
 
    foreach ($entries as $entry): ?>
   
-    user_id") ?>">= html::clean($entry->user->name) ?> 
+    = html::clean($entry->user->name) ?> 
     = gallery::date_time($entry->timestamp) ?>
     = $entry->message ?>
     = $entry->html ?>
diff --git a/modules/gallery/views/login_current_user.html.php b/modules/gallery/views/login_current_user.html.php
index e3b3688f..39f52b51 100644
--- a/modules/gallery/views/login_current_user.html.php
+++ b/modules/gallery/views/login_current_user.html.php
@@ -1,11 +1,8 @@
 
  
    $name = $menu->label->for_html() ?>
-   if (identity::is_writable()): ?>
+   $hover_text = Identity::is_writable() ? t("Edit your profile")->for_html_attr() :
+                                             t("Display your profile")->for_html_attr() ?>
   = t("Logged in as %name", array("name" => html::mark_clean(
-        ""))) ?>
-   else: ?>
-  = t("Logged in as %name", array("name" => $name)) ?>
-   endif ?>
+        ""))) ?>
  
diff --git a/modules/gallery/views/user_profile.html.php b/modules/gallery/views/user_profile.html.php
new file mode 100644
index 00000000..e7ce56b3
--- /dev/null
+++ b/modules/gallery/views/user_profile.html.php
@@ -0,0 +1,69 @@
+
+
+
+
+  
= t("%name Profile", array("name" => $user->display_name())) ?> 
+  
+    
+    = t("User information") ?> 
+    
+    
+     foreach ($fields as $field => $value): ?>
+    
+      = $field ?> 
+      = $value ?> 
+     
+     endforeach ?>
+    
+    
 
+     
+  
+  
+
 
\ No newline at end of file
diff --git a/modules/recaptcha/helpers/recaptcha_event.php b/modules/recaptcha/helpers/recaptcha_event.php
index e7ded3ab..a7f64bdd 100644
--- a/modules/recaptcha/helpers/recaptcha_event.php
+++ b/modules/recaptcha/helpers/recaptcha_event.php
@@ -18,6 +18,12 @@
  * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA  02110-1301, USA.
  */
 class recaptcha_event_Core {
+  static function user_profile_contact_form($form) {
+    if (module::get_var("recaptcha", "public_key")) {
+      $form->message->recaptcha("recaptcha")->label("")->id("g-recaptcha");
+    }
+  }
+
   static function comment_add_form($form) {
     if (module::get_var("recaptcha", "public_key")) {
       $form->add_comment->recaptcha("recaptcha")->label("")->id("g-recaptcha");
-- 
cgit v1.2.3