Example #1
0
        /// Execute main logic for DoRedirectItem action
        public override void Execute()
        {
            var errorMessage   = (String)null;
            var linkToRedirect = (String)null;

            if (!this.context.Request.Contains("id"))
            {
                errorMessage = "Item ID is required!";
            }
            else
            {
                var id = this.context.Request["id"];
                if (!TRequest.IsInteger(id) || INT(id) <= 0)
                {
                    errorMessage = "Incorrect item ID!";
                }
                else
                {
                    var doItem  = new DOItem(this.context.Connection);
                    var dsItems = doItem.GetById(INT(id));
                    if (dsItems.GetSize() == 0)
                    {
                        errorMessage = "No item with such ID!";
                    }
                    else
                    {
                        var oItem = dsItems.GetRow(0);
                        linkToRedirect = STR(oItem["s_Link"]);
                    }
                }
            }
            this.ExecuteRedirect(linkToRedirect, errorMessage);
        }
Example #2
0
        static public DOItem MapTo(this Item data, bool includeScopes = true)
        {
            DOItem result = new DOItem
            {
                Color = data.Color,
                Type  = data.Type,
                Row   = data.Row,
                Col   = data.Col,
                Alive = data.IsAlive,
            };

            if (includeScopes)
            {
                result.Scope = new List <DOPosition>();
                data.Scopes.ForEach(p => result.Scope.Add(new DOPosition {
                    Row = p.Row, Col = p.Col
                }));
            }
            return(result);
        }
        /// <summary>
        /// Execute re-counting of categories.
        /// </summary>
        private void RecountCategories()
        {
            this.oLogger.Output(CAT("<br/>", EOL, "Recount categories ... "));
            var doCategory   = new DOCategory(this.context.Connection);
            var doItem       = new DOItem(this.context.Connection);
            var dsCategories = doCategory.EnumCategories();

            for (int n = 0; n < dsCategories.GetSize(); n++)
            {
                var oCategory  = dsCategories.GetRow(n);
                var categoryId = STR(oCategory["s_CatId"]);
                var oldCounter = INT(oCategory["i_Counter"]);

                //String filter = STR(oCategory["s_Filter"]);
                //String sqlFilter = DOItem.BuildSqlByFilter(filter);

                var categoryName = STR(oCategory["s_Name"]);
                var sqlFilter    = DOItem.BuildSqlByCategory(categoryName);

                var dsCounters = doItem.EnumIds(CAT("_this.b_Counted = 0 AND ", sqlFilter));
                if (dsCounters.GetSize() == 0)
                {
                    continue;
                }

                var newCounter = INT(dsCounters.GetSize());

                //Update category
                var categoryFields = new THashtable();
                categoryFields["i_Counter"] = oldCounter + newCounter;
                doCategory.UpdateById(categoryId, categoryFields);
            }

            doItem.Update("_this.b_Counted = 1", "_this.b_Counted = 0");

            this.oLogger.Output(CAT(" ... Done<br/>", EOL));
        }
