diff --git a/i18n.module b/i18n.module
index 29e3581..681980d 100644
--- a/i18n.module
+++ b/i18n.module
@@ -315,12 +315,61 @@ function i18n_context_language() {
 }

 /**
- * Create object wrapper
+ * Create object wrapper.
+ *
+ * @param $type
+ *  The object type to load e.g. node_type, menu, taxonomy_term.
+ *  @see i18n_object_info().
+ * @param $object
+ *  The object to create a string wrapper for.
+ *
+ * @return
+ *   A fully-populated object wrapper, or FALSE if the object is not found.
  */
 function i18n_object($type, $object) {
-  $i18n_object = &drupal_static(__FUNCTION__);
   $key = i18n_object_key($type, $object);
   $key = is_array($key) ? implode(':', $key) : $key;
+  return isset($key) ? _i18n_object_store($type, $key, $object) : FALSE;
+}
+
+/**
+ * Create object wrapper by object id.
+ *
+ * @param $type
+ *  The object type to load e.g. node_type, menu, taxonomy_term.
+ * @param $object_id
+ *  The object identifier.
+ *  @see i18n_object_info(), {i18n_string}.objectid
+ *
+ * @return
+ *   A fully-populated object wrapper, or FALSE if the object is not found.
+ */
+function i18n_object_by_name($type, $key) {
+  if (is_int($key) || is_string($key)) {
+    $object_id = explode(':', $key);
+    if (count($object_id) == 1) {
+      $object_id = reset($object_id);
+    }
+  }
+  return isset($object_id) ? _i18n_object_store($type, $key, $object_id) : FALSE;
+}
+
+/**
+ * Static cache storage for object wrappers indexed by object type and id.
+ * Do not access this function directly, use i18n_object() or i18n_object_by_name()
+ *
+ * @param $type
+ *  The object type to load e.g. node_type, menu, taxonomy_term.
+ * @param $key
+ *  The object identifier.
+ * @param $object
+ *  The wrapper object.
+ *
+ * @return
+ *   A fully-populated string wrapper object.
+ */
+function _i18n_object_store($type, $key, $object) {
+  $i18n_object = &drupal_static(__FUNCTION__);
   if (!isset($i18n_object[$type][$key])) {
     $class = i18n_object_info($type, 'class');
     if (!$class) {
@@ -511,4 +560,4 @@ function i18n_entity_translation_enabled($entity_type) {
     $cache[$entity_type] = module_exists('entity_translation') && entity_translation_enabled($entity_type);
   }
   return $cache[$entity_type];
-}
\ No newline at end of file
+}
diff --git a/i18n_string/i18n_string.test b/i18n_string/i18n_string.test
index 5d7fc5b..6a4b810 100644
--- a/i18n_string/i18n_string.test
+++ b/i18n_string/i18n_string.test
@@ -55,6 +55,23 @@ class i18nStringTestCase extends Drupali18nTestCase {
   }

   /**
+   * Test the i18n_object store.
+   */
+  function testStringObject() {
+    foreach(menu_get_menus() as $menu_name => $title) {
+      $menu = menu_load($menu_name);
+
+      $i18n_object = i18n_object('menu', $menu_name);
+      $this->assertFalse($i18n_object);
+
+      $i18n_object = i18n_object_by_name('menu', $menu_name);
+
+      $this->assertEqual($i18n_object->get_field('menu_name'), $menu['menu_name']);
+      $this->assertEqual($i18n_object->get_field('title'), $menu['title']);
+    }
+  }
+
+  /**
    * Create strings for all languages
    */
   public static function stringCreateAll($number = 10, $length = 100) {
