Index: t3lib/class.t3lib_page.php
===================================================================
--- t3lib/class.t3lib_page.php	(revision 3829)
+++ t3lib/class.t3lib_page.php	(working copy)
@@ -454,15 +454,22 @@
 					} else unset($row);	// If the mount point could not be fetched with respect to enableFields, unset the row so it does not become a part of the menu!
 				}
 
-					// if shortcut, look up if the target exists and is currently visible
+				// if shortcut, look up if the target exists and is currently visible
 				if ($row['doktype'] == 4 && ($row['shortcut'] || $row['shortcut_mode']) && $checkShortcuts)	{
+					$shortcutParts = explode('_', $row['shortcut']);
+					$shortcutUid = intval(array_pop($shortcutParts)); // chop off the uid, separated by '_'. Remark: '_' is likely to be part of the table name as well.
+					$shortcutTable = implode('_', $shortcutParts); // rebuild the table name
+
+					if ($shortcutTable == 'tt_content') { // is this shortcut an anchor to tt_content?
+						list($shortcutUid, $shortcutSection) = $this->resolveShortcutToContent($shortcutUid);
+					}
 					if ($row['shortcut_mode'] == 0)	{
 						$searchField = 'uid';
-						$searchUid = intval($row['shortcut']);
+						$searchUid = $shortcutUid;
 					} else { // check subpages - first subpage or random subpage
 						$searchField = 'pid';
-							// If a shortcut mode is set and no valid page is given to select subpags from use the actual page.
-						$searchUid = intval($row['shortcut'])?intval($row['shortcut']):$row['uid'];
+						// If a shortcut mode is set and no valid page is given to select subpags from use the actual page.
+						$searchUid = ($shortcutUid > 0) ? $shortcutUid : $row['uid'];
 					}
 					$res2 = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', 'pages', $searchField.'='.$searchUid.$this->where_hid_del.$this->where_groupAccess.' '.$addWhere, '', $sortField);
 					if (!$GLOBALS['TYPO3_DB']->sql_num_rows($res2))	{
@@ -1375,6 +1382,68 @@
 		}
 		return ($ws['_ACCESS'] != '');
 	}
+
+	/**
+	 * Resolves shortcut links to tt_content elements: an array ( pid=int, uid=int|false ) will be returned.
+	 * A workspace overlay is performed, if applicable.
+	 * For the pid, it doesn't matter, if the uid is deleted or not visible even for WS reasons.
+	 * For the uid, this is relevant: If the tt_content linked to is not visible for any reason, no id but false is returned.
+	 *
+	 * @param	integer		The tt_content id
+	 * @return	array		Array with two elements: (1) int: pid of tt_content (2) int or false: uid of tt_content, if visible
+	 * @see tslib_menu::link(), tslib_fe::getPageAndRootline
+	 */
+	function resolveShortcutToContent($contentUid) {
+		$pid = false;
+		$uid = false;
+		// first: get the tt_content record, disregarding any disabled fields:
+		// If the record turns out to be disabled (even deleted), we want at least return its pid.
+		$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'tt_content', 'uid=' . $contentUid);
+		$shortcutContent = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
+		$GLOBALS['TYPO3_DB']->sql_free_result($res);
+		if ($shortcutContent) { // WS overlay.
+			if ($shortcutContent['pid'] > 0) { // Save record from Live WS, if any.
+				$liveRecord = $shortcutContent;
+			} else {
+				$liveRecord = false;
+			}
+			$this->versionOL('tt_content', $shortcutContent, false, false); // get WS overlay. May unset $shortcutContent.
+			if (!is_array($shortcutContent) && is_array($liveRecord)) {
+				// WS overlay failed, but there is a live version => fallback to live WS
+				$pid = $liveRecord['pid'];
+				$uid = $liveRecord['uid'];
+			} elseif (is_array($shortcutContent)) {
+
+				// WS overlay was successful
+				$pid = $shortcutContent['pid'];
+				// uid is returned, if current ws id matches the one overlayed
+				if (	$this->versioningWorkspaceId == $shortcutContent['t3ver_wsid'] ||
+					!strcmp($shortcutContent['t3ver_wsid'],'0')
+				) {
+					$uid = $shortcutContent['uid'];
+				} else {
+					$uid = false;
+				}
+			} else {
+				// failsafe: no live record, no workspace record.
+				// fall back to current page
+				$pid = $this->fixVersioningPid('tt_content',$shortcutContent);
+				$uid = false;
+			}
+		} else {
+			// failsafe: the tt_content record didn't even exist.
+			// fall back to current page
+			$linkpid = $GLOBALS['TSFE']->id;
+			$uid = false;
+		}
+		// now check, if the WS overlayed tt_content record itself and its parent page is accessible
+		if (	$uid && !is_array($this->checkRecord('tt_content',$uid)) ||
+			$uid && !is_array($this->checkRecord('pages',$pid))
+		) {
+			$uid = false;
+		}
+		return array($pid, $uid);
+	}
 }
 
 