Example #4
0
        /// Execute main logic for Home block.
        public override void Execute()
        {
            var pars = this.Check();

            if (pars == null)
            {
                return;
            }

            var prepare = new THashtable();

            var doItem = new DOItem(this.context.Connection);

            prepare["[#BrowseItemsLink]"] = this.GetLink(Config.INDEX_PAGE, "?p=", null, "items");
            if (Config.SHOW_IMAGES)
            {
                prepare["[#Show_Images]"] = 1;
            }

            var source   = (String)null;
            var search   = (String)null;
            var maxRows  = Config.DB_HOME_ROWS;
            var dsItems  = doItem.EnumItems(source, search, 1, maxRows);
            var rowCount = 1;
            var items    = new TArrayList();

            for (int n = 0; n < dsItems.GetSize(); n++)
            {
                var oItem = dsItems.GetRow(n);
                var row   = FillItemRow(oItem, doItem.GetIdField(), rowCount);
                items.Add(row);
                rowCount++;
            }
            prepare["[#Items]"] = items;

            this.Write("Pages/home", prepare);
        }
        /// <summary>
        /// Parse data from the item.
        /// </summary>
        /// <param name="oSource">Source object.</param>
        /// <param name="item">Item object.</param>
        /// <returns>Result of executing SQL-query.</returns>
        private int ParseItemData(THashtable oSource, THashtable item)
        {
            // Load original values

            var sourceName = STR(oSource["s_SourceName"]);
            var sourceId   = INT(oSource["i_SourceId"]);
            var boItem     = new BOItem(sourceName, item);
            var pubDate    = STR(item["pubDate"]);

            if (BLANK(pubDate) && !BLANK(item["dc"]))   //TODO implement [dc][time]
            {
                var temp = (THashtable)item["dc"];
                if (!BLANK(temp["date"]))
                {
                    pubDate         = STR(temp["date"]);
                    item["pubDate"] = pubDate;
                }
            }

            boItem.ProcessMappings(this.dsMappings);

            boItem.ProcessDescription();
            //boItem.ProcessCustomFields(); // Uncomment for processing custom fields
            boItem.ProcessCategory();
            boItem.ProcessCreator();

            // Process rules AFTER processing description (as some info can be extracted from it)
            boItem.ProcessRules(this.dsRules);

            if (BLANK(boItem.link)) //TODO - what we can do else?
            {
                return(0);
            }

            // Get date here as it can be extracted in rules processing
            if (boItem.date != null)
            {
                pubDate = boItem.date;
            }
            if (!BLANK(pubDate))
            {
                pubDate = pubDate.Trim();
            }
            var date = DateTimes.GmtFormat(DateTimes.SQL_DTS, DateTimes.FromRss(pubDate));

            // Check whether item with the same link exists already
            var doItem  = new DOItem(this.context.Connection);
            var dsItems = doItem.FindItemByLink(boItem.link, sourceId);

            if (dsItems.GetSize() > 0)
            {
                return(0);
            }

            // Try to add/embed standard categories from description
            var countCategories = boItem.AddStandardCategories(this.dsCategories, this.context.Lang);

            boItem.NormalizeCategories();

            // Check the link once again after processing rules
            if (dsItems == null && !BLANK(boItem.link))
            {
                doItem.FindItemByLink(boItem.link, sourceId);
                if (dsItems.GetSize() > 0)
                {
                    return(0);
                }
            }

            var url    = boItem.GetUrlTitle(true); //TODO -- Need to pass true if transliteration is required
            var fields = new THashtable();

            fields["s_Link"]       = boItem.link;
            fields["s_Title"]      = boItem.title;
            fields["s_FullTitle"]  = boItem.fullTitle;
            fields["s_Url"]        = url;
            fields["i_Categories"] = countCategories;
            if (boItem.description != null)
            {
                fields["t_Description"] = boItem.description;
            }
            if (boItem.fullDescription != null)
            {
                fields["t_FullDescription"] = boItem.fullDescription;
            }
            fields["d_Date"]       = date;
            fields["i_SourceLink"] = INT(oSource["i_SourceId"]);
            if (!BLANK(boItem.category))
            {
                fields["s_Category"] = boItem.category;
            }
            if (!BLANK(boItem.creator))
            {
                fields["s_Creator"] = boItem.creator;
            }
            if (!BLANK(boItem.custom1))
            {
                fields["s_Custom1"] = boItem.custom1;
            }
            if (!BLANK(boItem.custom2))
            {
                fields["s_Custom2"] = boItem.custom2;
            }

            var result = doItem.Insert(fields);

            return(result);
        }
