]> git.wh0rd.org - tt-rss.git/commitdiff
digest improvements and bugfixes
authorAndrew Dolgov <fox@madoka.spb.ru>
Tue, 30 Oct 2007 06:57:03 +0000 (07:57 +0100)
committerAndrew Dolgov <fox@madoka.spb.ru>
Tue, 30 Oct 2007 06:57:03 +0000 (07:57 +0100)
13 files changed:
MiniTemplator.class.php [new file with mode: 0644]
config.php-dist
functions.php
locale/fr_FR/LC_MESSAGES/messages.mo
locale/fr_FR/LC_MESSAGES/messages.po
locale/pt_BR/LC_MESSAGES/messages.mo
locale/pt_BR/LC_MESSAGES/messages.po
locale/ru_RU/LC_MESSAGES/messages.mo
locale/ru_RU/LC_MESSAGES/messages.po
locale/zh_CN/LC_MESSAGES/messages.mo
locale/zh_CN/LC_MESSAGES/messages.po
templates/digest_template.txt [new file with mode: 0644]
templates/digest_template_html.txt [new file with mode: 0644]

diff --git a/MiniTemplator.class.php b/MiniTemplator.class.php
new file mode 100644 (file)
index 0000000..69281cb
--- /dev/null
@@ -0,0 +1,922 @@
+<?php\r
+/**\r
+* File MiniTemplator.class.php\r
+* @package MiniTemplator\r
+*/\r
+\r
+/**\r
+* A compact template engine for HTML files.\r
+*\r
+* Requires PHP 4.0.4 or newer.\r
+*\r
+* <pre>\r
+* Template syntax:\r
+*\r
+*   Variables:\r
+*     ${VariableName}\r
+*\r
+*   Blocks:\r
+*     &lt;!-- $BeginBlock BlockName --&gt;\r
+*     ... block content ...\r
+*     &lt;!-- $EndBlock BlockName --&gt;\r
+*\r
+*   Include a subtemplate:\r
+*     &lt;!-- $Include RelativeFileName --&gt;\r
+* </pre>\r
+*\r
+* <pre>\r
+* General remarks:\r
+*  - Variable names and block names are case-insensitive.\r
+*  - The same variable may be used multiple times within a template.\r
+*  - Blocks can be nested.\r
+*  - Multiple blocks with the same name may occur within a template.\r
+* </pre>\r
+*\r
+* <pre>\r
+* Public methods:\r
+*   readTemplateFromFile   - Reads the template from a file.\r
+*   setTemplateString      - Assigns a new template string.\r
+*   setVariable            - Sets a template variable.\r
+*   setVariableEsc         - Sets a template variable to an escaped string value.\r
+*   variableExists         - Checks whether a template variable exists.\r
+*   addBlock               - Adds an instance of a template block.\r
+*   blockExists            - Checks whether a block exists.\r
+*   reset                  - Clears all variables and blocks.\r
+*   generateOutput         - Generates the HTML page and writes it to the PHP output stream.\r
+*   generateOutputToFile   - Generates the HTML page and writes it to a file.\r
+*   generateOutputToString - Generates the HTML page and writes it to a string.\r
+* </pre>\r
+*\r
+* Home page: {@link http://www.source-code.biz/MiniTemplator}<br>\r
+* License: This module is released under the GNU/LGPL license ({@link http://www.gnu.org/licenses/lgpl.html}).<br>\r
+* Copyright 2003: Christian d'Heureuse, Inventec Informatik AG, Switzerland. All rights reserved.<br>\r
+* This product is provided "as is" without warranty of any kind.<br>\r
+*\r
+* Version history:<br>\r
+* 2001-10-24 Christian d'Heureuse (chdh): VBasic version created.<br>\r
+* 2002-01-26 Markus Angst: ported to PHP4.<br>\r
+* 2003-04-07 chdh: changes to adjust to Java version.<br>\r
+* 2003-07-08 chdh: Method variableExists added.\r
+*   Method setVariable changed to trigger an error when the variable does not exist.<br>\r
+* 2004-04-07 chdh: Parameter isOptional added to method setVariable.\r
+*   Licensing changed from GPL to LGPL.<br>\r
+* 2004-04-18 chdh: Method blockExists added.<br>\r
+* 2004-10-28 chdh:<br>\r
+*   Method setVariableEsc added.<br>\r
+*   Multiple blocks with the same name may now occur within a template.<br>\r
+*   No error ("unknown command") is generated any more, if a HTML comment starts with "${".<br>\r
+* 2004-11-06 chdh:<br>\r
+*   "$Include" command implemented.<br>\r
+* 2004-11-20 chdh:<br>\r
+*   "$Include" command changed so that the command text is not copied to the output file.<br>\r
+*/\r
+\r
+class MiniTemplator {\r
+\r
+//--- public member variables ---------------------------------------------------------------------------------------\r
+\r
+/**\r
+* Base path for relative file names of subtemplates (for the $Include command).\r
+* This path is prepended to the subtemplate file names. It must be set before\r
+* readTemplateFromFile or setTemplateString.\r
+* @access public\r
+*/\r
+var $subtemplateBasePath;\r
+\r
+//--- private member variables --------------------------------------------------------------------------------------\r
+\r
+/**#@+\r
+* @access private\r
+*/\r
+\r
+var $maxNestingLevel = 50;            // maximum number of block nestings\r
+var $maxInclTemplateSize = 1000000;   // maximum length of template string when including subtemplates\r
+var $template;                        // Template file data\r
+var $varTab;                          // variables table, array index is variable no\r
+    // Fields:\r
+    //  varName                       // variable name\r
+    //  varValue                      // variable value\r
+var $varTabCnt;                       // no of entries used in VarTab\r
+var $varNameToNoMap;                  // maps variable names to variable numbers\r
+var $varRefTab;                       // variable references table\r
+    // Contains an entry for each variable reference in the template. Ordered by TemplatePos.\r
+    // Fields:\r
+    //  varNo                         // variable no\r
+    //  tPosBegin                     // template position of begin of variable reference\r
+    //  tPosEnd                       // template position of end of variable reference\r
+    //  blockNo                       // block no of the (innermost) block that contains this variable reference\r
+    //  blockVarNo                    // block variable no. Index into BlockInstTab.BlockVarTab\r
+var $varRefTabCnt;                    // no of entries used in VarRefTab\r
+var $blockTab;                        // Blocks table, array index is block no\r
+    // Contains an entry for each block in the template. Ordered by TPosBegin.\r
+    // Fields:\r
+    //  blockName                     // block name\r
+    //  nextWithSameName;             // block no of next block with same name or -1 (blocks are backward linked in relation to template position)\r
+    //  tPosBegin                     // template position of begin of block\r
+    //  tPosContentsBegin             // template pos of begin of block contents\r
+    //  tPosContentsEnd               // template pos of end of block contents\r
+    //  tPosEnd                       // template position of end of block\r
+    //  nestingLevel                  // block nesting level\r
+    //  parentBlockNo                 // block no of parent block\r
+    //  definitionIsOpen              // true while $BeginBlock processed but no $EndBlock\r
+    //  instances                     // number of instances of this block\r
+    //  firstBlockInstNo              // block instance no of first instance of this block or -1\r
+    //  lastBlockInstNo               // block instance no of last instance of this block or -1\r
+    //  currBlockInstNo               // current block instance no, used during generation of output file\r
+    //  blockVarCnt                   // no of variables in block\r
+    //  blockVarNoToVarNoMap          // maps block variable numbers to variable numbers\r
+    //  firstVarRefNo                 // variable reference no of first variable of this block or -1\r
+var $blockTabCnt;                     // no of entries used in BlockTab\r
+var $blockNameToNoMap;                // maps block names to block numbers\r
+var $openBlocksTab;\r
+    // During parsing, this table contains the block numbers of the open parent blocks (nested outer blocks).\r
+    // Indexed by the block nesting level.\r
+var $blockInstTab;                    // block instances table\r
+    // This table contains an entry for each block instance that has been added.\r
+    // Indexed by BlockInstNo.\r
+    // Fields:\r
+    //  blockNo                       // block number\r
+    //  instanceLevel                 // instance level of this block\r
+    //     InstanceLevel is an instance counter per block.\r
+    //     (In contrast to blockInstNo, which is an instance counter over the instances of all blocks)\r
+    //  parentInstLevel               // instance level of parent block\r
+    //  nextBlockInstNo               // pointer to next instance of this block or -1\r
+    //     Forward chain for instances of same block.\r
+    //  blockVarTab                   // block instance variables\r
+var $blockInstTabCnt;                 // no of entries used in BlockInstTab\r
+\r
+var $currentNestingLevel;             // Current block nesting level during parsing.\r
+var $templateValid;                   // true if a valid template is prepared\r
+var $outputMode;                      // 0 = to PHP output stream, 1 = to file, 2 = to string\r
+var $outputFileHandle;                // file handle during writing of output file\r
+var $outputError;                     // true when an output error occurred\r
+var $outputString;                    // string buffer for the generated HTML page\r
+\r
+/**#@-*/\r
+\r
+//--- constructor ---------------------------------------------------------------------------------------------------\r
+\r
+/**\r
+* Constructs a MiniTemplator object.\r
+* @access public\r
+*/\r
+function MiniTemplator() {\r
+   $this->templateValid = false; }\r
+\r
+//--- template string handling --------------------------------------------------------------------------------------\r
+\r
+/**\r
+* Reads the template from a file.\r
+* @param  string   $fileName  name of the file that contains the template.\r
+* @return boolean  true on success, false on error.\r
+* @access public\r
+*/\r
+function readTemplateFromFile ($fileName) {\r
+   if (!$this->readFileIntoString($fileName,$s)) {\r
+      $this->triggerError ("Error while reading template file " . $fileName . ".");\r
+      return false; }\r
+   if (!$this->setTemplateString($s)) return false;\r
+   return true; }\r
+\r
+/**\r
+* Assigns a new template string.\r
+* @param  string   $templateString  contents of the template file.\r
+* @return boolean  true on success, false on error.\r
+* @access public\r
+*/\r
+function setTemplateString ($templateString) {\r
+   $this->templateValid = false;\r
+   $this->template = $templateString;\r
+   if (!$this->parseTemplate()) return false;\r
+   $this->reset();\r
+   $this->templateValid = true;\r
+   return true; }\r
+\r
+/**\r
+* Loads the template string for a subtemplate (used for the $Include command).\r
+* @return boolean  true on success, false on error.\r
+* @access private\r
+*/\r
+function loadSubtemplate ($subtemplateName, &$s) {\r
+   $subtemplateFileName = $this->combineFileSystemPath($this->subtemplateBasePath,$subtemplateName);\r
+   if (!$this->readFileIntoString($subtemplateFileName,$s)) {\r
+      $this->triggerError ("Error while reading subtemplate file " . $subtemplateFileName . ".");\r
+      return false; }\r
+   return true; }\r
+\r
+//--- template parsing ----------------------------------------------------------------------------------------------\r
+\r
+/**\r
+* Parses the template.\r
+* @return boolean  true on success, false on error.\r
+* @access private\r
+*/\r
+function parseTemplate() {\r
+   $this->initParsing();\r
+   $this->beginMainBlock();\r
+   if (!$this->parseTemplateCommands()) return false;\r
+   $this->endMainBlock();\r
+   if (!$this->checkBlockDefinitionsComplete()) return false;\r
+   if (!$this->parseTemplateVariables()) return false;\r
+   $this->associateVariablesWithBlocks();\r
+   return true; }\r
+\r
+/**\r
+* @access private\r
+*/\r
+function initParsing() {\r
+   $this->varTab = array();\r
+   $this->varTabCnt = 0;\r
+   $this->varNameToNoMap = array();\r
+   $this->varRefTab = array();\r
+   $this->varRefTabCnt = 0;\r
+   $this->blockTab = array();\r
+   $this->blockTabCnt = 0;\r
+   $this->blockNameToNoMap = array();\r
+   $this->openBlocksTab = array(); }\r
+\r
+/**\r
+* Registers the main block.\r
+* The main block is an implicitly defined block that covers the whole template.\r
+* @access private\r
+*/\r
+function beginMainBlock() {\r
+   $blockNo = 0;\r
+   $this->registerBlock('@@InternalMainBlock@@', $blockNo);\r
+   $bte =& $this->blockTab[$blockNo];\r
+   $bte['tPosBegin'] = 0;\r
+   $bte['tPosContentsBegin'] = 0;\r
+   $bte['nestingLevel'] = 0;\r
+   $bte['parentBlockNo'] = -1;\r
+   $bte['definitionIsOpen'] = true;\r
+   $this->openBlocksTab[0] = $blockNo;\r
+   $this->currentNestingLevel = 1; }\r
+\r
+/**\r
+* Completes the main block registration.\r
+* @access private\r
+*/\r
+function endMainBlock() {\r
+   $bte =& $this->blockTab[0];\r
+   $bte['tPosContentsEnd'] = strlen($this->template);\r
+   $bte['tPosEnd'] = strlen($this->template);\r
+   $bte['definitionIsOpen'] = false;\r
+   $this->currentNestingLevel -= 1; }\r
+\r
+/**\r
+* Parses commands within the template in the format "<!-- $command parameters -->".\r
+* @return boolean  true on success, false on error.\r
+* @access private\r
+*/\r
+function parseTemplateCommands() {\r
+   $p = 0;\r
+   while (true) {\r
+      $p0 = strpos($this->template,'<!--',$p);\r
+      if ($p0 === false) break;\r
+      $p = strpos($this->template,'-->',$p0);\r
+      if ($p === false) {\r
+         $this->triggerError ("Invalid HTML comment in template at offset $p0.");\r
+         return false; }\r
+      $p += 3;\r
+      $cmdL = substr($this->template,$p0+4,$p-$p0-7);\r
+      if (!$this->processTemplateCommand($cmdL,$p0,$p,$resumeFromStart))\r
+         return false;\r
+      if ($resumeFromStart) $p = $p0; }\r
+   return true; }\r
+\r
+/**\r
+* @return boolean  true on success, false on error.\r
+* @access private\r
+*/\r
+function processTemplateCommand ($cmdL, $cmdTPosBegin, $cmdTPosEnd, &$resumeFromStart) {\r
+   $resumeFromStart = false;\r
+   $p = 0;\r
+   $cmd = '';\r
+   if (!$this->parseWord($cmdL,$p,$cmd)) return true;\r
+   $parms = substr($cmdL,$p);\r
+   switch (strtoupper($cmd)) {\r
+      case '$BEGINBLOCK':\r
+         if (!$this->processBeginBlockCmd($parms,$cmdTPosBegin,$cmdTPosEnd))\r
+            return false;\r
+         break;\r
+      case '$ENDBLOCK':\r
+         if (!$this->processEndBlockCmd($parms,$cmdTPosBegin,$cmdTPosEnd))\r
+            return false;\r
+         break;\r
+      case '$INCLUDE':\r
+         if (!$this->processincludeCmd($parms,$cmdTPosBegin,$cmdTPosEnd))\r
+            return false;\r
+         $resumeFromStart = true;\r
+         break;\r
+      default:\r
+         if ($cmd{0} == '$' && !(strlen($cmd) >= 2 && $cmd{1} == '{')) {\r
+            $this->triggerError ("Unknown command \"$cmd\" in template at offset $cmdTPosBegin.");\r
+            return false; }}\r
+    return true; }\r
+\r
+/**\r
+* Processes the $BeginBlock command.\r
+* @return boolean  true on success, false on error.\r
+* @access private\r
+*/\r
+function processBeginBlockCmd ($parms, $cmdTPosBegin, $cmdTPosEnd) {\r
+   $p = 0;\r
+   if (!$this->parseWord($parms,$p,$blockName)) {\r
+      $this->triggerError ("Missing block name in \$BeginBlock command in template at offset $cmdTPosBegin.");\r
+      return false; }\r
+   if (trim(substr($parms,$p)) != '') {\r
+      $this->triggerError ("Extra parameter in \$BeginBlock command in template at offset $cmdTPosBegin.");\r
+      return false; }\r
+   $this->registerBlock ($blockName, $blockNo);\r
+   $btr =& $this->blockTab[$blockNo];\r
+   $btr['tPosBegin'] = $cmdTPosBegin;\r
+   $btr['tPosContentsBegin'] = $cmdTPosEnd;\r
+   $btr['nestingLevel'] = $this->currentNestingLevel;\r
+   $btr['parentBlockNo'] = $this->openBlocksTab[$this->currentNestingLevel-1];\r
+   $this->openBlocksTab[$this->currentNestingLevel] = $blockNo;\r
+   $this->currentNestingLevel += 1;\r
+   if ($this->currentNestingLevel > $this->maxNestingLevel) {\r
+      $trhis->triggerError ("Block nesting overflow in template at offset $cmdTPosBegin.");\r
+      return false; }\r
+   return true; }\r
+\r
+/**\r
+* Processes the $EndBlock command.\r
+* @return boolean  true on success, false on error.\r
+* @access private\r
+*/\r
+function processEndBlockCmd ($parms, $cmdTPosBegin, $cmdTPosEnd) {\r
+   $p = 0;\r
+   if (!$this->parseWord($parms,$p,$blockName)) {\r
+      $this->triggerError ("Missing block name in \$EndBlock command in template at offset $cmdTPosBegin.");\r
+      return false; }\r
+   if (trim(substr($parms,$p)) != '') {\r
+      $this->triggerError ("Extra parameter in \$EndBlock command in template at offset $cmdTPosBegin.");\r
+      return false; }\r
+   if (!$this->lookupBlockName($blockName,$blockNo)) {\r
+      $this->triggerError ("Undefined block name \"$blockName\" in \$EndBlock command in template at offset $cmdTPosBegin.");\r
+      return false; }\r
+   $this->currentNestingLevel -= 1;\r
+   $btr =& $this->blockTab[$blockNo];\r
+   if (!$btr['definitionIsOpen']) {\r
+      $this->triggerError ("Multiple \$EndBlock command for block \"$blockName\" in template at offset $cmdTPosBegin.");\r
+      return false; }\r
+   if ($btr['nestingLevel'] != $this->currentNestingLevel) {\r
+      $this->triggerError ("Block nesting level mismatch at \$EndBlock command for block \"$blockName\" in template at offset $cmdTPosBegin.");\r
+      return false; }\r
+   $btr['tPosContentsEnd'] = $cmdTPosBegin;\r
+   $btr['tPosEnd'] = $cmdTPosEnd;\r
+   $btr['definitionIsOpen'] = false;\r
+   return true; }\r
+\r
+/**\r
+* @access private\r
+*/\r
+function registerBlock($blockName, &$blockNo) {\r
+   $blockNo = $this->blockTabCnt++;\r
+   $btr =& $this->blockTab[$blockNo];\r
+   $btr = array();\r
+   $btr['blockName'] = $blockName;\r
+   if (!$this->lookupBlockName($blockName,$btr['nextWithSameName']))\r
+      $btr['nextWithSameName'] = -1;\r
+   $btr['definitionIsOpen'] = true;\r
+   $btr['instances'] = 0;\r
+   $btr['firstBlockInstNo'] = -1;\r
+   $btr['lastBlockInstNo'] = -1;\r
+   $btr['blockVarCnt'] = 0;\r
+   $btr['firstVarRefNo'] = -1;\r
+   $btr['blockVarNoToVarNoMap'] = array();\r
+   $this->blockNameToNoMap[strtoupper($blockName)] = $blockNo; }\r
+\r
+/**\r
+* Checks that all block definitions are closed.\r
+* @return boolean  true on success, false on error.\r
+* @access private\r
+*/\r
+function checkBlockDefinitionsComplete() {\r
+   for ($blockNo=0; $blockNo < $this->blockTabCnt; $blockNo++) {\r
+      $btr =& $this->blockTab[$blockNo];\r
+      if ($btr['definitionIsOpen']) {\r
+         $this->triggerError ("Missing \$EndBlock command in template for block " . $btr['blockName'] . ".");\r
+         return false; }}\r
+   if ($this->currentNestingLevel != 0) {\r
+      $this->triggerError ("Block nesting level error at end of template.");\r
+      return false; }\r
+   return true; }\r
+\r
+/**\r
+* Processes the $Include command.\r
+* @return boolean  true on success, false on error.\r
+* @access private\r
+*/\r
+function processIncludeCmd ($parms, $cmdTPosBegin, $cmdTPosEnd) {\r
+   $p = 0;\r
+   if (!$this->parseWordOrQuotedString($parms,$p,$subtemplateName)) {\r
+      $this->triggerError ("Missing or invalid subtemplate name in \$Include command in template at offset $cmdTPosBegin.");\r
+      return false; }\r
+   if (trim(substr($parms,$p)) != '') {\r
+      $this->triggerError ("Extra parameter in \$include command in template at offset $cmdTPosBegin.");\r
+      return false; }\r
+   return $this->insertSubtemplate($subtemplateName,$cmdTPosBegin,$cmdTPosEnd); }\r
+\r
+/**\r
+* Processes the $Include command.\r
+* @return boolean  true on success, false on error.\r
+* @access private\r
+*/\r
+function insertSubtemplate ($subtemplateName, $tPos1, $tPos2) {\r
+   if (strlen($this->template) > $this->maxInclTemplateSize) {\r
+      $this->triggerError ("Subtemplate include aborted because the internal template string is longer than $this->maxInclTemplateSize characters.");\r
+      return false; }\r
+   if (!$this->loadSubtemplate($subtemplateName,$subtemplate)) return false;\r
+   // (Copying the template to insert a subtemplate is a bit slow. In a future implementation of MiniTemplator,\r
+   // a table could be used that contains references to the string fragments.)\r
+   $this->template = substr($this->template,0,$tPos1) . $subtemplate . substr($this->template,$tPos2);\r
+   return true; }\r
+\r
+/**\r
+* Parses variable references within the template in the format "${VarName}".\r
+* @return boolean  true on success, false on error.\r
+* @access private\r
+*/\r
+function parseTemplateVariables() {\r
+   $p = 0;\r
+   while (true) {\r
+      $p = strpos($this->template, '${', $p);\r
+      if ($p === false) break;\r
+      $p0 = $p;\r
+      $p = strpos($this->template, '}', $p);\r
+      if ($p === false) {\r
+         $this->triggerError ("Invalid variable reference in template at offset $p0.");\r
+         return false; }\r
+      $p += 1;\r
+      $varName = trim(substr($this->template, $p0+2, $p-$p0-3));\r
+      if (strlen($varName) == 0) {\r
+         $this->triggerError ("Empty variable name in template at offset $p0.");\r
+         return false; }\r
+      $this->registerVariableReference ($varName, $p0, $p); }\r
+   return true; }\r
+\r
+/**\r
+* @access private\r
+*/\r
+function registerVariableReference ($varName, $tPosBegin, $tPosEnd) {\r
+   if (!$this->lookupVariableName($varName,$varNo))\r
+      $this->registerVariable($varName,$varNo);\r
+   $varRefNo = $this->varRefTabCnt++;\r
+   $vrtr =& $this->varRefTab[$varRefNo];\r
+   $vrtr = array();\r
+   $vrtr['tPosBegin'] = $tPosBegin;\r
+   $vrtr['tPosEnd'] = $tPosEnd;\r
+   $vrtr['varNo'] = $varNo; }\r
+\r
+/**\r
+* @access private\r
+*/\r
+function registerVariable ($varName, &$varNo) {\r
+   $varNo = $this->varTabCnt++;\r
+   $vtr =& $this->varTab[$varNo];\r
+   $vtr = array();\r
+   $vtr['varName'] = $varName;\r
+   $vtr['varValue'] = '';\r
+   $this->varNameToNoMap[strtoupper($varName)] = $varNo; }\r
+\r
+/**\r
+* Associates variable references with blocks.\r
+* @access private\r
+*/\r
+function associateVariablesWithBlocks() {\r
+   $varRefNo = 0;\r
+   $activeBlockNo = 0;\r
+   $nextBlockNo = 1;\r
+   while ($varRefNo < $this->varRefTabCnt) {\r
+      $vrtr =& $this->varRefTab[$varRefNo];\r
+      $varRefTPos = $vrtr['tPosBegin'];\r
+      $varNo = $vrtr['varNo'];\r
+      if ($varRefTPos >= $this->blockTab[$activeBlockNo]['tPosEnd']) {\r
+         $activeBlockNo = $this->blockTab[$activeBlockNo]['parentBlockNo'];\r
+         continue; }\r
+      if ($nextBlockNo < $this->blockTabCnt) {\r
+         if ($varRefTPos >= $this->blockTab[$nextBlockNo]['tPosBegin']) {\r
+            $activeBlockNo = $nextBlockNo;\r
+            $nextBlockNo += 1;\r
+            continue; }}\r
+      $btr =& $this->blockTab[$activeBlockNo];\r
+      if ($varRefTPos < $btr['tPosBegin'])\r
+         $this->programLogicError(1);\r
+      $blockVarNo = $btr['blockVarCnt']++;\r
+      $btr['blockVarNoToVarNoMap'][$blockVarNo] = $varNo;\r
+      if ($btr['firstVarRefNo'] == -1)\r
+         $btr['firstVarRefNo'] = $varRefNo;\r
+      $vrtr['blockNo'] = $activeBlockNo;\r
+      $vrtr['blockVarNo'] = $blockVarNo;\r
+      $varRefNo += 1; }}\r
+\r
+//--- build up (template variables and blocks) ----------------------------------------------------------------------\r
+\r
+/**\r
+* Clears all variables and blocks.\r
+* This method can be used to produce another HTML page with the same\r
+* template. It is faster than creating another MiniTemplator object,\r
+* because the template does not have to be parsed again.\r
+* All variable values are cleared and all added block instances are deleted.\r
+* @access public\r
+*/\r
+function reset() {\r
+   for ($varNo=0; $varNo<$this->varTabCnt; $varNo++)\r
+      $this->varTab[$varNo]['varValue'] = '';\r
+   for ($blockNo=0; $blockNo<$this->blockTabCnt; $blockNo++) {\r
+      $btr =& $this->blockTab[$blockNo];\r
+      $btr['instances'] = 0;\r
+      $btr['firstBlockInstNo'] = -1;\r
+      $btr['lastBlockInstNo'] = -1; }\r
+   $this->blockInstTab = array();\r
+   $this->blockInstTabCnt = 0; }\r
+\r
+/**\r
+* Sets a template variable.\r
+* For variables that are used in blocks, the variable value\r
+* must be set before {@link addBlock} is called.\r
+* @param  string  $variableName   the name of the variable to be set.\r
+* @param  string  $variableValue  the new value of the variable.\r
+* @param  boolean $isOptional     Specifies whether an error should be\r
+*    generated when the variable does not exist in the template. If\r
+*    $isOptional is false and the variable does not exist, an error is\r
+*    generated.\r
+* @return boolean true on success, or false on error (e.g. when no\r
+*    variable with the specified name exists in the template and\r
+*    $isOptional is false).\r
+* @access public\r
+*/\r
+function setVariable ($variableName, $variableValue, $isOptional=false) {\r
+   if (!$this->templateValid) {$this->triggerError ("Template not valid."); return false; }\r
+   if (!$this->lookupVariableName($variableName,$varNo)) {\r
+      if ($isOptional) return true;\r
+      $this->triggerError ("Variable \"$variableName\" not defined in template.");\r
+      return false; }\r
+   $this->varTab[$varNo]['varValue'] = $variableValue;\r
+   return true; }\r
+\r
+/**\r
+* Sets a template variable to an escaped string.\r
+* This method is identical to (@link setVariable), except that\r
+* the characters &lt;, &gt;, &amp;, ' and " of variableValue are\r
+* replaced by their corresponding HTML/XML character entity codes.\r
+* For variables that are used in blocks, the variable value\r
+* must be set before {@link addBlock} is called.\r
+* @param  string  $variableName   the name of the variable to be set.\r
+* @param  string  $variableValue  the new value of the variable. Special HTML/XML characters are escaped.\r
+* @param  boolean $isOptional     Specifies whether an error should be\r
+*    generated when the variable does not exist in the template. If\r
+*    $isOptional is false and the variable does not exist, an error is\r
+*    generated.\r
+* @return boolean true on success, or false on error (e.g. when no\r
+*    variable with the specified name exists in the template and\r
+*    $isOptional is false).\r
+* @access public\r
+*/\r
+function setVariableEsc ($variableName, $variableValue, $isOptional=false) {\r
+   return $this->setVariable($variableName,htmlspecialchars($variableValue,ENT_QUOTES),$isOptional); }\r
+\r
+/**\r
+* Checks whether a variable with the specified name exists within the template.\r
+* @param  string  $variableName   the name of the variable.\r
+* @return boolean true if the variable exists, or false when no\r
+*    variable with the specified name exists in the template.\r
+* @access public\r
+*/\r
+function variableExists ($variableName) {\r
+   if (!$this->templateValid) {$this->triggerError ("Template not valid."); return false; }\r
+   return $this->lookupVariableName($variableName,$varNo); }\r
+\r
+/**\r
+* Adds an instance of a template block.\r
+* If the block contains variables, these variables must be set\r
+* before the block is added.\r
+* If the block contains subblocks (nested blocks), the subblocks\r
+* must be added before this block is added.\r
+* If multiple blocks exist with the specified name, an instance\r
+* is added for each block occurence.\r
+* @param  string   blockName the name of the block to be added.\r
+* @return boolean  true on success, false on error (e.g. when no\r
+*    block with the specified name exists in the template).\r
+* @access public\r
+*/\r
+function addBlock($blockName) {\r
+   if (!$this->templateValid) {$this->triggerError ("Template not valid."); return false; }\r
+   if (!$this->lookupBlockName($blockName,$blockNo)) {\r
+      $this->triggerError ("Block \"$blockName\" not defined in template.");\r
+      return false; }\r
+   while ($blockNo != -1) {\r
+      $this->addBlockByNo($blockNo);\r
+      $blockNo = $this->blockTab[$blockNo]['nextWithSameName']; }\r
+   return true; }\r
+\r
+/**\r
+* @access private\r
+*/\r
+function addBlockByNo ($blockNo) {\r
+   $btr =& $this->blockTab[$blockNo];\r
+   $this->registerBlockInstance ($blockInstNo);\r
+   $bitr =& $this->blockInstTab[$blockInstNo];\r
+   if ($btr['firstBlockInstNo'] == -1)\r
+      $btr['firstBlockInstNo'] = $blockInstNo;\r
+   if ($btr['lastBlockInstNo'] != -1)\r
+      $this->blockInstTab[$btr['lastBlockInstNo']]['nextBlockInstNo'] = $blockInstNo;\r
+         // set forward pointer of chain\r
+   $btr['lastBlockInstNo'] = $blockInstNo;\r
+   $parentBlockNo = $btr['parentBlockNo'];\r
+   $blockVarCnt = $btr['blockVarCnt'];\r
+   $bitr['blockNo'] = $blockNo;\r
+   $bitr['instanceLevel'] = $btr['instances']++;\r
+   if ($parentBlockNo == -1)\r
+      $bitr['parentInstLevel'] = -1;\r
+    else\r
+      $bitr['parentInstLevel'] = $this->blockTab[$parentBlockNo]['instances'];\r
+   $bitr['nextBlockInstNo'] = -1;\r
+   $bitr['blockVarTab'] = array();\r
+   // copy instance variables for this block\r
+   for ($blockVarNo=0; $blockVarNo<$blockVarCnt; $blockVarNo++) {\r
+      $varNo = $btr['blockVarNoToVarNoMap'][$blockVarNo];\r
+      $bitr['blockVarTab'][$blockVarNo] = $this->varTab[$varNo]['varValue']; }}\r
+\r
+/**\r
+* @access private\r
+*/\r
+function registerBlockInstance (&$blockInstNo) {\r
+   $blockInstNo = $this->blockInstTabCnt++; }\r
+\r
+/**\r
+* Checks whether a block with the specified name exists within the template.\r
+* @param  string  $blockName   the name of the block.\r
+* @return boolean true if the block exists, or false when no\r
+*    block with the specified name exists in the template.\r
+* @access public\r
+*/\r
+function blockExists ($blockName) {\r
+   if (!$this->templateValid) {$this->triggerError ("Template not valid."); return false; }\r
+   return $this->lookupBlockName($blockName,$blockNo); }\r
+\r
+//--- output generation ---------------------------------------------------------------------------------------------\r
+\r
+/**\r
+* Generates the HTML page and writes it to the PHP output stream.\r
+* @return boolean  true on success, false on error.\r
+* @access public\r
+*/\r
+function generateOutput () {\r
+   $this->outputMode = 0;\r
+   if (!$this->generateOutputPage()) return false;\r
+   return true; }\r
+\r
+/**\r
+* Generates the HTML page and writes it to a file.\r
+* @param  string   $fileName  name of the output file.\r
+* @return boolean  true on success, false on error.\r
+* @access public\r
+*/\r
+function generateOutputToFile ($fileName) {\r
+   $fh = fopen($fileName,"wb");\r
+   if ($fh === false) return false;\r
+   $this->outputMode = 1;\r
+   $this->outputFileHandle = $fh;\r
+   $ok = $this->generateOutputPage();\r
+   fclose ($fh);\r
+   return $ok; }\r
+\r
+/**\r
+* Generates the HTML page and writes it to a string.\r
+* @param  string   $outputString  variable that receives\r
+*                  the contents of the generated HTML page.\r
+* @return boolean  true on success, false on error.\r
+* @access public\r
+*/\r
+function generateOutputToString (&$outputString) {\r
+   $outputString = "Error";\r
+   $this->outputMode = 2;\r
+   $this->outputString = "";\r
+   if (!$this->generateOutputPage()) return false;\r
+   $outputString = $this->outputString;\r
+   return true; }\r
+\r
+/**\r
+* @access private\r
+* @return boolean  true on success, false on error.\r
+*/\r
+function generateOutputPage() {\r
+   if (!$this->templateValid) {$this->triggerError ("Template not valid."); return false; }\r
+   if ($this->blockTab[0]['instances'] == 0)\r
+      $this->addBlockByNo (0);        // add main block\r
+   for ($blockNo=0; $blockNo < $this->blockTabCnt; $blockNo++) {\r
+       $btr =& $this->blockTab[$blockNo];\r
+       $btr['currBlockInstNo'] = $btr['firstBlockInstNo']; }\r
+   $this->outputError = false;\r
+   $this->writeBlockInstances (0, -1);\r
+   if ($this->outputError) return false;\r
+   return true; }\r
+\r
+/**\r
+* Writes all instances of a block that are contained within a specific\r
+* parent block instance.\r
+* Called recursively.\r
+* @access private\r
+*/\r
+function writeBlockInstances ($blockNo, $parentInstLevel) {\r
+   $btr =& $this->blockTab[$blockNo];\r
+   while (!$this->outputError) {\r
+      $blockInstNo = $btr['currBlockInstNo'];\r
+      if ($blockInstNo == -1) break;\r
+      $bitr =& $this->blockInstTab[$blockInstNo];\r
+      if ($bitr['parentInstLevel'] < $parentInstLevel)\r
+         $this->programLogicError (2);\r
+      if ($bitr['parentInstLevel'] > $parentInstLevel) break;\r
+      $this->writeBlockInstance ($blockInstNo);\r
+      $btr['currBlockInstNo'] = $bitr['nextBlockInstNo']; }}\r
+\r
+/**\r
+* @access private\r
+*/\r
+function writeBlockInstance($blockInstNo) {\r
+   $bitr =& $this->blockInstTab[$blockInstNo];\r
+   $blockNo = $bitr['blockNo'];\r
+   $btr =& $this->blockTab[$blockNo];\r
+   $tPos = $btr['tPosContentsBegin'];\r
+   $subBlockNo = $blockNo + 1;\r
+   $varRefNo = $btr['firstVarRefNo'];\r
+   while (!$this->outputError) {\r
+      $tPos2 = $btr['tPosContentsEnd'];\r
+      $kind = 0;                                // assume end-of-block\r
+      if ($varRefNo != -1 && $varRefNo < $this->varRefTabCnt) {  // check for variable reference\r
+         $vrtr =& $this->varRefTab[$varRefNo];\r
+         if ($vrtr['tPosBegin'] < $tPos) {\r
+            $varRefNo += 1;\r
+            continue; }\r
+         if ($vrtr['tPosBegin'] < $tPos2) {\r
+            $tPos2 = $vrtr['tPosBegin'];\r
+            $kind = 1; }}\r
+      if ($subBlockNo < $this->blockTabCnt) {   // check for subblock\r
+         $subBtr =& $this->blockTab[$subBlockNo];\r
+         if ($subBtr['tPosBegin'] < $tPos) {\r
+            $subBlockNo += 1;\r
+            continue; }\r
+         if ($subBtr['tPosBegin'] < $tPos2) {\r
+            $tPos2 = $subBtr['tPosBegin'];\r
+            $kind = 2; }}\r
+      if ($tPos2 > $tPos)\r
+         $this->writeString (substr($this->template,$tPos,$tPos2-$tPos));\r
+      switch ($kind) {\r
+         case 0:         // end of block\r
+            return;\r
+         case 1:         // variable\r
+            $vrtr =& $this->varRefTab[$varRefNo];\r
+            if ($vrtr['blockNo'] != $blockNo)\r
+               $this->programLogicError (4);\r
+            $variableValue = $bitr['blockVarTab'][$vrtr['blockVarNo']];\r
+            $this->writeString ($variableValue);\r
+            $tPos = $vrtr['tPosEnd'];\r
+            $varRefNo += 1;\r
+            break;\r
+         case 2:         // sub block\r
+            $subBtr =& $this->blockTab[$subBlockNo];\r
+            if ($subBtr['parentBlockNo'] != $blockNo)\r
+               $this->programLogicError (3);\r
+            $this->writeBlockInstances ($subBlockNo, $bitr['instanceLevel']);  // recursive call\r
+            $tPos = $subBtr['tPosEnd'];\r
+            $subBlockNo += 1;\r
+            break; }}}\r
+\r
+/**\r
+* @access private\r
+*/\r
+function writeString ($s) {\r
+   if ($this->outputError) return;\r
+   switch ($this->outputMode) {\r
+      case 0:            // output to PHP output stream\r
+         if (!print($s))\r
+            $this->outputError = true;\r
+         break;\r
+      case 1:            // output to file\r
+         $rc = fwrite($this->outputFileHandle, $s);\r
+         if ($rc === false) $this->outputError = true;\r
+         break;\r
+      case 2:            // output to string\r
+         $this->outputString .= $s;\r
+         break; }}\r
+\r
+//--- name lookup routines ------------------------------------------------------------------------------------------\r
+\r
+/**\r
+* Maps variable name to variable number.\r
+* @return boolean  true on success, false if the variable is not found.\r
+* @access private\r
+*/\r
+function lookupVariableName ($varName, &$varNo) {\r
+   $x =& $this->varNameToNoMap[strtoupper($varName)];\r
+   if (!isset($x)) return false;\r
+   $varNo = $x;\r
+   return true; }\r
+\r
+/**\r
+* Maps block name to block number.\r
+* If there are multiple blocks with the same name, the block number of the last\r
+* registered block with that name is returned.\r
+* @return boolean  true on success, false when the block is not found.\r
+* @access private\r
+*/\r
+function lookupBlockName ($blockName, &$blockNo) {\r
+   $x =& $this->blockNameToNoMap[strtoupper($blockName)];\r
+   if (!isset($x)) return false;\r
+   $blockNo = $x;\r
+   return true; }\r
+\r
+//--- general utility routines -----------------------------------------------------------------------------------------\r
+\r
+/**\r
+* Reads a file into a string.\r
+* @return boolean  true on success, false on error.\r
+* @access private\r
+*/\r
+function readFileIntoString ($fileName, &$s) {\r
+   if (function_exists('version_compare') && version_compare(phpversion(),"4.3.0",">=")) {\r
+      $s = file_get_contents($fileName);\r
+      if ($s === false) return false;\r
+      return true; }\r
+   $fh = fopen($fileName,"rb");\r
+   if ($fh === false) return false;\r
+   $fileSize = filesize($fileName);\r
+   if ($fileSize === false) {close ($fh); return false; }\r
+   $s = fread($fh,$fileSize);\r
+   fclose ($fh);\r
+   if (strlen($s) != $fileSize) return false;\r
+   return true; }\r
+\r
+/**\r
+* @access private\r
+* @return boolean  true on success, false when the end of the string is reached.\r
+*/\r
+function parseWord ($s, &$p, &$w) {\r
+   $sLen = strlen($s);\r
+   while ($p < $sLen && ord($s{$p}) <= 32) $p++;\r
+   if ($p >= $sLen) return false;\r
+   $p0 = $p;\r
+   while ($p < $sLen && ord($s{$p}) > 32) $p++;\r
+   $w = substr($s, $p0, $p - $p0);\r
+   return true; }\r
+\r
+/**\r
+* @access private\r
+* @return boolean  true on success, false on error.\r
+*/\r
+function parseQuotedString ($s, &$p, &$w) {\r
+   $sLen = strlen($s);\r
+   while ($p < $sLen && ord($s{$p}) <= 32) $p++;\r
+   if ($p >= $sLen) return false;\r
+   if (substr($s,$p,1) != '"') return false;\r
+   $p++; $p0 = $p;\r
+   while ($p < $sLen && $s{$p} != '"') $p++;\r
+   if ($p >= $sLen) return false;\r
+   $w = substr($s, $p0, $p - $p0);\r
+   $p++;\r
+   return true; }\r
+\r
+/**\r
+* @access private\r
+* @return boolean  true on success, false on error.\r
+*/\r
+function parseWordOrQuotedString ($s, &$p, &$w) {\r
+   $sLen = strlen($s);\r
+   while ($p < $sLen && ord($s{$p}) <= 32) $p++;\r
+   if ($p >= $sLen) return false;\r
+   if (substr($s,$p,1) == '"')\r
+      return $this->parseQuotedString($s,$p,$w);\r
+    else\r
+      return $this->parseWord($s,$p,$w); }\r
+\r
+/**\r
+* Combine two file system paths.\r
+* @access private\r
+*/\r
+function combineFileSystemPath ($path1, $path2) {\r
+   if ($path1 == '' || $path2 == '') return $path2;\r
+   $s = $path1;\r
+   if (substr($s,-1) != '\\' && substr($s,-1) != '/') $s = $s . "/";\r
+   if (substr($path2,0,1) == '\\' || substr($path2,0,1) == '/')\r
+      $s = $s . substr($path2,1);\r
+    else\r
+      $s = $s . $path2;\r
+   return $s; }\r
+\r
+/**\r
+* @access private\r
+*/\r
+function triggerError ($msg) {\r
+   trigger_error ("MiniTemplator error: $msg", E_USER_ERROR); }\r
+\r
+/**\r
+* @access private\r
+*/\r
+function programLogicError ($errorId) {\r
+   die ("MiniTemplator: Program logic error $errorId.\n"); }\r
+\r
+}\r
+?>\r
index 05ec08ea63c69f6948c1688faeffc0d631acf4b8..6da8eb1f055292aaf545d9de49dcca52cda4fad0 100644 (file)
        define('DIGEST_ENABLE', true);
        // Global option to enable daily digests
 