@@ -1382,4 +1451,4 @@
 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_page.php'])	{
 	include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_page.php']);
 }
-?>
+?>
\ No newline at end of file
Index: typo3/sysext/cms/ext_tables.php
===================================================================
--- typo3/sysext/cms/ext_tables.php	(revision 3829)
+++ typo3/sysext/cms/ext_tables.php	(working copy)
@@ -314,7 +314,7 @@
 			'config' => array (
 				'type' => 'group',
 				'internal_type' => 'db',
-				'allowed' => 'pages',
+				'allowed' => 'pages,tt_content',
 				'size' => '3',
 				'maxitems' => '1',
 				'minitems' => '0',
Index: typo3/sysext/cms/ext_tables.sql
===================================================================
--- typo3/sysext/cms/ext_tables.sql	(revision 3829)
+++ typo3/sysext/cms/ext_tables.sql	(working copy)
@@ -385,7 +385,7 @@
   starttime int(11) unsigned DEFAULT '0' NOT NULL,
   endtime int(11) unsigned DEFAULT '0' NOT NULL,
   urltype tinyint(4) unsigned DEFAULT '0' NOT NULL,
-  shortcut int(10) unsigned DEFAULT '0' NOT NULL,
+  shortcut varchar(255) DEFAULT '0' NOT NULL,
   shortcut_mode int(10) unsigned DEFAULT '0' NOT NULL,
   no_cache int(10) unsigned DEFAULT '0' NOT NULL,
   fe_group varchar(100) DEFAULT '0' NOT NULL,
Index: typo3/sysext/cms/tslib/class.tslib_fe.php
===================================================================
--- typo3/sysext/cms/tslib/class.tslib_fe.php	(revision 3829)
+++ typo3/sysext/cms/tslib/class.tslib_fe.php	(working copy)
@@ -1040,7 +1040,17 @@
 			// Is the ID a link to another page??
 		if ($this->page['doktype']==4)	{
 			$this->MP = '';		// We need to clear MP if the page is a shortcut. Reason is if the short cut goes to another page, then we LEAVE the rootline which the MP expects.
-			$this->page = $this->getPageShortcut($this->page['shortcut'],$this->page['shortcut_mode'],$this->page['uid']);
+
+			// Handle type of shortcut: Either of type pages or anything else (e.g. tt_content)
+			$shortcutParts = explode('_', $this->page['shortcut']);
+			$shortcutUid = array_pop($shortcutParts);
+			$shortcutTable = implode('_', $shortcutParts);
+			if (strlen($shortcutTable)==0 || $shortcutTable=='pages') {
+				$this->page = $this->getPageShortcut($shortcutUid,$this->page['shortcut_mode'],$this->page['uid']);
+			} elseif ($shortcutTable == 'tt_content') { // is this shortcut an anchor to tt_content?
+				list($shortcutUid,$sectionUid) = $this->sys_page->resolveShortcutToContent($shortcutUid);
+				$this->page = $this->getPageShortcut($shortcutUid,$this->page['shortcut_mode'],$this->page['uid']);
+			}
 			$this->id = $this->page['uid'];
 		}
 
Index: typo3/sysext/cms/tslib/class.tslib_menu.php
===================================================================
--- typo3/sysext/cms/tslib/class.tslib_menu.php	(revision 3829)
+++ typo3/sysext/cms/tslib/class.tslib_menu.php	(working copy)
@@ -449,7 +449,6 @@
 							$res = $GLOBALS['TSFE']->cObj->exec_getQuery('pages',Array('pidInList'=>$id,'orderBy'=>$altSortField));
 							while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))	{
 								$GLOBALS['TSFE']->sys_page->versionOL('pages',$row);
-
 								if (is_array($row))	{
 										// Keep mount point?
 									$mount_info = $this->sys_page->getMountPointInfo($row['uid'], $row);
@@ -1208,12 +1207,43 @@
 			// Setting main target:
 		$mainTarget = $altTarget ? $altTarget : $this->mconf['target'];
 
+
 			// Creating link:
 		if ($this->mconf['collapse'] && $this->isActive($this->menuArr[$key]['uid'], $this->getMPvar($key)))	{
+		
+			// collapse active menu item, link to pid
 			$thePage = $this->sys_page->getPage($this->menuArr[$key]['pid']);
 			$LD = $this->menuTypoLink($thePage,$mainTarget,'','',$overrideArray, $this->mconf['addParams'].$MP_params.$this->menuArr[$key]['_ADD_GETVARS'], $typeOverride);
 		} else {
-			$LD = $this->menuTypoLink($this->menuArr[$key],$mainTarget,'','',$overrideArray, $this->mconf['addParams'].$MP_params.$this->I['val']['additionalParams'].$this->menuArr[$key]['_ADD_GETVARS'], $typeOverride);
+
+			// Handle shortcut menut item (may be an anchorlink to a tt_content element as well)
+			if ($this->menuArr[$key]['doktype'] == 4) {
+				$shortcutPage = $this->menuArr[$key];
+
+				if (strlen($shortcutPage['shortcut']) > 0 && $shortcutPage['shortcut'] != '0') {
+
+					$shortcutParts = explode('_', $shortcutPage['shortcut']);
+					$shortcutUid = intval(array_pop($shortcutParts)); // chop off the uid, separated by'_'. Remark: '_' is likely to be part of the table name as well.
+					$shortcutTable = implode('_', $shortcutParts); // rebuild the table name
+					if ($shortcutTable == 'tt_content') { // is this shortcut an anchor to tt_content?
+
+						// returns: array (pid  ,  uid to content or false, if WS overlay or access to content failed)
+						list ($shortcutPid, $shortcutUid) = $this->sys_page->resolveShortcutToContent($shortcutUid);
+						$shortcutPage = $this->sys_page->getPage($shortcutPid);
+
+						// can we link to the content?
+						$shortcutPage['uid'].= ($shortcutUid) ? ('#'.$shortcutUid) : '';
+					} elseif ($shortcutTable == 'pages') {
+						$shortcutPage = $this->sys_page->getPage($shortcutUid);
+					}
+				} else {
+					// failsafe: shortcut page set, but no shortcut target chosen: take current page
+					$shortcutPage = $this->sys_page->getPage($GLOBALS['TSFE']->id);
+				}
+				$LD = $this->menuTypoLink($shortcutPage,$mainTarget,'','',$overrideArray, $this->mconf['addParams'].$MP_params.$this->I['val']['additionalParams'].$this->menuArr[$key]['_ADD_GETVARS'], $typeOverride);
+			} else {
+				$LD = $this->menuTypoLink($this->menuArr[$key],$mainTarget,'','',$overrideArray, $this->mconf['addParams'].$MP_params.$this->I['val']['additionalParams'].$this->menuArr[$key]['_ADD_GETVARS'], $typeOverride);
+			}
 		}
 
 			// Override URL if using "External URL" as doktype with a valid e-mail address:
@@ -2904,4 +2934,4 @@
 	include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['tslib/class.tslib_menu.php']);
 }
 
-?>
+?>
\ No newline at end of file