Example #6
0
        /// <summary>
        /// Execute main logic for generating RSS-feeds.
        /// </summary>
        public override void Execute()
        {
            //this.context.Request.Initialize();
            this.context.Request.ExtractAllVars();

            var errorMessage = "";

            // Check source
            var source = this.context.Request["source"];

            if (!NUL(source))
            {
                if (BLANK(source))
                {
                    errorMessage += "Empty source!";
                }
                else
                {
                    var          doSource = new DOSource(this.context.Connection);
                    THashtable[] oSource  =
                    { new THashtable() };
                    if (!doSource.CheckSourceName(source, oSource))
                    {
                        errorMessage += CAT("Incorrect source '", source, "'!");
                    }
                }
            }

            var anyFilter = false;

            if (this.context.Request.Contains("code"))
            {
                if (EQ(this.context.Request["code"], Config.SECURITY_CODE))
                {
                    anyFilter = true;
                }
            }

            // Check filter
            var filter       = (String)null;
            var filterName   = (String)null;
            var categoryName = (String)null;
            var doCategory   = new DOCategory(this.context.Connection);
            var dsCategories = doCategory.EnumCategories();

            if (dsCategories.GetSize() > 0)
            {
                filterName = this.context.Request["filter"];
                if (!NUL(filterName))
                {
                    if (BLANK(filterName))
                    {
                        if (errorMessage.Length > 0)
                        {
                            errorMessage += " ";
                        }
                        errorMessage += "Empty filter!";
                    }
                    else
                    {
                        THashtable[] oCategory =
                        { new THashtable() };
                        if (doCategory.CheckFilterName(filterName, oCategory))
                        {
                            categoryName = STR(oCategory[0]["s_Name"]);
                            filter       = STR(oCategory[0]["s_Filter"]);
                        }
                        else
                        {
                            if (anyFilter)
                            {
                                filter = filterName;
                            }
                            else
                            {
                                if (errorMessage.Length > 0)
                                {
                                    errorMessage += " ";
                                }
                                errorMessage += CAT("Incorrect filter '", filterName, "'!");
                            }
                        }
                    }
                }
            }

            // Check that parameters contain only 'source' or/and 'filter'
            var keys = this.context.Request.GetKeys();

            while (keys.MoveNext())
            {
                var key = (String)keys.GetCurrent();
                if (EQ(key, "source") || EQ(key, "filter") || EQ(key, "code") || EQ(key, "count"))
                {
                    //OK
                }
                else
                {
                    //Not OK
                    if (errorMessage.Length > 0)
                    {
                        errorMessage += " ";
                    }
                    errorMessage += CAT("Incorrect parameter '", key, "'!");
                }
            }

            if (errorMessage.Length > 0)
            {
                this.WriteErrorMessage(errorMessage);
                return;
            }

            var fullTitle = false;

            if (this.context.Request.Contains("title") && STR(this.context.Request["title"]) == "full")
            {
                fullTitle = true;
            }

            var count    = Config.MAX_RSS_ITEMS;
            var countSet = false;

            if (this.context.Request.Contains("count"))
            {
                if (INT(this.context.Request["count"]) > 0)
                {
                    count = INT(this.context.Request["count"]);
                    if (count < Config.MIN_RSS_ITEMS)
                    {
                        count = Config.MIN_RSS_ITEMS;
                    }
                    if (count > Config.MAX_RSS_ITEMS)
                    {
                        count = Config.MAX_RSS_ITEMS;
                    }
                    countSet = true;
                }
            }

            // Get content from cache (if enabled and cache data exists)
            var cachedFile = "";

            if (Config.CACHE_RSS && !countSet)
            {
                cachedFile = Strings.Concat(
                    this.context.RssFolder, "/rss",
                    (BLANK(source) ? null : CAT("-s=", source)),
                    (BLANK(filterName) ? null : CAT("-f=", filterName)),
                    (fullTitle ? "-full" : null), ".xml");
                if (Helper.FileExists(cachedFile))
                {
                    this.context.Response.WriteHeader("Content-type", "text/xml; charset=UTF-8");
                    var tempContent = Helper.ReadAllText(cachedFile);
                    //this.context.Response.Write(tempContent.Substring(3)); //TODO -- BOM?
                    this.context.Response.Write(tempContent); //TODO -- BOM?
                    return;
                }
            }

            var doItem = new DOItem(this.context.Connection);

            // 0 - item url
            // 1 - item title
            // 2 - marketplace url
            // 3 - marketplace name
            // 4 - date
            // 5 - description
            // 6 - category

            var pubDate  = DateTimes.Format(DateTimes.XML_DTS);
            var nowDate  = DateTimes.Format(DateTimes.SQL_DTS);
            var nowTime  = DateTimes.GetTime(nowDate);
            var fromDate = DateTimes.GmtFormat(DateTimes.SQL_DTS, nowTime - 6 * 60 * 60);
            //String search = DOItem.BuildSqlByFilter(filter);
            var search  = DOItem.BuildSqlByCategory(categoryName);
            var dsItems = doItem.EnumItemsFromSource(fromDate, source, search, count);
            var current = 0;

            var contentToCache = "";

            if (dsItems.GetSize() == 0)
            {
                contentToCache = this.WriteStart(source, categoryName, pubDate);
            }

            for (int n = 0; n < dsItems.GetSize(); n++)
            {
                var oItem = dsItems.GetRow(n);
                var date  = STR(oItem["d_Date"]);
                if (DateTimes.GetTime(date) > nowTime)
                {
                    continue;
                }

                if (current == 0)
                {
                    // Get puDate from the first item and write starting block
                    pubDate        = DateTimes.Format(DateTimes.XML_DTS, DateTimes.GetTime(date));
                    contentToCache = this.WriteStart(source, categoryName, pubDate);
                }

                var    category = this.context.Contains("Name_Category") ? STR(oItem["s_Category"]) : null;
                var    creator  = this.context.Contains("Name_Creator") ? STR(oItem["s_Creator"]) : null;
                String custom1  = this.context.Contains("Name_Custom1") ? STR(oItem["s_Custom1"]) : null;
                String custom2  = this.context.Contains("Name_Custom2") ? STR(oItem["s_Custom2"]) : null;

                var sourceName  = STR(oItem["s_SourceName"]);
                var description = STR(oItem["t_Description"]);
                if (!BLANK(description))
                {
                    description = Regex.Replace(description, "<br/>", " ", RegexOptions.IgnoreCase);
                    description = Regex.Replace(description, "&nbsp;", " ");
                    description = Regex.Replace(description, "[ \r\n\t]+", " ");
                    if (description.Length > 512)
                    {
                        description = description.Substring(0, 511);
                        var lastSpaceIndex = description.LastIndexOf(" ");
                        description = Strings.Concat(description.Substring(0, lastSpaceIndex), " ...");
                    }
                    //Boolean utfIsValid = Mb_check_encoding(description, "UTF-8");
                    //if (utfIsValid == false)
                    //    description = ""; //TODO
                }
                var itemTitle = CAT(
                    (fullTitle == true && !BLANK(custom2) ? CAT(custom2, " | ") : null),
                    Strings.RemoveTags(Strings.StripSlashes(STR(oItem["s_Title"]))),
                    (fullTitle == true ? CAT(" [", sourceName, "]") : null)
                    );

                var link = (String)null;
                if (this.context.ImmediateRedirect)
                {
                    link = STR(oItem["s_Link"]);
                }
                else
                {
                    var url     = STR(oItem["s_Url"]);
                    var idField = doItem.GetIdField();
                    link = this.GetAbsoluteLink(Config.INDEX_PAGE, "?p=view_item&amp;id=", "item/", oItem[idField]);
                    if (!BLANK(url))
                    {
                        link = this.AppendLink(link, "&amp;title=", "/", url);
                    }
                }

                Object[] args = ARR(7);
                args[0] = link;
                args[1] = itemTitle;
                args[2] = this.GetAbsoluteLink(Config.ACTION_PAGE, "?p=do_redirect_source&amp;source=", "redirect/source/", sourceName);
                args[3] = sourceName;
                args[4] = DateTimes.Format(DateTimes.XML_DTS, DateTimes.GetTime(date));
                var additional = (String)null;
                if (!BLANK(creator))
                {
                    if (additional != null)
                    {
                        additional = CAT(additional, "<br/>");
                    }
                    additional = CAT(additional, this.context["Name_Creator"], ": ", creator);
                }
                if (!BLANK(category))
                {
                    if (additional != null)
                    {
                        additional = CAT(additional, "<br/>");
                    }
                    additional = CAT(additional, this.context["Name_Categories"], ": ", category);
                }
                if (!BLANK(custom2))
                {
                    if (additional != null)
                    {
                        additional = CAT(additional, "<br/>");
                    }
                    additional = CAT(additional, this.context["Name_Custom2"], ": ", custom2);
                }
                if (!BLANK(custom1))
                {
                    if (additional != null)
                    {
                        additional = CAT(additional, "<br/>");
                    }
                    additional = CAT(additional, this.context["Name_Custom1"], ": ", custom1);
                }

                var extendedDescription = (String)null;
                if (!BLANK(description))
                {
                    if (BLANK(additional))
                    {
                        extendedDescription = description;
                    }
                    else
                    {
                        extendedDescription = CAT(description, "<br/><br/>", additional);
                    }
                }
                else if (!BLANK(additional))
                {
                    extendedDescription = additional;
                }
                args[5] = extendedDescription;
                args[6] = category;

                var itemContent = this.WriteItem(args);
                if (!BLANK(itemContent))
                {
                    contentToCache += itemContent;
                }

                current++;
            }

            var endContent = this.WriteEnd();

            if (!BLANK(endContent))
            {
                contentToCache += endContent;
            }

            // Save content to cache (if applicable)
            if (Config.CACHE_RSS && !countSet)
            {
                Helper.TestFileFolder(cachedFile);
                //Helper.WriteText(cachedFile, Strings.Concat("\xEF\xBB\xBF", xmlContent));
                Helper.WriteText(cachedFile, contentToCache);
            }
            this.context.Response.WriteHeader("Content-type", "text/xml; charset=UTF-8");
            this.context.Response.Write(contentToCache); //TODO -- BOM?
        }