-       define('DIGEST_HOSTNAME', 'your.domain.dom');
-       // Hostname for email digest signature
-
        define('DIGEST_EMAIL_LIMIT', 10);
        // The maximum amount of emails sent in one digest batch
 
index 9e9eb6f35068407a0c667c51fda253417fef2a69..2303f54ad299057d19e49ff6cd5abab68928b71f 100644 (file)
                                $digest = $tuple[0];
                                $headlines_count = $tuple[1];
                                $affected_ids = $tuple[2];
+                               $digest_text = $tuple[3];
 
                                if ($headlines_count > 0) {
 
-                                       if (!DIGEST_SMTP_HOST) {
+                                       $mail = new PHPMailer();
 
-                                               $rc = mail($line["login"] . " <" . $line["email"] . ">",
-                                                       "[tt-rss] New headlines for last 24 hours", $digest,
-                                                       "From: " . DIGEST_FROM_NAME . " <" . DIGEST_FROM_ADDRESS . ">\n".
-                                                       "Content-Type: text/plain; charset=\"utf-8\"\n".
-                                                       "Content-Transfer-Encoding: 8bit\n");
+                                       $mail->PluginDir = "phpmailer/";
+                                       $mail->SetLanguage("en", "phpmailer/language/");
 
-                                       } else {
-
-                                               $mail = new PHPMailer();
-
-                                               $mail->PluginDir = "phpmailer/";
-                                               $mail->SetLanguage("en", "phpmailer/language/");
+                                       $mail->CharSet = "UTF-8";
 
-                                               $mail->CharSet = "UTF-8";
+                                       $mail->From = DIGEST_FROM_ADDRESS;
+                                       $mail->FromName = DIGEST_FROM_NAME;
+                                       $mail->AddAddress($line["email"], $line["login"]);
 
-                                               $mail->From = DIGEST_FROM_ADDRESS;
-                                               $mail->FromName = DIGEST_FROM_NAME;
-                                               $mail->AddAddress($line["email"], $line["login"]);
+                                       if (DIGEST_SMTP_HOST) {
                                                $mail->Host = DIGEST_SMTP_HOST;
                                                $mail->Mailer = "smtp";
-
                                                $mail->Username = DIGEST_SMTP_LOGIN;
                                                $mail->Password = DIGEST_SMTP_PASSWORD;
+                                       }
 
-                                               $mail->Subject = "[tt-rss] New headlines for last 24 hours";
-                                               $mail->Body = $digest;
+                                       $mail->IsHTML(true);
+                                       $mail->Subject = "[tt-rss] New headlines for last 24 hours";
+                                       $mail->Body = $digest;
+                                       $mail->AltBody = $digest_text;
 
-                                               $rc = $mail->Send();
+                                       $rc = $mail->Send();
 
-                                               if (!$rc) print "ERROR: " . $mail->ErrorInfo;
-
-                                       }
+                                       if (!$rc) print "ERROR: " . $mail->ErrorInfo;
 
                                        print "RC=$rc\n";
 
-                                       if ($rc) {
+                                       if ($rc && $do_catchup) {
                                                print "Marking affected articles as read...\n";
                                                catchupArticlesById($link, $affected_ids, 0, $line["id"]);
                                        }
                        }
                }
 
