diff --git a/include/blocks.inc.php b/include/blocks.inc.php
index 92d110a..93b9d2a 100644
--- a/include/blocks.inc.php
+++ b/include/blocks.inc.php
@@ -1016,7 +1016,7 @@ function make_latest_issues(array $filter = array()) {
 
 		// description
 		if (!zbx_empty($trigger['url'])) {
-			$description = new CLink($description, resolveTriggerUrl($trigger), null, null, true);
+			$description = new CLink($description, CMacrosResolverHelper::resolveTriggerUrl(zbx_array_merge($trigger)), null, null, true);
 		}
 		else {
 			$description = new CSpan($description, 'pointer');
diff --git a/include/classes/macros/CMacrosResolver.php b/include/classes/macros/CMacrosResolver.php
index 416442e..4c8e33e 100644
--- a/include/classes/macros/CMacrosResolver.php
+++ b/include/classes/macros/CMacrosResolver.php
@@ -57,6 +57,11 @@ class CMacrosResolver extends CMacrosResolverGeneral {
 			'source' => 'comments',
 			'method' => 'resolveTrigger'
 		),
+		'triggerUrl' => array(
+			'types' => array('host', 'interface', 'user', 'item'),
+			'source' => 'url',
+			'method' => 'resolveTrigger'
+		),
 		'triggerExpressionUser' => array(
 			'types' => array('user'),
 			'source' => 'expression',
@@ -344,6 +349,7 @@ class CMacrosResolver extends CMacrosResolverGeneral {
 	 * @param string $triggers[$triggerId]['expression']
 	 * @param string $triggers[$triggerId]['description']			depend from config
 	 * @param string $triggers[$triggerId]['comments']				depend from config
+	 * @param string $triggers[$triggerId]['url']					depend from config
 	 *
 	 * @return array
 	 */
@@ -369,6 +375,13 @@ class CMacrosResolver extends CMacrosResolverGeneral {
 
 		// find macros
 		foreach ($triggers as $triggerId => $trigger) {
+
+			foreach ($this->findFunctionMacros(self::PATTERN_TRIGGER, $trigger[$source]) as $macro => $fNums) {
+				foreach ($fNums as $fNum) {
+					$macroValues[$triggerId][$this->getFunctionMacroName($macro, $fNum)] = $triggerId;
+				}
+			}
+
 			if ($userMacrosAvailable) {
 				$userMacros = $this->findMacros(ZBX_PREG_EXPRESSION_USER_MACROS, array($trigger[$source]));
 
@@ -383,7 +396,7 @@ class CMacrosResolver extends CMacrosResolverGeneral {
 				}
 			}
 
-			$functions = $this->findFunctions($trigger['expression']);
+			$functions = (array_key_exists('expression', $trigger) ? $this->findFunctions($trigger['expression']) : null);
 
 			if ($hostMacrosAvailable) {
 				foreach ($this->findFunctionMacros(self::PATTERN_HOST_FUNCTION, $trigger[$source]) as $macro => $fNums) {
@@ -488,6 +501,7 @@ class CMacrosResolver extends CMacrosResolverGeneral {
 			preg_match_all('/'.self::PATTERN_HOST_FUNCTION.
 								'|'.$patternInterfaceFunction.
 								'|'.self::PATTERN_ITEM_FUNCTION.
+								'|'.self::PATTERN_TRIGGER.
 								'|'.ZBX_PREG_EXPRESSION_USER_MACROS.
 								'|\$([1-9])/', $trigger[$source], $matches, PREG_OFFSET_CAPTURE);
 
diff --git a/include/classes/macros/CMacrosResolverGeneral.php b/include/classes/macros/CMacrosResolverGeneral.php
index 41eb560..701b7da 100644
--- a/include/classes/macros/CMacrosResolverGeneral.php
+++ b/include/classes/macros/CMacrosResolverGeneral.php
@@ -31,6 +31,7 @@ class CMacrosResolverGeneral {
 	const PATTERN_ITEM_FUNCTION = '{(ITEM\.LASTVALUE|ITEM\.VALUE)([1-9]?)}';
 	const PATTERN_ITEM_NUMBER = '\$[1-9]';
 	const PATTERN_ITEM_MACROS = '{(HOSTNAME|HOST\.HOST|HOST\.NAME|IPADDRESS|HOST\.IP|HOST\.DNS|HOST\.CONN)}';
+	const PATTERN_TRIGGER = '{(TRIGGER\.ID)}';
 
 	/**
 	 * Interface priorities.
diff --git a/include/classes/macros/CMacrosResolverHelper.php b/include/classes/macros/CMacrosResolverHelper.php
index d5fddc9..afafc86 100644
--- a/include/classes/macros/CMacrosResolverHelper.php
+++ b/include/classes/macros/CMacrosResolverHelper.php
@@ -318,6 +318,40 @@ class CMacrosResolverHelper {
 	}
 
 	/**
+	 * Resolve macros in trigger URL.
+	 *
+	 * @static
+	 *
+	 * @param array $trigger
+	 *
+	 * @return string
+	 */
+	public static function resolveTriggerUrl(array $trigger) {
+		$urls = self::resolveTriggerUrls(array($trigger));
+		$urls = reset($urls);
+
+		return $urls['url'];
+	}
+
+	/**
+	 * Resolve macros in trigger URLs.
+	 *
+	 * @static
+	 *
+	 * @param array $triggers
+	 *
+	 * @return array
+	 */
+	public static function resolveTriggerUrls(array $triggers) {
+		self::init();
+
+		return self::$macrosResolver->resolve(array(
+			'config' => 'triggerUrl',
+			'data' => zbx_toHash($triggers, 'triggerid')
+		));
+	}
+
+	/**
 	 * Resolve macros in event description.
 	 *
 	 * @static
diff --git a/include/func.inc.php b/include/func.inc.php
index 3853490..171828b 100644
--- a/include/func.inc.php
+++ b/include/func.inc.php
@@ -2811,7 +2811,7 @@ function getMenuPopupTrigger(array $trigger, array $items = null, array $acknowl
 		'acknowledge' => $acknowledge,
 		'eventTime' => $eventTime,
 		'configuration' => null,
-		'url' => resolveTriggerUrl($trigger)
+		'url' => CMacrosResolverHelper::resolveTriggerUrl($trigger)
 	);
 
 	if ((CWebUser::$data['type'] == USER_TYPE_ZABBIX_ADMIN || CWebUser::$data['type'] == USER_TYPE_SUPER_ADMIN)
diff --git a/include/triggers.inc.php b/include/triggers.inc.php
index b858b44..388dffe 100644
--- a/include/triggers.inc.php
+++ b/include/triggers.inc.php
@@ -2421,19 +2421,6 @@ function evalExpressionData($expression, $rplcts) {
 	);
 }
 
-/**
- * Resolve {TRIGGER.ID} macro in trigger url.
- *
- * @param array  $trigger				trigger data with url and triggerid
- * @param int    $trigger['triggerid']
- * @param string $trigger['url']
- *
- * @return string
- */
-function resolveTriggerUrl($trigger) {
-	return str_replace('{TRIGGER.ID}', $trigger['triggerid'], $trigger['url']);
-}
-
 function convert($value) {
 	$value = trim($value);
 	if (!preg_match('/(?P<value>[\-+]?[0-9]+[.]?[0-9]*)(?P<mult>['.ZBX_BYTE_SUFFIXES.ZBX_TIME_SUFFIXES.']?)/', $value, $arr)) {