Example #7
0
        /// Execute main logic for View Item block.
        public override void Execute()
        {
            var pars = Check();

            if (pars == null)
            {
                return;
            }

            var id = (String)pars["id"];

            var prepare = new THashtable();

            var doItem  = new DOItem(this.context.Connection);
            var dsItems = doItem.GetById(INT(id));

            if (dsItems == null || dsItems.GetSize() == 0)
            {
                prepare["[#ErrMessage]"] = "Wrong item ID!";
                this.Write("error", prepare);
                return;
            }

            var oItem      = dsItems.GetRow(0);
            var title      = STR(oItem["s_Title"]);
            var sourceName = STR(oItem["s_SourceName"]);

            this.context["Page_Title"] = title;
            var leftWidth = "25%";

            if (this.context.IsMobile)
            {
                leftWidth = "20%";
            }

            var idField = doItem.GetIdField();

            if (Config.SHOW_IMAGES)
            {
                prepare["[#Show_Images]"] = 1;
            }
            prepare["[#RedirectLink]"]   = this.GetLink(Config.ACTION_PAGE, "?p=do_redirect_item&id=", "redirect/item/", oItem[idField]);
            prepare["[#LeftWidth]"]      = leftWidth;
            prepare["[#Title]"]          = Util.Show(title);
            prepare["[#InputTitle]"]     = Util.Safe(title);
            prepare["[#RedirectSource]"] = this.GetLink(Config.ACTION_PAGE, "?p=do_redirect_source&source=", "redirect/source/", sourceName);
            prepare["[#SourceName]"]     = sourceName;
            prepare["[#ExtImages]"]      = Config.EXT_IMAGES;
            prepare["[#SourceLink]"]     = this.GetLink(Config.INDEX_PAGE, "?p=items&source=", "items/source/", sourceName);
            prepare["[#Date]"]           = Util.ShowTime(STR(oItem["d_Date"]));
            if (!NUL(oItem["s_Creator"]))
            {
                prepare["[#Creator]"] = STR(oItem["s_Creator"]);
            }
            if (oItem.ContainsKey("t_Description") && !BLANK(STR(oItem["t_Description"])))
            {
                prepare["[#Description]"] = Util.Show(STR(oItem["t_Description"]));
            }
            prepare["[#ItemID]"] = oItem[idField];
            if (this.context.Contains("Name_Category") && !NUL(oItem["s_Category"]))
            {
                prepare["[#Category]"] = oItem["s_Category"];
            }
            if (this.context.Contains("Name_Custom1") && !NUL(oItem["s_Custom1"]))
            {
                prepare["[#Custom1]"] = oItem["s_Custom1"];
            }
            if (this.context.Contains("Name_Custom2") && !NUL(oItem["s_Custom2"]))
            {
                prepare["[#Custom2]"] = oItem["s_Custom2"];
            }

            if (this.context.Lang == "ru" && !this.context.IsMobile)
            {
                prepare["[#Share]"] = 1;
            }

            var engine = this.context.GetEngine();

            if (Config.CACHE_PAGES)
            {
                prepare["[#Home]"] = Util.ShowFromCache(engine, this.context.CacheFolder, "home", "Home", "p=home&from_view_item=1");
            }
            else
            {
                prepare["[#Home]"] = engine.IncludeTemplate("Pages/Home");
            }

            this.Write("Pages/view_item", prepare);
        }