-//             $digest = prepare_headlines_digest($link, $user_id, $days, $limit);
-
                print "All done.\n";
 
        }
 
        function prepare_headlines_digest($link, $user_id, $days = 1, $limit = 100) {
-               $tmp =  __("New headlines for last 24 hours, as of ") . date("Y/m/d H:m") . "\n";       
-               $tmp .= "=======================================================\n\n";
+
+               require_once "MiniTemplator.class.php";
+
+               $tpl = new MiniTemplator;
+               $tpl_t = new MiniTemplator;
+
+               $tpl->readTemplateFromFile("templates/digest_template_html.txt");
+               $tpl_t->readTemplateFromFile("templates/digest_template.txt");
+
+               $tpl->setVariable('CUR_DATE', date('Y/m/d'));
+               $tpl->setVariable('CUR_TIME', date('G:i'));
+
+               $tpl_t->setVariable('CUR_DATE', date('Y/m/d'));
+               $tpl_t->setVariable('CUR_TIME', date('G:i'));
 
                $affected_ids = array();
 
                                date_entered,
                                ttrss_user_entries.ref_id,
                                link,
+                               SUBSTRING(content, 1, 120) AS excerpt,
                                SUBSTRING(last_updated,1,19) AS last_updated
                        FROM 
                                ttrss_user_entries,ttrss_entries,ttrss_feeds 
                                AND $interval_query
                                AND hidden = false
                                AND ttrss_user_entries.owner_uid = $user_id
-                               AND unread = true ORDER BY ttrss_feeds.title, date_entered DESC
+                               AND unread = true 
+                       ORDER BY ttrss_feeds.title, date_entered DESC
                        LIMIT $limit");
 
                $cur_feed_title = "";
 
                $headlines_count = db_num_rows($result);
 
+               $headlines = array();
+
                while ($line = db_fetch_assoc($result)) {
+                       array_push($headlines, $line);
+               }
+
+               for ($i = 0; $i < sizeof($headlines); $i++) {   
+
+                       $line = $headlines[$i];
 
                        array_push($affected_ids, $line["ref_id"]);
 
                        $updated = smart_date_time(strtotime($line["last_updated"]));
-                       $feed_title = $line["feed_title"];
 
-                       if ($cur_feed_title != $feed_title) {
-                               $cur_feed_title = $feed_title;
+                       $tpl->setVariable('FEED_TITLE', $line["feed_title"]);
+                       $tpl->setVariable('ARTICLE_TITLE', $line["title"]);
+                       $tpl->setVariable('ARTICLE_LINK', $line["link"]);
+                       $tpl->setVariable('ARTICLE_UPDATED', $updated);
+//                     $tpl->setVariable('ARTICLE_EXCERPT', 
+//                             truncate_string(strip_tags($line["excerpt"]), 100));
 
-                               $tmp .= "$feed_title\n\n";
+                       $tpl->addBlock('article');
+
+                       $tpl_t->setVariable('FEED_TITLE', $line["feed_title"]);
+                       $tpl_t->setVariable('ARTICLE_TITLE', $line["title"]);
+                       $tpl_t->setVariable('ARTICLE_LINK', $line["link"]);
+                       $tpl_t->setVariable('ARTICLE_UPDATED', $updated);
+//                     $tpl_t->setVariable('ARTICLE_EXCERPT', 
+//                             truncate_string(strip_tags($line["excerpt"]), 100));
+
+                       $tpl_t->addBlock('article');
+
+                       if ($headlines[$i]['feed_title'] != $headlines[$i+1]['feed_title']) {
+                               $tpl->addBlock('feed');
+                               $tpl_t->addBlock('feed');
                        }
 
-                       $tmp .= " * " . trim($line["title"]) . " - $updated\n";
-                       $tmp .= "   " . trim($line["link"]) . "\n";
-                       $tmp .= "\n";
                }
 
-               $tmp .= "--- \n";
-               $tmp .= __("You have been sent this email because you have enabled daily digests in Tiny Tiny RSS at ") . 
-                       DIGEST_HOSTNAME . "\n".
-                       __("To unsubscribe, visit your configuration options or contact instance owner.\n");
-                       
+               $tpl->addBlock('digest');
+               $tpl->generateOutputToString($tmp);
+
+               $tpl_t->addBlock('digest');
+               $tpl_t->generateOutputToString($tmp_t);
 
-               return array($tmp, $headlines_count, $affected_ids);
+               return array($tmp, $headlines_count, $affected_ids, $tmp_t);
        }
 
        function check_for_update($link, $brief_fmt = true) {
index 4802cdc1134d13cf1e387d802d68ed01a7dc6d94..e7279c7b671bb865ee6623681d48aff739e84788 100644 (file)
Binary files a/locale/fr_FR/LC_MESSAGES/messages.mo and b/locale/fr_FR/LC_MESSAGES/messages.mo differ
index 003545ed6ca02aa029775734aa8f65147e90d33e..6b726b6977093f5bfcdf08aa469cdb70be54a5ad 100644 (file)
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: messages\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-10-29 14:21+0300\n"
+"POT-Creation-Date: 2007-10-30 12:46+0300\n"
 "PO-Revision-Date: 2007-09-27 18:17+0200\n"
 "Last-Translator: Thibaut Cousin <informatique@thibaut-cousin.net>\n"
 "Language-Team: Français <fr@li.org>\n"
@@ -146,16 +146,16 @@ msgstr ""
 "Votre version de MySQL n'est pas gérée pour le moment. Reportez-vous au \n"
 "\t\tsite officiel pour plus d'informations."
 
-#: functions.php:2286 functions.php:2625 functions.php:2985 functions.php:3760
+#: functions.php:2286 functions.php:2625 functions.php:2985 functions.php:3772
 msgid "Starred articles"
 msgstr "Articles remarquables"
 
-#: functions.php:2295 functions.php:2627 functions.php:2987 functions.php:3767
+#: functions.php:2295 functions.php:2627 functions.php:2987 functions.php:3779
 #: modules/pref-feeds.php:1068
 msgid "Published articles"
 msgstr "Articles publiés"
 
-#: functions.php:2304 functions.php:2629 functions.php:2989 functions.php:3745
+#: functions.php:2304 functions.php:2629 functions.php:2989 functions.php:3757
 msgid "Fresh articles"
 msgstr "Nouveaux articles"
 
@@ -164,8 +164,8 @@ msgstr "Nouveaux articles"
 msgid "All feeds"
 msgstr "Tous les flux"
 
-#: functions.php:2576 functions.php:2615 functions.php:2963 functions.php:3924
-#: functions.php:3954 modules/pref-feeds.php:880
+#: functions.php:2576 functions.php:2615 functions.php:2963 functions.php:3936
+#: functions.php:3966 modules/pref-feeds.php:880
 msgid "Uncategorized"
 msgstr "Sans catégorie"
 
@@ -185,142 +185,123 @@ msgstr "Résultats de recherche"
 msgid "Searched for"
 msgstr "Recherché"
 
-#: functions.php:3271
-msgid "New headlines for last 24 hours, as of "
-msgstr "Nouveaux en-têtes dans les dernières 24 heures, à compter de "
-
-#: functions.php:3322
-msgid ""
-"You have been sent this email because you have enabled daily digests in Tiny "
-"Tiny RSS at "
-msgstr ""
-"Vous recevez ce courrier électronique parce que vous avez activé la synthèse "
-"quotidienne dans TIny Tiny RSS sur "
-
-#: functions.php:3324
-msgid ""
-"To unsubscribe, visit your configuration options or contact instance owner.\n"
-msgstr ""
-"Pour vous désinscrire, modifiez votre configuration ou contactez "
-"l'administrateur de votre TIny Tiny RSS.\n"
-
-#: functions.php:3555 functions.php:3602 functions.php:4650
+#: functions.php:3567 functions.php:3614 functions.php:4662
 #: modules/pref-feeds.php:655 modules/pref-feeds.php:842
 #: modules/pref-filters.php:255 modules/pref-labels.php:234
 #: modules/pref-users.php:208
 msgid "Select:"
 msgstr "Sélectionner&nbsp;:"
 
-#: functions.php:3556 functions.php:3603 modules/pref-feeds.php:656
+#: functions.php:3568 functions.php:3615 modules/pref-feeds.php:656
 #: modules/pref-feeds.php:843 modules/pref-filters.php:256
 #: modules/pref-labels.php:235 modules/pref-users.php:209
 msgid "All"
 msgstr "Tout"
 
-#: functions.php:3557 functions.php:3561 functions.php:3604 functions.php:3607
+#: functions.php:3569 functions.php:3573 functions.php:3616 functions.php:3619
 #: tt-rss.php:165
 msgid "Unread"
 msgstr "Non lus"
 
-#: functions.php:3558 functions.php:3605 modules/pref-feeds.php:657
+#: functions.php:3570 functions.php:3617 modules/pref-feeds.php:657
 #: modules/pref-feeds.php:844 modules/pref-filters.php:257
 #: modules/pref-labels.php:236 modules/pref-users.php:210
 msgid "None"
 msgstr "Aucun"
 
-#: functions.php:3560
+#: functions.php:3572
 msgid "Toggle"
 msgstr "Marquages spéciaux&nbsp;"
 
-#: functions.php:3562 functions.php:3608 tt-rss.php:164
+#: functions.php:3574 functions.php:3620 tt-rss.php:164
 msgid "Starred"
 msgstr "Remarquables"
 
-#: functions.php:3563
+#: functions.php:3575
 msgid "Published"
 msgstr "Publiés"
 
-#: functions.php:3566 localized_schema.php:15
+#: functions.php:3578 localized_schema.php:15
 msgid "Mark as read"
 msgstr "Marquer comme lu"
 
-#: functions.php:3567
+#: functions.php:3579
 msgid "Selection"
 msgstr "La sélection"
 
-#: functions.php:3568
+#: functions.php:3580
 msgid "This page"
 msgstr "Cette page"
 
-#: functions.php:3570
+#: functions.php:3582
 msgid "Above active article"
 msgstr "Au-dessus de l'article courant"
 
-#: functions.php:3571
+#: functions.php:3583
 msgid "Below active article"
 msgstr "En dessous de l'article courant"
 
-#: functions.php:3573
+#: functions.php:3585
 msgid "Entire feed"
 msgstr "Tout le flux"
 
-#: functions.php:3581
+#: functions.php:3593
 msgid "Next page"
 msgstr "Page suivante"
 
-#: functions.php:3582
+#: functions.php:3594
 msgid "Previous page"
 msgstr "Page précédente"
 
-#: functions.php:3583
+#: functions.php:3595
 msgid "First page"
 msgstr "Première page"
 
-#: functions.php:3593 functions.php:3619
+#: functions.php:3605 functions.php:3631
 msgid "Convert to label"
 msgstr "Convertir en intitulé"
 
-#: functions.php:3607
+#: functions.php:3619
 msgid "Toggle:"
 msgstr "Marquages spéciaux&nbsp;:"
 
-#: functions.php:3610
+#: functions.php:3622
 msgid "Mark as read:"
 msgstr "Marquer comme lu&nbsp;:"
 
-#: functions.php:3611
+#: functions.php:3623
 msgid "Page"
 msgstr "Page"
 
-#: functions.php:3612 modules/pref-filters.php:263
+#: functions.php:3624 modules/pref-filters.php:263
 msgid "Feed"
 msgstr "Flux"
 
-#: functions.php:3658
+#: functions.php:3670
 msgid "Generated feed"
 msgstr "Flux généré"
 
-#: functions.php:3994
+#: functions.php:4006
 msgid "No feeds to display."
 msgstr "Aucun flux à afficher."
 
-#: functions.php:4011
+#: functions.php:4023
 msgid "Tags"
 msgstr "Étiquettes"
 
-#: functions.php:4236
+#: functions.php:4248
 msgid " - by "
 msgstr "- par "
 
-#: functions.php:4285
+#: functions.php:4297
 msgid "no tags"
 msgstr "aucune étiquette"
 
-#: functions.php:4356
+#: functions.php:4368
 msgid "Feed not found."
 msgstr "Flux non trouvé."
 
-#: functions.php:4418
+#: functions.php:4430
 msgid ""
 "Could not display feed (query failed). Please check label match syntax or "
 "local configuration."
@@ -328,12 +309,12 @@ msgstr ""
 "Impossible d'afficher le flux (la requête l'a pas abouti). Veuillez vérifier "
 "la syntaxe de son intitulé ou la configuration locale."
 
-#: functions.php:4616
+#: functions.php:4628
 #, fuzzy
 msgid "Show article"
 msgstr "Marquer comme remarquable"
 
-#: functions.php:4713
+#: functions.php:4725
 msgid "No articles found."
 msgstr "Aucun article trouvé."
 
@@ -1956,5 +1937,22 @@ msgstr "Détails de l'utilisateur"
 msgid "Reset password"
 msgstr "Réinitialiser le mot de passe"
 
+#~ msgid "New headlines for last 24 hours, as of "
+#~ msgstr "Nouveaux en-têtes dans les dernières 24 heures, à compter de "
+
+#~ msgid ""
+#~ "You have been sent this email because you have enabled daily digests in "
+#~ "Tiny Tiny RSS at "
+#~ msgstr ""
+#~ "Vous recevez ce courrier électronique parce que vous avez activé la "
+#~ "synthèse quotidienne dans TIny Tiny RSS sur "
+
+#~ msgid ""
+#~ "To unsubscribe, visit your configuration options or contact instance "
+#~ "owner.\n"
+#~ msgstr ""
+#~ "Pour vous désinscrire, modifiez votre configuration ou contactez "
+#~ "l'administrateur de votre TIny Tiny RSS.\n"
+
 #~ msgid "&nbsp;&nbsp;Update"
 #~ msgstr "&nbsp;&nbsp;Mettre à jour"
index 9b26ddc428e5e7b854875344bd0529822a4c917e..75306e9f9f3c48c01abde34eb8622afe4a06a1a7 100644 (file)
Binary files a/locale/pt_BR/LC_MESSAGES/messages.mo and b/locale/pt_BR/LC_MESSAGES/messages.mo differ
index 9d6406a5d96b165c584b3b9152504ba6ec6741ea..ae71d93e3a7a40ea89d80a6bb864252cd462a306 100644 (file)
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: tt-rss 1.2.14.2\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-10-29 14:21+0300\n"
+"POT-Creation-Date: 2007-10-30 12:46+0300\n"
 "PO-Revision-Date: 2007-10-24 00:47-0200\n"
 "Last-Translator: Marcelo Jorge VIeira (metal) <metal@alucinados.com>\n"
 "Language-Team: Portuguese/Brazil\n"
@@ -140,16 +140,16 @@ msgstr ""
 "Sua versão do MySQL não é atualmente suportada. Por favor acesse \n"
 "\t\to site oficial para mais informações."
 
-#: functions.php:2286 functions.php:2625 functions.php:2985 functions.php:3760
+#: functions.php:2286 functions.php:2625 functions.php:2985 functions.php:3772
 msgid "Starred articles"
 msgstr ""
 
-#: functions.php:2295 functions.php:2627 functions.php:2987 functions.php:3767
+#: functions.php:2295 functions.php:2627 functions.php:2987 functions.php:3779
 #: modules/pref-feeds.php:1068
 msgid "Published articles"
 msgstr ""
 
-#: functions.php:2304 functions.php:2629 functions.php:2989 functions.php:3745
+#: functions.php:2304 functions.php:2629 functions.php:2989 functions.php:3757
 msgid "Fresh articles"
 msgstr ""
 
@@ -158,8 +158,8 @@ msgstr ""
 msgid "All feeds"
 msgstr "Todos os feeds"
 
-#: functions.php:2576 functions.php:2615 functions.php:2963 functions.php:3924
-#: functions.php:3954 modules/pref-feeds.php:880
+#: functions.php:2576 functions.php:2615 functions.php:2963 functions.php:3936
+#: functions.php:3966 modules/pref-feeds.php:880
 msgid "Uncategorized"
 msgstr "Não Categorizado"
 
@@ -179,149 +179,134 @@ msgstr ""
 msgid "Searched for"
 msgstr ""
 
-#: functions.php:3271
-msgid "New headlines for last 24 hours, as of "
-msgstr ""
-
-#: functions.php:3322
-msgid ""
-"You have been sent this email because you have enabled daily digests in Tiny "
-"Tiny RSS at "
-msgstr ""
-
-#: functions.php:3324
-msgid ""
-"To unsubscribe, visit your configuration options or contact instance owner.\n"
-msgstr ""
-
-#: functions.php:3555 functions.php:3602 functions.php:4650
+#: functions.php:3567 functions.php:3614 functions.php:4662
 #: modules/pref-feeds.php:655 modules/pref-feeds.php:842
 #: modules/pref-filters.php:255 modules/pref-labels.php:234
 #: modules/pref-users.php:208
 msgid "Select:"
 msgstr "Selecione:"
 
-#: functions.php:3556 functions.php:3603 modules/pref-feeds.php:656
+#: functions.php:3568 functions.php:3615 modules/pref-feeds.php:656
 #: modules/pref-feeds.php:843 modules/pref-filters.php:256
 #: modules/pref-labels.php:235 modules/pref-users.php:209
 msgid "All"
 msgstr "Todos"
 
-#: functions.php:3557 functions.php:3561 functions.php:3604 functions.php:3607
+#: functions.php:3569 functions.php:3573 functions.php:3616 functions.php:3619
 #: tt-rss.php:165
 msgid "Unread"
 msgstr "Não Lido"
 
-#: functions.php:3558 functions.php:3605 modules/pref-feeds.php:657
+#: functions.php:3570 functions.php:3617 modules/pref-feeds.php:657
 #: modules/pref-feeds.php:844 modules/pref-filters.php:257
 #: modules/pref-labels.php:236 modules/pref-users.php:210
 msgid "None"
 msgstr "Nenhum"
 
-#: functions.php:3560
+#: functions.php:3572
 msgid "Toggle"
 msgstr ""
 
-#: functions.php:3562 functions.php:3608 tt-rss.php:164
+#: functions.php:3574 functions.php:3620 tt-rss.php:164
 msgid "Starred"
 msgstr "Favoritos"
 
-#: functions.php:3563
+#: functions.php:3575
 msgid "Published"
 msgstr "Publicado"
 
-#: functions.php:3566 localized_schema.php:15
+#: functions.php:3578 localized_schema.php:15
 msgid "Mark as read"
 msgstr "Marcar como lido"
 
-#: functions.php:3567
+#: functions.php:3579
 msgid "Selection"
 msgstr "Seleção"
 
-#: functions.php:3568
+#: functions.php:3580
 msgid "This page"
 msgstr ""
 
-#: functions.php:3570
+#: functions.php:3582
 msgid "Above active article"
 msgstr ""
 
-#: functions.php:3571
+#: functions.php:3583
 msgid "Below active article"
 msgstr ""
 
-#: functions.php:3573
+#: functions.php:3585
 msgid "Entire feed"
 msgstr ""
 
-#: functions.php:3581
+#: functions.php:3593
 msgid "Next page"
 msgstr "Próxima página"
 
-#: functions.php:3582
+#: functions.php:3594
 msgid "Previous page"
 msgstr "Página anterior"
 
-#: functions.php:3583
+#: functions.php:3595
 msgid "First page"
 msgstr "Primeira página"
 
-#: functions.php:3593 functions.php:3619
+#: functions.php:3605 functions.php:3631
 msgid "Convert to label"
 msgstr ""
 
-#: functions.php:3607
+#: functions.php:3619
 msgid "Toggle:"
 msgstr ""
 
-#: functions.php:3610
+#: functions.php:3622
 msgid "Mark as read:"
 msgstr "Marcar como lido:"
 
-#: functions.php:3611
+#: functions.php:3623
 msgid "Page"
 msgstr "Página"
 
-#: functions.php:3612 modules/pref-filters.php:263
+#: functions.php:3624 modules/pref-filters.php:263
 msgid "Feed"
 msgstr "Feed"
 
-#: functions.php:3658
+#: functions.php:3670
 msgid "Generated feed"
 msgstr ""
 
-#: functions.php:3994
+#: functions.php:4006
 msgid "No feeds to display."
 msgstr "Sem Feeds para exibir."
 
-#: functions.php:4011
+#: functions.php:4023
 msgid "Tags"
 msgstr "Tags"
 
-#: functions.php:4236
+#: functions.php:4248
 msgid " - by "
 msgstr " - por "
 
-#: functions.php:4285
+#: functions.php:4297
 msgid "no tags"
 msgstr "sem tags"
 
-#: functions.php:4356
+#: functions.php:4368
 msgid "Feed not found."
 msgstr "Feed não encontrado."
 
-#: functions.php:4418
+#: functions.php:4430
 msgid ""
 "Could not display feed (query failed). Please check label match syntax or "
 "local configuration."
 msgstr ""
 
-#: functions.php:4616
+#: functions.php:4628
 #, fuzzy
 msgid "Show article"
 msgstr "Favoritos"
 
-#: functions.php:4713
+#: functions.php:4725
 msgid "No articles found."
 msgstr ""
 
index 28efb9c4d65f8567dab9466206335d4f971f95e4..5aab32d31c51114a4ecb9ea04f2e7bf904d9a388 100644 (file)
Binary files a/locale/ru_RU/LC_MESSAGES/messages.mo and b/locale/ru_RU/LC_MESSAGES/messages.mo differ
index 4b5e1eb83df37078d7454f40995daa5851bf1279..b840ac48c1d9ceca0c79f62f7b4d8333e32f8ac4 100644 (file)
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: 1.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-10-29 14:21+0300\n"
+"POT-Creation-Date: 2007-10-30 12:46+0300\n"
 "PO-Revision-Date: 2007-08-18 15:14+0400\n"
 "Last-Translator: Andrew Dolgov <cthulhoo@gmail.com>\n"
 "Language-Team: Русский <ru@li.org>\n"
@@ -140,16 +140,16 @@ msgid ""
 "\t\tofficial site for more information."
 msgstr ""
 
-#: functions.php:2286 functions.php:2625 functions.php:2985 functions.php:3760
+#: functions.php:2286 functions.php:2625 functions.php:2985 functions.php:3772
 msgid "Starred articles"
 msgstr "Отмеченные"
 
-#: functions.php:2295 functions.php:2627 functions.php:2987 functions.php:3767
+#: functions.php:2295 functions.php:2627 functions.php:2987 functions.php:3779
 #: modules/pref-feeds.php:1068
 msgid "Published articles"
 msgstr "Опубликованные"
 
-#: functions.php:2304 functions.php:2629 functions.php:2989 functions.php:3745
+#: functions.php:2304 functions.php:2629 functions.php:2989 functions.php:3757
 #, fuzzy
 msgid "Fresh articles"
 msgstr "Отмеченные"
@@ -159,8 +159,8 @@ msgstr "Отмеченные"
 msgid "All feeds"
 msgstr "Все каналы"
 
-#: functions.php:2576 functions.php:2615 functions.php:2963 functions.php:3924
-#: functions.php:3954 modules/pref-feeds.php:880
+#: functions.php:2576 functions.php:2615 functions.php:2963 functions.php:3936
+#: functions.php:3966 modules/pref-feeds.php:880
 msgid "Uncategorized"
 msgstr "Нет категории"
 
@@ -180,151 +180,136 @@ msgstr "Результаты поиска"
 msgid "Searched for"
 msgstr "Поиск"
 
-#: functions.php:3271
-msgid "New headlines for last 24 hours, as of "
-msgstr "Новые заголовки за последние 24 часа, на "
-
-#: functions.php:3322
-msgid ""
-"You have been sent this email because you have enabled daily digests in Tiny "
-"Tiny RSS at "
-msgstr ""
-
-#: functions.php:3324
-msgid ""
-"To unsubscribe, visit your configuration options or contact instance owner.\n"
-msgstr ""
-
-#: functions.php:3555 functions.php:3602 functions.php:4650
+#: functions.php:3567 functions.php:3614 functions.php:4662
 #: modules/pref-feeds.php:655 modules/pref-feeds.php:842
 #: modules/pref-filters.php:255 modules/pref-labels.php:234
 #: modules/pref-users.php:208
 msgid "Select:"
 msgstr "Выбрать:"
 
-#: functions.php:3556 functions.php:3603 modules/pref-feeds.php:656
+#: functions.php:3568 functions.php:3615 modules/pref-feeds.php:656
 #: modules/pref-feeds.php:843 modules/pref-filters.php:256
 #: modules/pref-labels.php:235 modules/pref-users.php:209
 msgid "All"
 msgstr "Все"
 
-#: functions.php:3557 functions.php:3561 functions.php:3604 functions.php:3607
+#: functions.php:3569 functions.php:3573 functions.php:3616 functions.php:3619
 #: tt-rss.php:165
 msgid "Unread"
 msgstr "Новые"
 
-#: functions.php:3558 functions.php:3605 modules/pref-feeds.php:657
+#: functions.php:3570 functions.php:3617 modules/pref-feeds.php:657
 #: modules/pref-feeds.php:844 modules/pref-filters.php:257
 #: modules/pref-labels.php:236 modules/pref-users.php:210
 msgid "None"
 msgstr "Ничего"
 
-#: functions.php:3560
+#: functions.php:3572
 msgid "Toggle"
 msgstr "Изменить:"
 
-#: functions.php:3562 functions.php:3608 tt-rss.php:164
+#: functions.php:3574 functions.php:3620 tt-rss.php:164
 msgid "Starred"
 msgstr "Отмеченные"
 
-#: functions.php:3563
+#: functions.php:3575
 msgid "Published"
 msgstr "Опубликован"
 
-#: functions.php:3566 localized_schema.php:15
+#: functions.php:3578 localized_schema.php:15
 msgid "Mark as read"
 msgstr "Как прочитанные"
 
-#: functions.php:3567
+#: functions.php:3579
 #, fuzzy
 msgid "Selection"
 msgstr "Выбрать:"
 
-#: functions.php:3568
+#: functions.php:3580
 msgid "This page"
 msgstr "Эту страницу"
 
-#: functions.php:3570
+#: functions.php:3582
 msgid "Above active article"
 msgstr ""
 
-#: functions.php:3571
+#: functions.php:3583
 #, fuzzy
 msgid "Below active article"
 msgstr "Отфильтровать статью"
 
-#: functions.php:3573
+#: functions.php:3585
 msgid "Entire feed"
 msgstr "Весь канал"
 
-#: functions.php:3581
+#: functions.php:3593
 msgid "Next page"
 msgstr "След. стр."
 
-#: functions.php:3582
+#: functions.php:3594
 msgid "Previous page"
 msgstr "Пред. cтр."
 
-#: functions.php:3583
+#: functions.php:3595
 msgid "First page"
 msgstr "На первую"
 
-#: functions.php:3593 functions.php:3619
+#: functions.php:3605 functions.php:3631
 msgid "Convert to label"
 msgstr "Превратить в метку"
 
-#: functions.php:3607
+#: functions.php:3619
 msgid "Toggle:"
 msgstr "Изменить:"
 
-#: functions.php:3610
+#: functions.php:3622
 msgid "Mark as read:"
 msgstr "Пометить как прочит.:"
 
-#: functions.php:3611
+#: functions.php:3623
 msgid "Page"
 msgstr "Страница"
 
-#: functions.php:3612 modules/pref-filters.php:263
+#: functions.php:3624 modules/pref-filters.php:263
 msgid "Feed"
 msgstr "Канал"
 
-#: functions.php:3658
+#: functions.php:3670
 msgid "Generated feed"
 msgstr ""
 
-#: functions.php:3994
+#: functions.php:4006
 msgid "No feeds to display."
 msgstr "Нет каналов для отображения."
 
-#: functions.php:4011
+#: functions.php:4023
 msgid "Tags"
 msgstr "Теги"
 
-#: functions.php:4236
+#: functions.php:4248
 msgid " - by "
 msgstr ", автор - "
 
-#: functions.php:4285
+#: functions.php:4297
 msgid "no tags"
 msgstr "нет тегов"
 
-#: functions.php:4356
+#: functions.php:4368
 msgid "Feed not found."
 msgstr "Канал не найден."
 
-#: functions.php:4418
+#: functions.php:4430
 msgid ""
 "Could not display feed (query failed). Please check label match syntax or "
 "local configuration."
 msgstr ""
 
-#: functions.php:4616
+#: functions.php:4628
 #, fuzzy
 msgid "Show article"
 msgstr "Отмеченные"
 
-#: functions.php:4713
+#: functions.php:4725
 msgid "No articles found."
 msgstr "Статей не найдено."
 
@@ -1871,6 +1856,9 @@ msgstr "Подробнее..."
 msgid "Reset password"
 msgstr "Сбросить пароль"
 
+#~ msgid "New headlines for last 24 hours, as of "
+#~ msgstr "Новые заголовки за последние 24 часа, на "
+
 #~ msgid "&nbsp;&nbsp;Update"
 #~ msgstr "&nbsp;&nbsp;Обновить"
 
index fd9d4f181a0c4634c937b4c6f5702c493fcbe357..73dee5e96af1024dcc0a3411b67f5816ce86f60a 100644 (file)
Binary files a/locale/zh_CN/LC_MESSAGES/messages.mo and b/locale/zh_CN/LC_MESSAGES/messages.mo differ
index 5a83e8897c00292d129c9cef97b639b2d4a18ee6..26b592689708380f9876c3dc509ba4587ea87f8e 100644 (file)
@@ -2,7 +2,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Tiny Tiny RSS1.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-10-29 14:21+0300\n"
+"POT-Creation-Date: 2007-10-30 12:46+0300\n"
 "PO-Revision-Date: 2007-08-19 19:03+0800\n"
 "Last-Translator: sluke <sluke520@yahoo.com.cn>\n"
 "Language-Team: hicode.org <sluke520@yahoo.com.cn>\n"
@@ -136,16 +136,16 @@ msgstr ""
 "不支持你的MySQL版本. 请访问 \n"
 "\t\t官方网站获取更多信息。"
 
-#: functions.php:2286 functions.php:2625 functions.php:2985 functions.php:3760
+#: functions.php:2286 functions.php:2625 functions.php:2985 functions.php:3772
 msgid "Starred articles"
 msgstr "星级文章"
 
-#: functions.php:2295 functions.php:2627 functions.php:2987 functions.php:3767
+#: functions.php:2295 functions.php:2627 functions.php:2987 functions.php:3779
 #: modules/pref-feeds.php:1068
 msgid "Published articles"
 msgstr "已发布文章"
 
-#: functions.php:2304 functions.php:2629 functions.php:2989 functions.php:3745
+#: functions.php:2304 functions.php:2629 functions.php:2989 functions.php:3757
 #, fuzzy
 msgid "Fresh articles"
 msgstr "星级文章"
@@ -155,8 +155,8 @@ msgstr "星级文章"
 msgid "All feeds"
 msgstr "所有feed"
 
-#: functions.php:2576 functions.php:2615 functions.php:2963 functions.php:3924
-#: functions.php:3954 modules/pref-feeds.php:880
+#: functions.php:2576 functions.php:2615 functions.php:2963 functions.php:3936
+#: functions.php:3966 modules/pref-feeds.php:880
 msgid "Uncategorized"
 msgstr "未分类"
 
@@ -176,150 +176,135 @@ msgstr "搜索结果"
 msgid "Searched for"
 msgstr "搜索"
 
-#: functions.php:3271
-msgid "New headlines for last 24 hours, as of "
-msgstr "24小时最新提要,截至"
-
-#: functions.php:3322
-msgid ""
-"You have been sent this email because you have enabled daily digests in Tiny "
-"Tiny RSS at "
-msgstr "由于您启用了Tiny Tiny RSS每日文摘,会收到此邮件。"
-
-#: functions.php:3324
-msgid ""
-"To unsubscribe, visit your configuration options or contact instance owner.\n"
-msgstr "若要退订,访问你的配置选项或联络管理员。\n"
-
-#: functions.php:3555 functions.php:3602 functions.php:4650
+#: functions.php:3567 functions.php:3614 functions.php:4662
 #: modules/pref-feeds.php:655 modules/pref-feeds.php:842
 #: modules/pref-filters.php:255 modules/pref-labels.php:234
 #: modules/pref-users.php:208
 msgid "Select:"
 msgstr "选择:"
 
-#: functions.php:3556 functions.php:3603 modules/pref-feeds.php:656
+#: functions.php:3568 functions.php:3615 modules/pref-feeds.php:656
 #: modules/pref-feeds.php:843 modules/pref-filters.php:256
 #: modules/pref-labels.php:235 modules/pref-users.php:209
 msgid "All"
 msgstr "所有"
 
-#: functions.php:3557 functions.php:3561 functions.php:3604 functions.php:3607
+#: functions.php:3569 functions.php:3573 functions.php:3616 functions.php:3619
 #: tt-rss.php:165
 msgid "Unread"
 msgstr "未读"
 
-#: functions.php:3558 functions.php:3605 modules/pref-feeds.php:657
+#: functions.php:3570 functions.php:3617 modules/pref-feeds.php:657
 #: modules/pref-feeds.php:844 modules/pref-filters.php:257
 #: modules/pref-labels.php:236 modules/pref-users.php:210
 msgid "None"
 msgstr "无"
 
-#: functions.php:3560
+#: functions.php:3572
 msgid "Toggle"
 msgstr "触发开关"
 
-#: functions.php:3562 functions.php:3608 tt-rss.php:164
+#: functions.php:3574 functions.php:3620 tt-rss.php:164
 msgid "Starred"
 msgstr "星级"
 
-#: functions.php:3563
+#: functions.php:3575
 msgid "Published"
 msgstr "已发布"
 
-#: functions.php:3566 localized_schema.php:15
+#: functions.php:3578 localized_schema.php:15
 msgid "Mark as read"
 msgstr "标记为已读"
 
-#: functions.php:3567
+#: functions.php:3579
 msgid "Selection"
 msgstr "选择:"
 
-#: functions.php:3568
+#: functions.php:3580
 msgid "This page"
 msgstr "本页"
 
-#: functions.php:3570
+#: functions.php:3582
 msgid "Above active article"
 msgstr ""
 
-#: functions.php:3571
+#: functions.php:3583
 #, fuzzy
 msgid "Below active article"
 msgstr "过滤文章"
 
-#: functions.php:3573
+#: functions.php:3585
 msgid "Entire feed"
 msgstr "输入feed"
 
-#: functions.php:3581
+#: functions.php:3593
 msgid "Next page"
 msgstr "下页"
 
-#: functions.php:3582
+#: functions.php:3594
 msgid "Previous page"
 msgstr "上页"
 
-#: functions.php:3583
+#: functions.php:3595
 msgid "First page"
 msgstr "首页"
 
-#: functions.php:3593 functions.php:3619
+#: functions.php:3605 functions.php:3631
 msgid "Convert to label"
 msgstr "转换标签"
 
-#: functions.php:3607
+#: functions.php:3619
 msgid "Toggle:"
 msgstr "触发:"
 
-#: functions.php:3610
+#: functions.php:3622
 msgid "Mark as read:"
 msgstr "标记为已读:"
 
-#: functions.php:3611
+#: functions.php:3623
 msgid "Page"
 msgstr "页"
 
-#: functions.php:3612 modules/pref-filters.php:263
+#: functions.php:3624 modules/pref-filters.php:263
 msgid "Feed"
 msgstr "Feed"
 
-#: functions.php:3658
+#: functions.php:3670
 msgid "Generated feed"
 msgstr "产生feed"
 
-#: functions.php:3994
+#: functions.php:4006
 msgid "No feeds to display."
 msgstr "无feed显示。"
 
-#: functions.php:4011
+#: functions.php:4023
 msgid "Tags"
 msgstr "标签"
 
-#: functions.php:4236
+#: functions.php:4248
 msgid " - by "
 msgstr ", 由 - "
 
-#: functions.php:4285
+#: functions.php:4297
 msgid "no tags"
 msgstr "无标签"
 
-#: functions.php:4356
+#: functions.php:4368
 msgid "Feed not found."
 msgstr "未找到Feed."
 
-#: functions.php:4418
+#: functions.php:4430
 msgid ""
 "Could not display feed (query failed). Please check label match syntax or "
 "local configuration."
 msgstr "无法显示feed(查询失败); 请核对标签匹配语法或本地配置."
 
-#: functions.php:4616
+#: functions.php:4628
 #, fuzzy
 msgid "Show article"
 msgstr "星级文章"
 
-#: functions.php:4713
+#: functions.php:4725
 msgid "No articles found."
 msgstr "未找到文章。"
 
@@ -1887,5 +1872,18 @@ msgstr "用户详细"
 msgid "Reset password"
 msgstr "重置密码"
 
+#~ msgid "New headlines for last 24 hours, as of "
+#~ msgstr "24小时最新提要,截至"
+
+#~ msgid ""
+#~ "You have been sent this email because you have enabled daily digests in "
+#~ "Tiny Tiny RSS at "
+#~ msgstr "由于您启用了Tiny Tiny RSS每日文摘,会收到此邮件。"
+
+#~ msgid ""
+#~ "To unsubscribe, visit your configuration options or contact instance "
+#~ "owner.\n"
+#~ msgstr "若要退订,访问你的配置选项或联络管理员。\n"
+
 #~ msgid "&nbsp;&nbsp;Update"
 #~ msgstr "&nbsp;&nbsp;更新"
diff --git a/templates/digest_template.txt b/templates/digest_template.txt
new file mode 100644 (file)
index 0000000..aa56fb3
--- /dev/null
@@ -0,0 +1,14 @@
+<!-- $BeginBlock digest -->
+New headlines for last 24 hours, as of ${CUR_DATE} ${CUR_TIME}
+==============================================================
+<!-- $BeginBlock feed -->
+${FEED_TITLE}
+
+<!-- $BeginBlock article -->
+* ${ARTICLE_TITLE} - ${ARTICLE_UPDATED}
+  ${ARTICLE_LINK}
+<!-- $EndBlock article -->
+<!-- $EndBlock feed -->
+-- 
+To unsubscribe, visit your configuration options or contact instance owner.
+<!-- $EndBlock digest -->
diff --git a/templates/digest_template_html.txt b/templates/digest_template_html.txt
new file mode 100644 (file)
index 0000000..4b85f8b
--- /dev/null
@@ -0,0 +1,14 @@
+<!-- $BeginBlock digest -->
+<h1>New headlines for last 24 hours, as of ${CUR_DATE} ${CUR_TIME}</h1>
+<!-- $BeginBlock feed -->
+<h2>${FEED_TITLE}</h2>
+
+<ul>
+<!-- $BeginBlock article -->
+<li><a href="${ARTICLE_LINK}">${ARTICLE_TITLE}</a> - ${ARTICLE_UPDATED}
+<!-- $EndBlock article -->
+</ul>
+<!-- $EndBlock feed -->
+<p><em>To unsubscribe, visit your configuration options or contact instance owner.</em></p>
+<!-- $EndBlock digest -->