Example #8
0
        /// Execute main logic for Items block.
        public override void Execute()
        {
            var pars = this.Check();

            if (pars == null)
            {
                return;
            }

            var list       = (String)pars["list"];
            var listNumber = list == null ? 1 : INT(list);
            var sourceName = (String)pars["source_name"];
            var filterName = (String)pars["filter_name"];

            var errorMessage = "";
            var filter       = (String)null;
            var category     = (String)null;

            if (!NUL(filterName))
            {
                var          doCategory = new DOCategory(this.context.Connection);
                THashtable[] oCategory  =
                { new THashtable() };
                if (!doCategory.CheckFilterName(filterName, oCategory))
                {
                    errorMessage += "Non-existing filter name!";
                }
                else
                {
                    category = STR(oCategory[0]["s_Name"]);
                    filter   = STR(oCategory[0]["s_Filter"]);
                }
            }

            var sourceId = -1;

            if (!NUL(sourceName))
            {
                var          doSource = new DOSource(this.context.Connection);
                THashtable[] oSource  =
                { new THashtable() };
                if (!doSource.CheckSourceName(sourceName, oSource))
                {
                    if (errorMessage.Length > 0)
                    {
                        errorMessage += "<br/>";
                    }
                    errorMessage += "Non-existing source name!";
                }
                else
                {
                    sourceId = INT(oSource[0]["i_SourceId"]);
                }
            }

            var engine = this.context.GetEngine();

            var prepare = new THashtable();

            if (errorMessage.Length > 0)
            {
                prepare["[#ErrMessage]"] = errorMessage;
                this.Write("error", prepare);
                return;
            }

            if (Config.SHOW_IMAGES)
            {
                prepare["[#Show_Images]"] = 1;
            }
            prepare["[#ColSpan]"] = Config.SHOW_IMAGES ? 4 : 3;

            // Uncomment to enable filtering by source and/or category
            prepare["[#FilterItems]"] = engine.IncludeTemplate("Pages/FilterItems");

            var s_Title = CAT(
                "Browse ",
                Config.NAME_ITEMS,
                (this.context.IsMobile ? "<br/>" : null),
                (!BLANK(sourceName) ? CAT(" ... from '", sourceName, "'") : null),
                (!BLANK(filter) ? CAT(" ... for '", category, "'") : null)
                );

            prepare["[#Title]"] = s_Title;

            var maxRows = Config.DB_ITEMS_ROWS;

            var doItem = new DOItem(this.context.Connection);
            //String realFilter = DOItem.BuildSqlByFilter(filter);
            var realFilter = DOItem.BuildSqlByCategory(category);
            var dsItems    = doItem.EnumItems(sourceName, realFilter, listNumber, maxRows);

            var listTotal = dsItems.GetTotalPages();

            if (listNumber > listTotal)
            {
                if (listTotal > 0)
                {
                    prepare["[#ErrMessage]"] = "List number is too large!";
                    this.Write("error", prepare);
                    return;
                }
                else
                {
                    prepare["[#ErrMessage]"] = "Empty list!";
                    this.Write("error", prepare);
                    return;
                }
            }
            if (listTotal > 1)
            {
                prepare["[#List_Total]"] = listTotal;
                prepare["[#List]"]       = listNumber;
            }

            var count = 1;
            var rows  = new TArrayList();

            for (int n = 0; n < dsItems.GetSize(); n++)
            {
                var oItem = dsItems.GetRow(n);
                var row   = FillItemRow(oItem, doItem.GetIdField(), count);
                count++;
                rows.Add(row);
            }
            prepare["[#Rows]"] = rows;

            if (listTotal > 1)
            {
                var chunk  = 2;
                var before = false;
                var after  = false;

                var pages = new TArrayList();
                for (int n = 1; n <= listTotal; n++)
                {
                    var page = new THashtable();
                    if (n < listNumber - chunk)
                    {
                        if (!before)
                        {
                            before          = true;
                            page["[#Text]"] = "1";
                            page["[#Link]"] = GetPageLink(1);
                            pages.Add(page);
                            page            = new THashtable();
                            page["[#Text]"] = " ... ";
                            //row.Remove("[#Link]");
                            pages.Add(page);
                        }
                        continue;
                    }
                    if (n > listNumber + chunk)
                    {
                        if (!after)
                        {
                            after           = true;
                            page["[#Text]"] = " ... ";
                            pages.Add(page);
                            page            = new THashtable();
                            page["[#Text]"] = listTotal;
                            page["[#Link]"] = GetPageLink(listTotal);
                            pages.Add(page);
                        }
                        continue;
                    }
                    if (listNumber == n)
                    {
                        page["[#Text]"] = CAT("=", n, "=");
                        pages.Add(page);
                    }
                    else
                    {
                        if (n == 1)
                        {
                            page["[#Link]"] = GetPageLink(1);
                            page["[#Text]"] = 1;
                        }
                        else
                        {
                            page["[#Link]"] = GetPageLink(n);
                            page["[#Text]"] = n;
                        }
                        pages.Add(page);
                    }
                }
                prepare["[#Pages]"] = pages;
            }

            this.Write("Pages/items", prepare);
        }