From e9c4465ec72548545eb60f640da85110033d1d69 Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Fri, 25 Oct 2013 15:23:29 -0400 Subject: [PATCH] FIX: Various bugs with Category breadcrumbs --- .../components/breadcrumbs_component.js | 9 +- .../components/categorydrop_component.js | 24 +- .../discourse/helpers/application_helpers.js | 37 +- app/assets/javascripts/discourse/lib/html.js | 60 ++ .../javascripts/discourse/lib/utilities.js | 23 - .../javascripts/discourse/models/nav_item.js | 6 +- .../discourse/routes/application_routes.js | 6 +- .../discourse/routes/list_category_route.js | 7 +- .../discourse-breadcrumbs.js.handlebars | 14 +- .../discourse-categorydrop.js.handlebars | 9 +- .../javascripts/discourse/views/topic_view.js | 2 +- .../common/components/badges.css.scss | 1 + .../stylesheets/desktop/topic-list.scss | 46 +- app/assets/stylesheets/desktop/topic.scss | 92 -- app/assets/stylesheets/mobile/topic-list.scss | 8 +- config/routes.rb | 6 +- test/javascripts/fixtures/list_fixtures.js | 2 +- test/javascripts/helpers/assertions.js | 8 - test/javascripts/helpers/parse_html.js | 7 + test/javascripts/jshint_all.js.erb | 1 + test/javascripts/lib/html_test.js | 43 + test/javascripts/test_helper.js | 1 + vendor/assets/javascripts/htmlparser.js | 993 ++++++++++++++++++ 23 files changed, 1232 insertions(+), 173 deletions(-) create mode 100644 app/assets/javascripts/discourse/lib/html.js create mode 100644 test/javascripts/helpers/parse_html.js create mode 100644 test/javascripts/lib/html_test.js create mode 100644 vendor/assets/javascripts/htmlparser.js diff --git a/app/assets/javascripts/discourse/components/breadcrumbs_component.js b/app/assets/javascripts/discourse/components/breadcrumbs_component.js index 05ae9585b..1f4d90094 100644 --- a/app/assets/javascripts/discourse/components/breadcrumbs_component.js +++ b/app/assets/javascripts/discourse/components/breadcrumbs_component.js @@ -12,8 +12,11 @@ Discourse.DiscourseBreadcrumbsComponent = Ember.Component.extend({ return this.get('parentCategory') || this.get('category'); }.property('parentCategory', 'category'), - childCategories: Em.computed.filter('categories', function(c) { - return c.get('parentCategory') === this.get('targetCategory'); - }) + childCategories: function() { + var self = this; + return this.get('categories').filter(function (c) { + return c.get('parentCategory') === self.get('targetCategory'); + }); + }.property('targetCategory') }); diff --git a/app/assets/javascripts/discourse/components/categorydrop_component.js b/app/assets/javascripts/discourse/components/categorydrop_component.js index e1cec611a..0eb45d099 100644 --- a/app/assets/javascripts/discourse/components/categorydrop_component.js +++ b/app/assets/javascripts/discourse/components/categorydrop_component.js @@ -1,5 +1,4 @@ Discourse.DiscourseCategorydropComponent = Ember.Component.extend({ - classNameBindings: ['category::no-category', 'categories:has-drop'], tagName: 'li', @@ -8,6 +7,15 @@ Discourse.DiscourseCategorydropComponent = Ember.Component.extend({ return "icon icon-caret-right"; }.property('expanded'), + badgeStyle: function() { + var category = this.get('category'); + if (category) { + return Discourse.HTML.categoryStyle(category); + } else { + return "background-color: #eee; color: #333"; + } + }.property('category'), + actions: { expand: function() { if (this.get('expanded')) { @@ -18,25 +26,27 @@ Discourse.DiscourseCategorydropComponent = Ember.Component.extend({ if (this.get('categories')) { this.set('expanded', true); } - var self = this, $dropdown = this.$()[0]; $('html').on('click.category-drop', function(e) { - var closest = $(e.target).closest($dropdown); - return (closest.length && closest[0] === $dropdown) ? true : self.close(); + var $target = $(e.target), + closest = $target.closest($dropdown); + + return ($(e.currentTarget).hasClass('badge-category') || (closest.length && closest[0] === $dropdown)) ? true : self.close(); }); } }, + categoryChanged: function() { + this.close(); + }.observes('category', 'parentCategory'), + close: function() { $('html').off('click.category-drop'); this.set('expanded', false); }, - didInsertElement: function() { - }, - willDestroyElement: function() { $('html').off('click.category-drop'); } diff --git a/app/assets/javascripts/discourse/helpers/application_helpers.js b/app/assets/javascripts/discourse/helpers/application_helpers.js index e1c58b29d..adb570eb2 100644 --- a/app/assets/javascripts/discourse/helpers/application_helpers.js +++ b/app/assets/javascripts/discourse/helpers/application_helpers.js @@ -29,12 +29,32 @@ Handlebars.registerHelper('shorten', function(property, options) { @for Handlebars **/ Handlebars.registerHelper('topicLink', function(property, options) { - var title, topic; - topic = Ember.Handlebars.get(this, property, options); - title = topic.get('fancy_title') || topic.get('title'); - return "" + title + ""; + var topic = Ember.Handlebars.get(this, property, options), + title = topic.get('fancy_title') || topic.get('title'); + return "" + title + ""; }); + +/** + Produces a link to a category given a category object and helper options + + @method categoryLinkHTML + @param {Discourse.Category} category to link to + @param {Object} options standard from handlebars +**/ +function categoryLinkHTML(category, options) { + var categoryOptions = {}; + if (options.hash) { + if (options.hash.allowUncategorized) { + categoryOptions.allowUncategorized = true; + } + if (options.hash.categories) { + categoryOptions.categories = Em.Handlebars.get(this, options.hash.categories, options); + } + } + return new Handlebars.SafeString(Discourse.HTML.categoryLink(category, categoryOptions)); +} + /** Produces a link to a category @@ -42,21 +62,16 @@ Handlebars.registerHelper('topicLink', function(property, options) { @for Handlebars **/ Handlebars.registerHelper('categoryLink', function(property, options) { - var allowUncategorized = options.hash && options.hash.allowUncategorized; - var category = Ember.Handlebars.get(this, property, options); - return new Handlebars.SafeString(Discourse.Utilities.categoryLink(category, allowUncategorized)); + return categoryLinkHTML(Ember.Handlebars.get(this, property, options), options); }); - /** Produces a bound link to a category @method boundCategoryLink @for Handlebars **/ -Ember.Handlebars.registerBoundHelper('boundCategoryLink', function(category) { - return new Handlebars.SafeString(Discourse.Utilities.categoryLink(category)); -}); +Ember.Handlebars.registerBoundHelper('boundCategoryLink', categoryLinkHTML); /** Produces a link to a route with support for i18n on the title diff --git a/app/assets/javascripts/discourse/lib/html.js b/app/assets/javascripts/discourse/lib/html.js new file mode 100644 index 000000000..e204d9983 --- /dev/null +++ b/app/assets/javascripts/discourse/lib/html.js @@ -0,0 +1,60 @@ +/** + Helpers to build HTML strings such as rich links to categories and topics. + + @class HTML + @namespace Discourse + @module Discourse +**/ +Discourse.HTML = { + + /** + Returns the CSS styles for a category + + @method categoryStyle + @param {Discourse.Category} category the category whose link we want + **/ + categoryStyle: function(category) { + var color = Em.get(category, 'color'), + textColor = Em.get(category, 'text_color'); + + if (!color && !textColor) { return; } + + // Add the custom style if we need to + var style = ""; + if (color) { style += "background-color: #" + color + "; "; } + if (textColor) { style += "color: #" + textColor + "; "; } + return style; + }, + + /** + Create a badge-like category link + + @method categoryLink + @param {Discourse.Category} category the category whose link we want + @param {Object} opts The options for the category link + @param {Boolean} opts.allowUncategorized Whether we allow rendering of the uncategorized category + @returns {String} the html category badge + **/ + categoryLink: function(category, opts) { + opts = opts || {}; + + if ((!category) || + (!opts.allowUncategorized && Em.get(category, 'id') === Discourse.Site.currentProp("uncategorized_category_id"))) return ""; + + var name = Em.get(category, 'name'), + description = Em.get(category, 'description'), + html = ""; + + return html; + } + +}; \ No newline at end of file diff --git a/app/assets/javascripts/discourse/lib/utilities.js b/app/assets/javascripts/discourse/lib/utilities.js index eef2ed1e2..e2e306094 100644 --- a/app/assets/javascripts/discourse/lib/utilities.js +++ b/app/assets/javascripts/discourse/lib/utilities.js @@ -33,29 +33,6 @@ Discourse.Utilities = { } }, - /** - Create a badge-like category link - - @method categoryLink - @param {Discourse.Category} category the category whose link we want - @returns {String} the html category badge - **/ - categoryLink: function(category, allowUncategorized) { - if (!category) return ""; - if (!allowUncategorized && Em.get(category, 'id') === Discourse.Site.currentProp("uncategorized_category_id")) return ""; - - var color = Em.get(category, 'color'), - textColor = Em.get(category, 'text_color'), - name = Em.get(category, 'name'), - description = Em.get(category, 'description'), - html = "" + name + ""; - }, - avatarUrl: function(template, size) { if (!template) { return ""; } var rawSize = Discourse.Utilities.getRawSize(Discourse.Utilities.translateSize(size)); diff --git a/app/assets/javascripts/discourse/models/nav_item.js b/app/assets/javascripts/discourse/models/nav_item.js index 5bb6ef44a..0a58954be 100644 --- a/app/assets/javascripts/discourse/models/nav_item.js +++ b/app/assets/javascripts/discourse/models/nav_item.js @@ -43,7 +43,11 @@ Discourse.NavItem = Discourse.Model.extend({ var mode = ""; var category = this.get("category"); if(category){ - mode += "category/" + category.get("slug") + "/"; + mode += "category/"; + + var parentSlug = category.get('parentCategory.slug'); + if (parentSlug) { mode += parentSlug + "/"; } + mode += category.get("slug") + "/l/"; } return mode + name.replace(' ', '-'); } diff --git a/app/assets/javascripts/discourse/routes/application_routes.js b/app/assets/javascripts/discourse/routes/application_routes.js index 1d7f4db2e..139b86359 100644 --- a/app/assets/javascripts/discourse/routes/application_routes.js +++ b/app/assets/javascripts/discourse/routes/application_routes.js @@ -26,8 +26,10 @@ Discourse.Route.buildRoutes(function() { Discourse.ListController.filters.forEach(function(filter) { router.route(filter, { path: "/" + filter }); router.route(filter, { path: "/" + filter + "/more" }); - router.route(filter + "Category", { path: "/category/:slug/" + filter }); - router.route(filter + "Category", { path: "/category/:slug/" + filter + "/more" }); + router.route(filter + "Category", { path: "/category/:slug/l/" + filter }); + router.route(filter + "Category", { path: "/category/:slug/l/" + filter + "/more" }); + router.route(filter + "Category", { path: "/category/:parentSlug/:slug/l/" + filter }); + router.route(filter + "Category", { path: "/category/:parentSlug/:slug/l/" + filter + "/more" }); }); diff --git a/app/assets/javascripts/discourse/routes/list_category_route.js b/app/assets/javascripts/discourse/routes/list_category_route.js index e85c8ccf3..c9257a995 100644 --- a/app/assets/javascripts/discourse/routes/list_category_route.js +++ b/app/assets/javascripts/discourse/routes/list_category_route.js @@ -23,10 +23,9 @@ Discourse.ListCategoryRoute = Discourse.FilteredListRoute.extend({ var listController = this.controllerFor('list'), categorySlug = Discourse.Category.slugFor(category), - self = this; - - var filter = this.filter || "latest"; - var url = "category/" + categorySlug + "/" + filter; + self = this, + filter = this.filter || "latest", + url = "category/" + categorySlug + "/l/" + filter; listController.set('filterMode', url); listController.load(url).then(function(topicList) { diff --git a/app/assets/javascripts/discourse/templates/components/discourse-breadcrumbs.js.handlebars b/app/assets/javascripts/discourse/templates/components/discourse-breadcrumbs.js.handlebars index c20dfc4a5..a67132bf2 100644 --- a/app/assets/javascripts/discourse/templates/components/discourse-breadcrumbs.js.handlebars +++ b/app/assets/javascripts/discourse/templates/components/discourse-breadcrumbs.js.handlebars @@ -1,9 +1,13 @@ -{{discourse-categorydrop title=title categories=parentCategories}} - -{{discourse-categorydrop category=targetCategory categories=childCategories}} - +
  • +{{discourse-categorydrop parentCategory=category categories=parentCategories}} +
  • +
  • + {{discourse-categorydrop parentCategory=category category=targetCategory categories=childCategories}} +
  • {{#if parentCategory}} - {{discourse-categorydrop category=category}} +
  • + {{boundCategoryLink category}} +
  • {{/if}}
    \ No newline at end of file diff --git a/app/assets/javascripts/discourse/templates/components/discourse-categorydrop.js.handlebars b/app/assets/javascripts/discourse/templates/components/discourse-categorydrop.js.handlebars index f2148db82..c586619cc 100644 --- a/app/assets/javascripts/discourse/templates/components/discourse-categorydrop.js.handlebars +++ b/app/assets/javascripts/discourse/templates/components/discourse-categorydrop.js.handlebars @@ -1,13 +1,12 @@ {{#if category}} - {{categoryLink category}} + {{boundCategoryLink category}} {{else}} - + {{/if}} {{#if categories}} - - -
    + +
    {{#each categories}}
    {{categoryLink this}}
    {{/each}} diff --git a/app/assets/javascripts/discourse/views/topic_view.js b/app/assets/javascripts/discourse/views/topic_view.js index 0a39045b5..2d4f8e88a 100644 --- a/app/assets/javascripts/discourse/views/topic_view.js +++ b/app/assets/javascripts/discourse/views/topic_view.js @@ -330,7 +330,7 @@ Discourse.TopicView = Discourse.View.extend(Discourse.Scrolling, { var category = this.get('controller.content.category'); if (category) { - opts.catLink = Discourse.Utilities.categoryLink(category); + opts.catLink = Discourse.HTML.categoryLink(category); } else { opts.catLink = "" + (I18n.t("topic.browse_all_categories")) + ""; } diff --git a/app/assets/stylesheets/common/components/badges.css.scss b/app/assets/stylesheets/common/components/badges.css.scss index afd2d4df3..6a84b3eea 100644 --- a/app/assets/stylesheets/common/components/badges.css.scss +++ b/app/assets/stylesheets/common/components/badges.css.scss @@ -30,6 +30,7 @@ } } + // Notification badge // -------------------------------------------------- diff --git a/app/assets/stylesheets/desktop/topic-list.scss b/app/assets/stylesheets/desktop/topic-list.scss index 93493d12f..052d6cc8b 100644 --- a/app/assets/stylesheets/desktop/topic-list.scss +++ b/app/assets/stylesheets/desktop/topic-list.scss @@ -350,12 +350,28 @@ // -------------------------------------------------- .list-controls { + .home { + font-size: 20px; + font-weight: normal; + } + .badge-category { + padding: 4px 10px; display: inline-block; - background-color: yellow; - margin: 8px 0 0 8px; + line-height: 24px; float: left; } + .category-dropdown-button { + padding: 4px 10px 3px 8px; + border-left: 1px solid rgba(0, 0, 0, 0.15); + font-size: 16px; + width: 10px; + text-align: center; + + &:hover { + opacity: 0.8; + } + } clear: both; } #list-area { @@ -364,8 +380,6 @@ .topic-statuses .topic-status i {font-size: 15px;} - - .empty-topic-list { padding: 10px; } @@ -396,3 +410,27 @@ span.posted { image: image-url("posted.png"); }; } + +.category-dropdown-menu { + overflow-x: hidden; + overflow-y: scroll; + position: absolute; + border: 1px solid #ccc; + background-color: white; + width: 200px; + height: 200px; + padding: 8px 5px 0 7px; + z-index: 100; + margin-top: 31px; + + .badge-category { + font-size: 13px; + line-height: 26px; + padding: 0px 8px; + float: none; + } + + div { + margin-bottom: 10px; + } +} diff --git a/app/assets/stylesheets/desktop/topic.scss b/app/assets/stylesheets/desktop/topic.scss index d93dd36c8..f6d84c3ba 100644 --- a/app/assets/stylesheets/desktop/topic.scss +++ b/app/assets/stylesheets/desktop/topic.scss @@ -208,97 +208,5 @@ ol.category-breadcrumb { li { float: left; margin-right: 5px; - border: 1px solid transparent; - line-height: 31px; - - &.no-category { - font-size: 22px; - - a { - margin-right: 3px; - margin-left: 4px; - - &:hover { - color: black; - } - } - - button { - padding-left: 6px; - &:hover { - background-color: #eee; - } - } - - &.has-drop:hover { - background-color: #f9f9f9; - button { - border-left: 1px solid #bbb; - } - } - - .category-menu { - margin-left: -1px; - padding: 8px 5px 0 3px; - } - } - - .badge-category { - margin: 0; - display: inline-block; - font-size: 14px; - padding: 0px 10px; - float: none; - } - - button { - background: none; - border: 1px solid transparent; - padding: 0 4px 0 2px; - margin: 0; - height: 22px; - color: #666; - line-height: 13px; - text-align: center; - - i.icon-caret-down { - margin-left: -2px; - } - } - - &.has-drop:hover { - background-color: #eee; - border: 1px solid #bbb; - - button { - color: black; - } - } - } - - .clear { - clear: both; - } - - .category-menu { - overflow-x: hidden; - overflow-y: scroll; - position: absolute; - border: 1px solid #ccc; - background-color: white; - width: 200px; - height: 200px; - padding: 8px 5px 0 7px; - z-index: 100; - - .badge-category { - font-size: 13px; - line-height: 26px; - padding: 0px 8px; - } - - div { - margin-bottom: 10px; - } } } diff --git a/app/assets/stylesheets/mobile/topic-list.scss b/app/assets/stylesheets/mobile/topic-list.scss index 739fc9049..56553a040 100644 --- a/app/assets/stylesheets/mobile/topic-list.scss +++ b/app/assets/stylesheets/mobile/topic-list.scss @@ -242,10 +242,13 @@ .list-controls { .badge-category { display: inline-block; - background-color: yellow; margin: 8px 0 0 8px; float: left; } + .category-dropdown { + margin: 8px 0; + } + clear: both; } #list-area { @@ -371,9 +374,6 @@ ol.category-breadcrumb { .icon-home { font-size: 20px; } - .badge-category { - margin: 3px 8px 0; - } button { padding: 5px 10px; font-size: 16px; diff --git a/config/routes.rb b/config/routes.rb index 2513694d1..d99aa0f3e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -210,8 +210,10 @@ Discourse::Application.routes.draw do get "#{filter}" => "list##{filter}" get "#{filter}/more" => "list##{filter}" - get "category/:category/#{filter}" => "list##{filter}" - get "category/:category/#{filter}/more" => "list##{filter}" + get "category/:category/l/#{filter}" => "list##{filter}" + get "category/:category/l/#{filter}/more" => "list##{filter}" + get "category/:parent_category/:category/l/#{filter}" => "list##{filter}" + get "category/:parent_category/:category/l/#{filter}/more" => "list##{filter}" end get 'category/:parent_category/:category' => 'list#category', as: 'category_list_parent' diff --git a/test/javascripts/fixtures/list_fixtures.js b/test/javascripts/fixtures/list_fixtures.js index 02e3973a6..c22ade7b0 100644 --- a/test/javascripts/fixtures/list_fixtures.js +++ b/test/javascripts/fixtures/list_fixtures.js @@ -1,4 +1,4 @@ /*jshint maxlen:10000000 */ Discourse.URL_FIXTURES["/latest.json"] = {"categories":[{"id":4,"name":"faq","color":"33b","text_color":"FFFFFF","slug":"faq","topic_count":41,"description":"Topics that come up very often when discussing Discourse will eventually be classified into this Frequently Asked Questions category. Should only be added to popular topics.","topic_url":"/t/category-definition-for-faq/25","hotness":5.0,"read_restricted":false,"permission":null},{"id":1,"name":"bug","color":"ae3a27","text_color":"FFFFFF","slug":"bug","topic_count":442,"description":"Bug reports on Discourse. Do be sure to search prior to submitting bugs. Include repro steps, and only describe one bug per topic please.","topic_url":"/t/category-definition-for-bug/2","hotness":5.0,"read_restricted":false,"permission":null},{"id":6,"name":"support","color":"b99","text_color":"FFFFFF","slug":"support","topic_count":374,"description":"Support on configuring, using, and installing Discourse. Not for software development related topics, but for admins and end users configuring and using Discourse.","topic_url":"/t/category-definition-for-support/389","hotness":5.0,"read_restricted":false,"permission":null},{"id":2,"name":"feature","color":"0E76BD","text_color":"FFFFFF","slug":"feature","topic_count":467,"description":"Discussion about features or potential features of Discourse: how they work, why they work, etc.","topic_url":"/t/category-definition-for-feature/11","hotness":5.0,"read_restricted":false,"permission":null},{"id":5,"name":"extensibility ","color":"FE8432","text_color":"FFFFFF","slug":"extensibility","topic_count":37,"description":"Topics about extending the functionality of Discourse with plugins, themes, add-ons, or other mechanisms for extensibility. ","topic_url":"/t/category-definition-for-extensibility/28","hotness":5.0,"read_restricted":false,"permission":null},{"id":9,"name":"ux","color":"5F497A","text_color":"FFFFFF","slug":"ux","topic_count":112,"description":"Discussion about the user interface of Discourse, how features are presented to the user in the client, including language and UI elements.","topic_url":"/t/category-definition-for-ux/2628","hotness":5.0,"read_restricted":false,"permission":null},{"id":10,"name":"howto","color":"76923C","text_color":"FFFFFF","slug":"howto","topic_count":45,"description":"Tutorial topics that describe how to set up, configure, or install Discourse using a specific platform or environment.","topic_url":"/t/category-definition-for-howto/2629","hotness":5.0,"read_restricted":false,"permission":null},{"id":7,"name":"dev","color":"000","text_color":"FFFFFF","slug":"dev","topic_count":183,"description":"This category is for topics related to hacking on Discourse: submitting pull requests, configuring development environments, coding conventions, and so forth.","topic_url":"/t/category-definition-for-dev/1026","hotness":5.0,"read_restricted":false,"permission":null}],"users":[{"id":1,"username":"sam","avatar_template":"https://www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon"},{"id":19,"username":"eviltrout","avatar_template":"https://www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon"},{"id":14,"username":"clay","avatar_template":"https://www.gravatar.com/avatar/e371bbd32ba2e9b27842e60ef5952d47.png?s={size}&r=pg&d=identicon"},{"id":32,"username":"codinghorror","avatar_template":"https://www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon"},{"id":6207,"username":"wiremine","avatar_template":"https://www.gravatar.com/avatar/f361c70e8d51674fa7dc3aa69e04e739.png?s={size}&r=pg&d=identicon"},{"id":3681,"username":"Ajarn","avatar_template":"https://www.gravatar.com/avatar/bdfe9d9defc060d689ccd31c07e1bc19.png?s={size}&r=pg&d=identicon"},{"id":5707,"username":"trident","avatar_template":"https://www.gravatar.com/avatar/f6e6a22d7b4afee9182de3ff2302534a.png?s={size}&r=pg&d=identicon"},{"id":3062,"username":"Sailsman63","avatar_template":"https://www.gravatar.com/avatar/d2afe59f03e33f57760fbaacc35949d5.png?s={size}&r=pg&d=identicon"},{"id":3987,"username":"Sander78","avatar_template":"https://www.gravatar.com/avatar/e7069beb46df22270a41afc7b277fe50.png?s={size}&r=pg&d=identicon"},{"id":6205,"username":"senny","avatar_template":"https://www.gravatar.com/avatar/3d698e2872c07061a455d9e250861235.png?s={size}&r=pg&d=identicon"},{"id":6197,"username":"pinecone","avatar_template":"https://www.gravatar.com/avatar/a7e15f8c5bac7d8bb5a6ea7ae0eb2092.png?s={size}&r=pg&d=identicon"},{"id":5271,"username":"royguo","avatar_template":"https://www.gravatar.com/avatar/7e795755fe8a817981c3a81620faf359.png?s={size}&r=pg&d=identicon"},{"id":5976,"username":"microcaicai","avatar_template":"https://www.gravatar.com/avatar/7fbcc3f547d91c5cc602f69cb78c26cf.png?s={size}&r=pg&d=identicon"},{"id":2602,"username":"georgekaplan59","avatar_template":"https://www.gravatar.com/avatar/503623c769903342cba73e722a364061.png?s={size}&r=pg&d=identicon"},{"id":6089,"username":"Juffin","avatar_template":"https://www.gravatar.com/avatar/1b65c915ecda3d3e1ae9338ee13147e2.png?s={size}&r=pg&d=identicon"},{"id":4457,"username":"Lee_Ars","avatar_template":"https://www.gravatar.com/avatar/eff1b72d56a97459a27161ccf7f20c89.png?s={size}&r=pg&d=identicon"},{"id":714,"username":"jcolebrand","avatar_template":"https://www.gravatar.com/avatar/c4cca9bfec5d5e77f625d9fbe8e37a41.png?s={size}&r=pg&d=identicon"},{"id":810,"username":"ChrisHanel","avatar_template":"https://www.gravatar.com/avatar/467863a322e1a3ce557bfd17f4677600.png?s={size}&r=pg&d=identicon"},{"id":5351,"username":"erlend_sh","avatar_template":"https://www.gravatar.com/avatar/69fda0df8b4878fb6a18deffa972d26a.png?s={size}&r=pg&d=identicon"},{"id":5992,"username":"tealfox","avatar_template":"https://www.gravatar.com/avatar/46365f8bb744cd42d31d6aefd51cd2d8.png?s={size}&r=pg&d=identicon"},{"id":2504,"username":"sreinert","avatar_template":"https://www.gravatar.com/avatar/2c264c3436863126b1f31e288facdf79.png?s={size}&r=pg&d=identicon"},{"id":3,"username":"supermathie","avatar_template":"https://www.gravatar.com/avatar/44ae1b2d44d48aed3d432129a5703942.png?s={size}&r=pg&d=identicon"},{"id":4263,"username":"mcwumbly","avatar_template":"https://www.gravatar.com/avatar/e217128117fe24525c7af5ebc5e45745.png?s={size}&r=pg&d=identicon"},{"id":4395,"username":"aftakitani","avatar_template":"https://www.gravatar.com/avatar/a26ec726f9f7e819e01797d34ea8dbc6.png?s={size}&r=pg&d=identicon"},{"id":402,"username":"thebrianbarlow","avatar_template":"https://www.gravatar.com/avatar/5ddf2459e8edd6cf52dfff6cb41ca70d.png?s={size}&r=pg&d=identicon"},{"id":2876,"username":"SBauch","avatar_template":"https://www.gravatar.com/avatar/9f9c97c5ef6915fb25af52ab3d51a06e.png?s={size}&r=pg&d=identicon"},{"id":2416,"username":"andrewkhunn","avatar_template":"https://www.gravatar.com/avatar/b1cf766ba89d10d985e408e488cd5b32.png?s={size}&r=pg&d=identicon"},{"id":5984,"username":"broerse","avatar_template":"https://www.gravatar.com/avatar/bdfe0429bb97aef2f9ba661a2ee3f8b8.png?s={size}&r=pg&d=identicon"},{"id":5648,"username":"jamesaanderson","avatar_template":"https://www.gravatar.com/avatar/b3e9977094ce189bbb493cf7f9adea21.png?s={size}&r=pg&d=identicon"},{"id":4996,"username":"wmertens","avatar_template":"https://www.gravatar.com/avatar/a64ed062eb5e2c3407122fcf16c5de6b.png?s={size}&r=pg&d=identicon"},{"id":6199,"username":"spiral2k","avatar_template":"https://www.gravatar.com/avatar/4d9710f54df9edece689980d4bd4ec91.png?s={size}&r=pg&d=identicon"},{"id":1353,"username":"sparr","avatar_template":"https://www.gravatar.com/avatar/7906663b1197829751673465948e0b05.png?s={size}&r=pg&d=identicon"},{"id":5108,"username":"djensen47","avatar_template":"https://www.gravatar.com/avatar/04e8c634e5ee0fd074f78f3bad6eb5b3.png?s={size}&r=pg&d=identicon"},{"id":5294,"username":"madbomber","avatar_template":"https://www.gravatar.com/avatar/185cd842e5a13f2adc822ae20ffaa7bb.png?s={size}&r=pg&d=identicon"},{"id":5979,"username":"balexand","avatar_template":"https://www.gravatar.com/avatar/6180d7335815945eda8651e080be4b98.png?s={size}&r=pg&d=identicon"},{"id":2,"username":"Neil","avatar_template":"https://www.gravatar.com/avatar/42776c4982dff1fa45ee8248532f8ad0.png?s={size}&r=pg&d=identicon"},{"id":162,"username":"splummer","avatar_template":"https://www.gravatar.com/avatar/26e826e728ae11afec33bd438769779a.png?s={size}&r=pg&d=identicon"},{"id":6208,"username":"chromium_o2","avatar_template":"https://www.gravatar.com/avatar/a5d0ac66c4b8a5ac23b58b109d068a20.png?s={size}&r=pg&d=identicon"},{"id":1995,"username":"zogstrip","avatar_template":"https://www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon"},{"id":5171,"username":"bosco","avatar_template":"https://www.gravatar.com/avatar/219547b6e3edf492a68a0d341e15f971.png?s={size}&r=pg&d=identicon"},{"id":38,"username":"frandallfarmer","avatar_template":"https://www.gravatar.com/avatar/6c38e00d92cd9bd3ada3392b15015553.png?s={size}&r=pg&d=identicon"},{"id":3192,"username":"patternicity","avatar_template":"https://www.gravatar.com/avatar/35f1f1927f10bd8f975325d440f6a77c.png?s={size}&r=pg&d=identicon"},{"id":5270,"username":"Nedal","avatar_template":"https://www.gravatar.com/avatar/fb74b7ff14d0eae68ca8992760133187.png?s={size}&r=pg&d=identicon"},{"id":5113,"username":"Heisenberg","avatar_template":"https://www.gravatar.com/avatar/70985ef0462329047f5d9302a89f277e.png?s={size}&r=pg&d=identicon"},{"id":3986,"username":"creativetech","avatar_template":"https://www.gravatar.com/avatar/c356b1a7f3bddcc8812e8a101eb99f07.png?s={size}&r=pg&d=identicon"},{"id":6218,"username":"stevefink","avatar_template":"https://www.gravatar.com/avatar/08780b97dd4b3ebc31d6b4b7d156b457.png?s={size}&r=pg&d=identicon"}],"topic_list":{"can_create_topic":false,"more_topics_url":"/latest.json?page=1","draft":null,"draft_key":"new_topic","draft_sequence":null,"topics":[{"id":1,"title":"Welcome to meta.discourse.org","fancy_title":"Welcome to meta.discourse.org","slug":"welcome-to-meta-discourse-org","posts_count":5,"reply_count":5,"highest_post_number":23,"image_url":null,"created_at":"2013-01-31T23:52:28-05:00","last_posted_at":"2013-02-07T16:50:41-05:00","bumped":true,"bumped_at":"2013-02-07T11:57:34-05:00","unseen":false,"pinned":true,"excerpt":"Welcome to meta, the official site for discussing the next-gen open source Discourse forum software. You'll find topics on features, bugs, hosting, development, and general support here. \n\nDiscourse is early beta softwar…","visible":true,"closed":true,"archived":false,"views":10354,"like_count":90,"has_best_of":false,"archetype":"regular","category_id":null,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Most Posts","user_id":19},{"extras":null,"description":"Frequent Poster","user_id":14},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":8606,"title":"Latest vs. New vs. Unread","fancy_title":"Latest vs. New vs. Unread","slug":"latest-vs-new-vs-unread","posts_count":11,"reply_count":8,"highest_post_number":11,"image_url":null,"created_at":"2013-07-23T15:10:56-04:00","last_posted_at":"2013-07-24T09:35:48-04:00","bumped":true,"bumped_at":"2013-07-24T09:35:48-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":69,"like_count":5,"has_best_of":false,"archetype":"regular","category_id":4,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":6207},{"extras":null,"description":"Most Posts","user_id":3681},{"extras":null,"description":"Frequent Poster","user_id":5707},{"extras":null,"description":"Frequent Poster","user_id":3062}]},{"id":8198,"title":"Unable to create group","fancy_title":"Unable to create group","slug":"unable-to-create-group","posts_count":12,"reply_count":6,"highest_post_number":12,"image_url":null,"created_at":"2013-07-08T13:58:49-04:00","last_posted_at":"2013-07-24T09:22:00-04:00","bumped":true,"bumped_at":"2013-07-24T09:22:00-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":139,"like_count":2,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":3681},{"extras":null,"description":"Most Posts","user_id":3987},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":6205},{"extras":"latest","description":"Most Recent Poster","user_id":6197}]},{"id":7802,"title":"Wrong displayed create time","fancy_title":"Wrong displayed create time","slug":"wrong-displayed-create-time","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1250/463c47397726e0a9.png","created_at":"2013-06-27T12:00:05-04:00","last_posted_at":"2013-07-24T08:25:35-04:00","bumped":true,"bumped_at":"2013-07-24T08:25:35-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":65,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":6,"posters":[{"extras":null,"description":"Original Poster","user_id":5271},{"extras":"latest","description":"Most Recent Poster","user_id":5976}]},{"id":8618,"title":"Not all mods to be staff memebers","fancy_title":"Not all mods to be staff memebers","slug":"not-all-mods-to-be-staff-memebers","posts_count":4,"reply_count":2,"highest_post_number":4,"image_url":null,"created_at":"2013-07-24T06:17:00-04:00","last_posted_at":"2013-07-24T08:24:44-04:00","bumped":true,"bumped_at":"2013-07-24T08:24:44-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":25,"like_count":1,"has_best_of":false,"archetype":"regular","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":2602},{"extras":null,"description":"Most Posts","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":6089}]},{"id":8615,"title":"Filtering out out-of-office-replies in the reply-by-mail feature","fancy_title":"Filtering out out-of-office-replies in the reply-by-mail feature","slug":"filtering-out-out-of-office-replies-in-the-reply-by-mail-feature","posts_count":3,"reply_count":0,"highest_post_number":3,"image_url":null,"created_at":"2013-07-24T04:40:43-04:00","last_posted_at":"2013-07-24T08:15:18-04:00","bumped":true,"bumped_at":"2013-07-24T08:15:18-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":13,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":2,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":3987},{"extras":null,"description":"Most Posts","user_id":1}]},{"id":7464,"title":"CSS documentation?","fancy_title":"CSS documentation?","slug":"css-documentation","posts_count":3,"reply_count":1,"highest_post_number":3,"image_url":null,"created_at":"2013-06-13T18:25:19-04:00","last_posted_at":"2013-07-24T02:21:38-04:00","bumped":true,"bumped_at":"2013-07-24T06:57:54-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":124,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":5,"posters":[{"extras":null,"description":"Original Poster","user_id":4457},{"extras":null,"description":"Most Posts","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":6089}]},{"id":31,"title":"What is the most awesome plugin for Discourse, that does not yet exist?","fancy_title":"What is the most awesome plugin for Discourse, that does not yet exist?","slug":"what-is-the-most-awesome-plugin-for-discourse-that-does-not-yet-exist","posts_count":164,"reply_count":115,"highest_post_number":170,"image_url":null,"created_at":"2013-02-03T06:43:18-05:00","last_posted_at":"2013-07-24T03:54:47-04:00","bumped":true,"bumped_at":"2013-07-24T03:54:47-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":3890,"like_count":428,"has_best_of":true,"archetype":"regular","category_id":5,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Most Posts","user_id":714},{"extras":null,"description":"Frequent Poster","user_id":810},{"extras":null,"description":"Frequent Poster","user_id":14},{"extras":"latest","description":"Most Recent Poster","user_id":5351}]},{"id":8342,"title":"Dropping the statistical stuff","fancy_title":"Dropping the statistical stuff","slug":"dropping-the-statistical-stuff","posts_count":17,"reply_count":9,"highest_post_number":17,"image_url":null,"created_at":"2013-07-13T03:19:58-04:00","last_posted_at":"2013-07-24T03:11:18-04:00","bumped":true,"bumped_at":"2013-07-24T03:11:18-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":281,"like_count":8,"has_best_of":false,"archetype":"regular","category_id":2,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":5992},{"extras":null,"description":"Most Posts","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":6207},{"extras":null,"description":"Frequent Poster","user_id":3681},{"extras":null,"description":"Frequent Poster","user_id":2504}]},{"id":8613,"title":"Add branching text when posts moved to a new topic","fancy_title":"Add branching text when posts moved to a new topic","slug":"add-branching-text-when-posts-moved-to-a-new-topic","posts_count":4,"reply_count":0,"highest_post_number":4,"image_url":"http://cdn.discourse.org/assets/emoji/grin.png","created_at":"2013-07-23T22:31:39-04:00","last_posted_at":"2013-07-24T02:47:22-04:00","bumped":true,"bumped_at":"2013-07-24T02:47:22-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":37,"like_count":1,"has_best_of":false,"archetype":"regular","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":3},{"extras":null,"description":"Most Posts","user_id":4263},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":5351}]},{"id":7764,"title":"New: Reply via Email Support!","fancy_title":"New: Reply via Email Support!","slug":"new-reply-via-email-support","posts_count":19,"reply_count":12,"highest_post_number":19,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1227/8f4e5818dfaa56c7.png","created_at":"2013-06-25T11:58:39-04:00","last_posted_at":"2013-07-24T01:56:23-04:00","bumped":true,"bumped_at":"2013-07-24T01:56:23-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":893,"like_count":34,"has_best_of":false,"archetype":"regular","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":19},{"extras":null,"description":"Most Posts","user_id":4395},{"extras":null,"description":"Frequent Poster","user_id":402},{"extras":null,"description":"Frequent Poster","user_id":2876},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":8564,"title":"Improvements to self-deleted posts","fancy_title":"Improvements to self-deleted posts","slug":"improvements-to-self-deleted-posts","posts_count":10,"reply_count":8,"highest_post_number":10,"image_url":null,"created_at":"2013-07-22T04:48:55-04:00","last_posted_at":"2013-07-24T01:54:46-04:00","bumped":true,"bumped_at":"2013-07-24T01:54:46-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":107,"like_count":11,"has_best_of":false,"archetype":"regular","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":32},{"extras":null,"description":"Most Posts","user_id":2416},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":8168,"title":"Audio html5 tag","fancy_title":"Audio html5 tag","slug":"audio-html5-tag","posts_count":6,"reply_count":2,"highest_post_number":6,"image_url":null,"created_at":"2013-07-07T11:48:25-04:00","last_posted_at":"2013-07-24T00:47:42-04:00","bumped":true,"bumped_at":"2013-07-24T00:47:42-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":112,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":2,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":5984},{"extras":null,"description":"Most Posts","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":5648}]},{"id":6743,"title":"Bare Bones Installer Notes for cPanel Server","fancy_title":"Bare Bones Installer Notes for cPanel Server","slug":"bare-bones-installer-notes-for-cpanel-server","posts_count":5,"reply_count":3,"highest_post_number":6,"image_url":null,"created_at":"2013-05-20T15:46:37-04:00","last_posted_at":"2013-07-23T23:41:38-04:00","bumped":true,"bumped_at":"2013-07-23T23:41:38-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":170,"like_count":6,"has_best_of":false,"archetype":"regular","category_id":10,"posters":[{"extras":null,"description":"Original Poster","user_id":4996},{"extras":null,"description":"Most Posts","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":8542,"title":"Add user to filter when explicitly requesting their post","fancy_title":"Add user to filter when explicitly requesting their post","slug":"add-user-to-filter-when-explicitly-requesting-their-post","posts_count":3,"reply_count":1,"highest_post_number":3,"image_url":null,"created_at":"2013-07-21T04:43:39-04:00","last_posted_at":"2013-07-23T22:17:30-04:00","bumped":true,"bumped_at":"2013-07-23T22:17:30-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":48,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":3},{"extras":null,"description":"Most Posts","user_id":32}]},{"id":8610,"title":"I want to translate and RTL this forum system","fancy_title":"I want to translate and RTL this forum system","slug":"i-want-to-translate-and-rtl-this-forum-system","posts_count":4,"reply_count":2,"highest_post_number":4,"image_url":null,"created_at":"2013-07-23T18:17:39-04:00","last_posted_at":"2013-07-23T20:57:40-04:00","bumped":true,"bumped_at":"2013-07-23T20:57:40-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":39,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":6,"posters":[{"extras":null,"description":"Original Poster","user_id":6199},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":6304,"title":"Proposal for a (hash) tagging feature","fancy_title":"Proposal for a (hash) tagging feature","slug":"proposal-for-a-hash-tagging-feature","posts_count":41,"reply_count":26,"highest_post_number":42,"image_url":"https://www.gravatar.com/avatar/9420c2ef938f4857bb9c921836b243d4.png?s=40&r=pg&d=identicon","created_at":"2013-05-01T12:05:51-04:00","last_posted_at":"2013-07-23T20:40:47-04:00","bumped":true,"bumped_at":"2013-07-23T20:40:47-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":739,"like_count":34,"has_best_of":false,"archetype":"regular","category_id":2,"posters":[{"extras":null,"description":"Original Poster","user_id":2876},{"extras":null,"description":"Most Posts","user_id":1353},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":5108},{"extras":"latest","description":"Most Recent Poster","user_id":5294}]},{"id":8604,"title":"Hide sensitive site settings","fancy_title":"Hide sensitive site settings","slug":"hide-sensitive-site-settings","posts_count":5,"reply_count":2,"highest_post_number":5,"image_url":null,"created_at":"2013-07-23T13:51:07-04:00","last_posted_at":"2013-07-23T19:15:26-04:00","bumped":true,"bumped_at":"2013-07-23T19:15:26-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":53,"like_count":5,"has_best_of":false,"archetype":"regular","category_id":null,"posters":[{"extras":null,"description":"Original Poster","user_id":5979},{"extras":null,"description":"Most Posts","user_id":3987},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":4874,"title":"Multisite setup instructions","fancy_title":"Multisite setup instructions","slug":"multisite-setup-instructions","posts_count":3,"reply_count":1,"highest_post_number":3,"image_url":null,"created_at":"2013-03-18T12:18:18-04:00","last_posted_at":"2013-07-23T18:39:00-04:00","bumped":true,"bumped_at":"2013-07-23T18:39:00-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":526,"like_count":15,"has_best_of":false,"archetype":"regular","category_id":10,"posters":[{"extras":null,"description":"Original Poster","user_id":2},{"extras":null,"description":"Most Posts","user_id":162},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":8588,"title":"Notify me about incoming links when I'm watching a topic","fancy_title":"Notify me about incoming links when I’m watching a topic","slug":"notify-me-about-incoming-links-when-im-watching-a-topic","posts_count":3,"reply_count":1,"highest_post_number":3,"image_url":null,"created_at":"2013-07-23T05:04:01-04:00","last_posted_at":"2013-07-23T17:33:04-04:00","bumped":true,"bumped_at":"2013-07-23T17:33:04-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":54,"like_count":12,"has_best_of":false,"archetype":"regular","category_id":2,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":5351},{"extras":null,"description":"Most Posts","user_id":32}]},{"id":7051,"title":"Image upload fails silently","fancy_title":"Image upload fails silently","slug":"image-upload-fails-silently","posts_count":5,"reply_count":2,"highest_post_number":5,"image_url":null,"created_at":"2013-05-31T16:12:56-04:00","last_posted_at":"2013-07-23T16:50:31-04:00","bumped":true,"bumped_at":"2013-07-23T16:50:31-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":129,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":3062},{"extras":null,"description":"Most Posts","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":6208},{"extras":"latest","description":"Most Recent Poster","user_id":1995}]},{"id":8609,"title":"New: Attachments!","fancy_title":"New: Attachments!","slug":"new-attachments","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2013-07-23T16:43:25-04:00","last_posted_at":"2013-07-23T16:43:25-04:00","bumped":false,"bumped_at":"2013-07-23T16:43:25-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":54,"like_count":8,"has_best_of":false,"archetype":"regular","category_id":2,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":1995}]},{"id":8605,"title":"Not finding any client translations","fancy_title":"Not finding any client translations","slug":"not-finding-any-client-translations","posts_count":5,"reply_count":2,"highest_post_number":5,"image_url":null,"created_at":"2013-07-23T14:15:08-04:00","last_posted_at":"2013-07-23T15:59:52-04:00","bumped":true,"bumped_at":"2013-07-23T15:59:52-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":34,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":7,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":2876},{"extras":null,"description":"Most Posts","user_id":19}]},{"id":8608,"title":"Upgrading to 0.9.5 bitnami installer on ec2","fancy_title":"Upgrading to 0.9.5 bitnami installer on ec2","slug":"upgrading-to-0-9-5-bitnami-installer-on-ec2","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2013-07-23T15:46:51-04:00","last_posted_at":"2013-07-23T15:46:51-04:00","bumped":false,"bumped_at":"2013-07-23T15:46:51-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":27,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":6,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":5171}]},{"id":5564,"title":"Gravatar, Wordpress.com accounts, and custom avatars","fancy_title":"Gravatar, Wordpress.com accounts, and custom avatars","slug":"gravatar-wordpress-com-accounts-and-custom-avatars","posts_count":17,"reply_count":13,"highest_post_number":19,"image_url":null,"created_at":"2013-04-03T12:25:51-04:00","last_posted_at":"2013-07-23T15:45:32-04:00","bumped":true,"bumped_at":"2013-07-23T15:45:32-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":505,"like_count":47,"has_best_of":false,"archetype":"regular","category_id":2,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":2876},{"extras":null,"description":"Most Posts","user_id":38},{"extras":null,"description":"Frequent Poster","user_id":3192},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":5270}]},{"id":8600,"title":"Modal when deleting post not disappearing","fancy_title":"Modal when deleting post not disappearing","slug":"modal-when-deleting-post-not-disappearing","posts_count":5,"reply_count":0,"highest_post_number":5,"image_url":null,"created_at":"2013-07-23T11:20:35-04:00","last_posted_at":"2013-07-23T15:24:36-04:00","bumped":true,"bumped_at":"2013-07-23T15:24:32-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":true,"views":36,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":3987},{"extras":null,"description":"Most Posts","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":19}]},{"id":8601,"title":"How are search results being ordered?","fancy_title":"How are search results being ordered?","slug":"how-are-search-results-being-ordered","posts_count":3,"reply_count":1,"highest_post_number":3,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1482/99e83823f868b58d.png","created_at":"2013-07-23T12:12:45-04:00","last_posted_at":"2013-07-23T15:14:13-04:00","bumped":true,"bumped_at":"2013-07-23T15:14:13-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":47,"like_count":1,"has_best_of":false,"archetype":"regular","category_id":9,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":5113},{"extras":null,"description":"Most Posts","user_id":32}]},{"id":8594,"title":"Restoring a category","fancy_title":"Restoring a category","slug":"restoring-a-category","posts_count":4,"reply_count":2,"highest_post_number":4,"image_url":null,"created_at":"2013-07-23T10:14:07-04:00","last_posted_at":"2013-07-23T14:02:24-04:00","bumped":true,"bumped_at":"2013-07-23T14:02:24-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":49,"like_count":1,"has_best_of":false,"archetype":"regular","category_id":6,"posters":[{"extras":null,"description":"Original Poster","user_id":3986},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":8603,"title":"Creating a new project, would love to share the users database between discourse and main app","fancy_title":"Creating a new project, would love to share the users database between discourse and main app","slug":"creating-a-new-project-would-love-to-share-the-users-database-between-discourse-and-main-app","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2013-07-23T13:32:26-04:00","last_posted_at":"2013-07-23T13:32:27-04:00","bumped":true,"bumped_at":"2013-07-23T13:32:27-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":34,"like_count":2,"has_best_of":false,"archetype":"regular","category_id":6,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":6218}]},{"id":6731,"title":"Can't delete a user if a deleted topic exists","fancy_title":"Can’t delete a user if a deleted topic exists","slug":"cant-delete-a-user-if-a-deleted-topic-exists","posts_count":3,"reply_count":0,"highest_post_number":3,"image_url":null,"created_at":"2013-05-20T07:22:51-04:00","last_posted_at":"2013-07-23T14:32:03-04:00","bumped":true,"bumped_at":"2013-07-23T12:19:42-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":true,"views":127,"like_count":5,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":3987},{"extras":"latest","description":"Most Recent Poster","user_id":2}]}]}}; Discourse.URL_FIXTURES["/categories.json"] = {"featured_users":[{"id":32,"username":"codinghorror","avatar_template":"https://www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon"},{"id":1,"username":"sam","avatar_template":"https://www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon"},{"id":5351,"username":"erlend_sh","avatar_template":"https://www.gravatar.com/avatar/69fda0df8b4878fb6a18deffa972d26a.png?s={size}&r=pg&d=identicon"},{"id":1353,"username":"sparr","avatar_template":"https://www.gravatar.com/avatar/7906663b1197829751673465948e0b05.png?s={size}&r=pg&d=identicon"},{"id":1995,"username":"zogstrip","avatar_template":"https://www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon"},{"id":19,"username":"eviltrout","avatar_template":"https://www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon"},{"id":2,"username":"Neil","avatar_template":"https://www.gravatar.com/avatar/42776c4982dff1fa45ee8248532f8ad0.png?s={size}&r=pg&d=identicon"},{"id":2600,"username":"NinjaFoodstuff","avatar_template":"https://www.gravatar.com/avatar/3709f34da1ff5433b41bc56df94dd453.png?s={size}&r=pg&d=identicon"},{"id":406,"username":"RGJ","avatar_template":"https://www.gravatar.com/avatar/55c791f0242e5167536c65496046eef5.png?s={size}&r=pg&d=identicon"},{"id":1263,"username":"ChrisB","avatar_template":"https://www.gravatar.com/avatar/1d75aba12b3961894f93959b5b013de0.png?s={size}&r=pg&d=identicon"},{"id":3,"username":"supermathie","avatar_template":"https://www.gravatar.com/avatar/44ae1b2d44d48aed3d432129a5703942.png?s={size}&r=pg&d=identicon"},{"id":1274,"username":"binaryphile","avatar_template":"https://www.gravatar.com/avatar/82564a08aebae1de68bea8e3df61ef93.png?s={size}&r=pg&d=identicon"},{"id":714,"username":"jcolebrand","avatar_template":"https://www.gravatar.com/avatar/c4cca9bfec5d5e77f625d9fbe8e37a41.png?s={size}&r=pg&d=identicon"},{"id":810,"username":"ChrisHanel","avatar_template":"https://www.gravatar.com/avatar/467863a322e1a3ce557bfd17f4677600.png?s={size}&r=pg&d=identicon"},{"id":4,"username":"stienman","avatar_template":"https://www.gravatar.com/avatar/281486f2a20201375414760dd347951d.png?s={size}&r=pg&d=identicon"},{"id":4263,"username":"mcwumbly","avatar_template":"https://www.gravatar.com/avatar/e217128117fe24525c7af5ebc5e45745.png?s={size}&r=pg&d=identicon"},{"id":2465,"username":"finid","avatar_template":"https://www.gravatar.com/avatar/989a7705a77732d888ddaff8b440fc3d.png?s={size}&r=pg&d=identicon"},{"id":2839,"username":"baus","avatar_template":"https://www.gravatar.com/avatar/57d4030570f672f515a7385cc74c8cfe.png?s={size}&r=pg&d=identicon"},{"id":2664,"username":"Odd_Bloke","avatar_template":"https://www.gravatar.com/avatar/af881deb1a7ef0a1f568e18cd967c0d3.png?s={size}&r=pg&d=identicon"},{"id":38,"username":"frandallfarmer","avatar_template":"https://www.gravatar.com/avatar/6c38e00d92cd9bd3ada3392b15015553.png?s={size}&r=pg&d=identicon"},{"id":2128,"username":"ultimape","avatar_template":"https://www.gravatar.com/avatar/6fe82efded2ee5e218e0452644a07e2e.png?s={size}&r=pg&d=identicon"},{"id":811,"username":"jpeg","avatar_template":"https://www.gravatar.com/avatar/4a214d4a12b7223b61ec36c7aa224c97.png?s={size}&r=pg&d=identicon"},{"id":2291,"username":"PabloC","avatar_template":"https://www.gravatar.com/avatar/82c793022ec1bce6ea7573bc27b2340b.png?s={size}&r=pg&d=identicon"},{"id":1674,"username":"colin","avatar_template":"https://www.gravatar.com/avatar/4cfb483116a822652d698dce303ec842.png?s={size}&r=pg&d=identicon"},{"id":2981,"username":"ian_carroll","avatar_template":"https://www.gravatar.com/avatar/76dd5343c6a95d7b2ce906fb9af94106.png?s={size}&r=pg&d=identicon"},{"id":5468,"username":"pixelBender67","avatar_template":"https://www.gravatar.com/avatar/4f4cc88cc2ebd747240c7bc53af99261.png?s={size}&r=pg&d=identicon"},{"id":4217,"username":"mshappe","avatar_template":"https://www.gravatar.com/avatar/36ffc752906110cd16e1746d5c95516f.png?s={size}&r=pg&d=identicon"},{"id":4939,"username":"stevebaer","avatar_template":"https://www.gravatar.com/avatar/7a42855912a58f4c3c5d0ce82e33905f.png?s={size}&r=pg&d=identicon"},{"id":3507,"username":"mozCallahad","avatar_template":"https://www.gravatar.com/avatar/a2746e0bf42c3245bfd80dea9b3efb32.png?s={size}&r=pg&d=identicon"},{"id":5460,"username":"ned","avatar_template":"https://www.gravatar.com/avatar/bc5e09a5ce0a85bf02a3fceb9b0bfaf4.png?s={size}&r=pg&d=identicon"},{"id":704,"username":"AstonJ","avatar_template":"https://www.gravatar.com/avatar/03af361cc843bc56e95cb6c406d06f80.png?s={size}&r=pg&d=identicon"},{"id":461,"username":"kuba","avatar_template":"https://www.gravatar.com/avatar/1835cb6a5f35bd4089e416a99af90f5f.png?s={size}&r=pg&d=identicon"},{"id":1566,"username":"hamburglar","avatar_template":"https://www.gravatar.com/avatar/57b39f59fa025f64e173ba6dffb8f2f7.png?s={size}&r=pg&d=identicon"}],"category_list":{"can_create_category":false,"can_create_topic":false,"draft":null,"draft_key":"new_topic","draft_sequence":null,"categories":[{"id":2,"name":"feature","color":"0E76BD","text_color":"FFFFFF","slug":"feature","topic_count":467,"topics_week":19,"topics_month":80,"topics_year":465,"description":"Discussion about features or potential features of Discourse: how they work, why they work, etc.","description_excerpt":"Discussion about features or potential features of Discourse: how they work, why they work, etc.","featured_user_ids":[32,1,5351,1353,1995],"topics":[{"id":8618,"title":"Not all mods to be staff memebers","fancy_title":"Not all mods to be staff memebers","slug":"not-all-mods-to-be-staff-memebers","posts_count":4,"reply_count":2,"highest_post_number":4,"image_url":null,"created_at":"2013-07-24T06:17:00-04:00","last_posted_at":"2013-07-24T08:24:44-04:00","bumped":true,"bumped_at":"2013-07-24T08:24:44-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":8615,"title":"Filtering out out-of-office-replies in the reply-by-mail feature","fancy_title":"Filtering out out-of-office-replies in the reply-by-mail feature","slug":"filtering-out-out-of-office-replies-in-the-reply-by-mail-feature","posts_count":3,"reply_count":0,"highest_post_number":3,"image_url":null,"created_at":"2013-07-24T04:40:43-04:00","last_posted_at":"2013-07-24T08:15:18-04:00","bumped":true,"bumped_at":"2013-07-24T08:15:18-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":8342,"title":"Dropping the statistical stuff","fancy_title":"Dropping the statistical stuff","slug":"dropping-the-statistical-stuff","posts_count":17,"reply_count":9,"highest_post_number":17,"image_url":null,"created_at":"2013-07-13T03:19:58-04:00","last_posted_at":"2013-07-24T03:11:18-04:00","bumped":true,"bumped_at":"2013-07-24T03:11:18-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":7764,"title":"New: Reply via Email Support!","fancy_title":"New: Reply via Email Support!","slug":"new-reply-via-email-support","posts_count":19,"reply_count":12,"highest_post_number":19,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1227/8f4e5818dfaa56c7.png","created_at":"2013-06-25T11:58:39-04:00","last_posted_at":"2013-07-24T01:56:23-04:00","bumped":true,"bumped_at":"2013-07-24T01:56:23-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":8564,"title":"Improvements to self-deleted posts","fancy_title":"Improvements to self-deleted posts","slug":"improvements-to-self-deleted-posts","posts_count":10,"reply_count":8,"highest_post_number":10,"image_url":null,"created_at":"2013-07-22T04:48:55-04:00","last_posted_at":"2013-07-24T01:54:46-04:00","bumped":true,"bumped_at":"2013-07-24T01:54:46-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":8168,"title":"Audio html5 tag","fancy_title":"Audio html5 tag","slug":"audio-html5-tag","posts_count":6,"reply_count":2,"highest_post_number":6,"image_url":null,"created_at":"2013-07-07T11:48:25-04:00","last_posted_at":"2013-07-24T00:47:42-04:00","bumped":true,"bumped_at":"2013-07-24T00:47:42-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false}]},{"id":1,"name":"bug","color":"ae3a27","text_color":"FFFFFF","slug":"bug","topic_count":442,"topics_week":17,"topics_month":81,"topics_year":442,"description":"Bug reports on Discourse. Do be sure to search prior to submitting bugs. Include repro steps, and only describe one bug per topic please.","description_excerpt":"Bug reports on Discourse. Do be sure to search prior to submitting bugs. Include repro steps, and only describe one bug per topic please.","featured_user_ids":[32,1,1995,19,2],"topics":[{"id":7288,"title":"Digest mail ignores secure groups","fancy_title":"Digest mail ignores secure groups","slug":"digest-mail-ignores-secure-groups","posts_count":7,"reply_count":3,"highest_post_number":7,"image_url":"http://cdn.discourse.org/assets/emoji/smile.png","created_at":"2013-06-08T08:54:12-04:00","last_posted_at":"2013-06-08T13:00:38-04:00","bumped":true,"bumped_at":"2013-06-08T13:00:38-04:00","unseen":false,"pinned":true,"excerpt":"People receiving the digest mail can easily read posts not meant for them. That's because the digest mail ignores the secure groups a member has access to or not. \n\nQuite a problem as I unfortunately found out. [smile]","visible":true,"closed":false,"archived":false},{"id":8198,"title":"Unable to create group","fancy_title":"Unable to create group","slug":"unable-to-create-group","posts_count":12,"reply_count":6,"highest_post_number":12,"image_url":null,"created_at":"2013-07-08T13:58:49-04:00","last_posted_at":"2013-07-24T09:22:00-04:00","bumped":true,"bumped_at":"2013-07-24T09:22:00-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":8542,"title":"Add user to filter when explicitly requesting their post","fancy_title":"Add user to filter when explicitly requesting their post","slug":"add-user-to-filter-when-explicitly-requesting-their-post","posts_count":3,"reply_count":1,"highest_post_number":3,"image_url":null,"created_at":"2013-07-21T04:43:39-04:00","last_posted_at":"2013-07-23T22:17:30-04:00","bumped":true,"bumped_at":"2013-07-23T22:17:30-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":7051,"title":"Image upload fails silently","fancy_title":"Image upload fails silently","slug":"image-upload-fails-silently","posts_count":5,"reply_count":2,"highest_post_number":5,"image_url":null,"created_at":"2013-05-31T16:12:56-04:00","last_posted_at":"2013-07-23T16:50:31-04:00","bumped":true,"bumped_at":"2013-07-23T16:50:31-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":8600,"title":"Modal when deleting post not disappearing","fancy_title":"Modal when deleting post not disappearing","slug":"modal-when-deleting-post-not-disappearing","posts_count":5,"reply_count":0,"highest_post_number":5,"image_url":null,"created_at":"2013-07-23T11:20:35-04:00","last_posted_at":"2013-07-23T15:24:36-04:00","bumped":true,"bumped_at":"2013-07-23T15:24:32-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":true},{"id":6731,"title":"Can't delete a user if a deleted topic exists","fancy_title":"Can’t delete a user if a deleted topic exists","slug":"cant-delete-a-user-if-a-deleted-topic-exists","posts_count":3,"reply_count":0,"highest_post_number":3,"image_url":null,"created_at":"2013-05-20T07:22:51-04:00","last_posted_at":"2013-07-23T14:32:03-04:00","bumped":true,"bumped_at":"2013-07-23T12:19:42-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":true}]},{"id":6,"name":"support","color":"b99","text_color":"FFFFFF","slug":"support","topic_count":374,"topics_week":12,"topics_month":67,"topics_year":374,"description":"Support on configuring, using, and installing Discourse. Not for software development related topics, but for admins and end users configuring and using Discourse.","description_excerpt":"Support on configuring, using, and installing Discourse. Not for software development related topics, but for admins and end users configuring and using Discourse.","featured_user_ids":[32,1,2,2600,406],"topics":[{"id":7802,"title":"Wrong displayed create time","fancy_title":"Wrong displayed create time","slug":"wrong-displayed-create-time","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1250/463c47397726e0a9.png","created_at":"2013-06-27T12:00:05-04:00","last_posted_at":"2013-07-24T08:25:35-04:00","bumped":true,"bumped_at":"2013-07-24T08:25:35-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":8610,"title":"I want to translate and RTL this forum system","fancy_title":"I want to translate and RTL this forum system","slug":"i-want-to-translate-and-rtl-this-forum-system","posts_count":4,"reply_count":2,"highest_post_number":4,"image_url":null,"created_at":"2013-07-23T18:17:39-04:00","last_posted_at":"2013-07-23T20:57:40-04:00","bumped":true,"bumped_at":"2013-07-23T20:57:40-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":8608,"title":"Upgrading to 0.9.5 bitnami installer on ec2","fancy_title":"Upgrading to 0.9.5 bitnami installer on ec2","slug":"upgrading-to-0-9-5-bitnami-installer-on-ec2","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2013-07-23T15:46:51-04:00","last_posted_at":"2013-07-23T15:46:51-04:00","bumped":false,"bumped_at":"2013-07-23T15:46:51-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":8594,"title":"Restoring a category","fancy_title":"Restoring a category","slug":"restoring-a-category","posts_count":4,"reply_count":2,"highest_post_number":4,"image_url":null,"created_at":"2013-07-23T10:14:07-04:00","last_posted_at":"2013-07-23T14:02:24-04:00","bumped":true,"bumped_at":"2013-07-23T14:02:24-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":8603,"title":"Creating a new project, would love to share the users database between discourse and main app","fancy_title":"Creating a new project, would love to share the users database between discourse and main app","slug":"creating-a-new-project-would-love-to-share-the-users-database-between-discourse-and-main-app","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2013-07-23T13:32:26-04:00","last_posted_at":"2013-07-23T13:32:27-04:00","bumped":true,"bumped_at":"2013-07-23T13:32:27-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":8583,"title":"How to remove/uninstall Discourse?","fancy_title":"How to remove/uninstall Discourse?","slug":"how-to-remove-uninstall-discourse","posts_count":6,"reply_count":3,"highest_post_number":6,"image_url":null,"created_at":"2013-07-22T19:06:51-04:00","last_posted_at":"2013-07-23T09:49:02-04:00","bumped":true,"bumped_at":"2013-07-23T09:49:02-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false}]},{"id":9,"name":"ux","color":"5F497A","text_color":"FFFFFF","slug":"ux","topic_count":112,"topics_week":8,"topics_month":16,"topics_year":112,"description":"Discussion about the user interface of Discourse, how features are presented to the user in the client, including language and UI elements.","description_excerpt":"Discussion about the user interface of Discourse, how features are presented to the user in the client, including language and UI elements.","featured_user_ids":[32,1,406,1263,3],"topics":[{"id":8613,"title":"Add branching text when posts moved to a new topic","fancy_title":"Add branching text when posts moved to a new topic","slug":"add-branching-text-when-posts-moved-to-a-new-topic","posts_count":4,"reply_count":0,"highest_post_number":4,"image_url":"http://cdn.discourse.org/assets/emoji/grin.png","created_at":"2013-07-23T22:31:39-04:00","last_posted_at":"2013-07-24T02:47:22-04:00","bumped":true,"bumped_at":"2013-07-24T02:47:22-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":8601,"title":"How are search results being ordered?","fancy_title":"How are search results being ordered?","slug":"how-are-search-results-being-ordered","posts_count":3,"reply_count":1,"highest_post_number":3,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1482/99e83823f868b58d.png","created_at":"2013-07-23T12:12:45-04:00","last_posted_at":"2013-07-23T15:14:13-04:00","bumped":true,"bumped_at":"2013-07-23T15:14:13-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":8597,"title":"Support category badge looks like an archived post","fancy_title":"Support category badge looks like an archived post","slug":"support-category-badge-looks-like-an-archived-post","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/_optimized/ced/58f/787dc3871c0_690x107.png","created_at":"2013-07-23T10:30:00-04:00","last_posted_at":"2013-07-23T10:30:00-04:00","bumped":false,"bumped_at":"2013-07-23T10:30:00-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":8552,"title":"Dealing With High Category Count: Reducing Noise & Increasing Discoverability","fancy_title":"Dealing With High Category Count: Reducing Noise & Increasing Discoverability","slug":"dealing-with-high-category-count-reducing-noise-increasing-discoverability","posts_count":4,"reply_count":0,"highest_post_number":4,"image_url":null,"created_at":"2013-07-21T12:05:24-04:00","last_posted_at":"2013-07-22T08:53:00-04:00","bumped":true,"bumped_at":"2013-07-22T08:53:00-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":6252,"title":"Going back to profile activity page should remember filter and scrolling location","fancy_title":"Going back to profile activity page should remember filter and scrolling location","slug":"going-back-to-profile-activity-page-should-remember-filter-and-scrolling-location","posts_count":3,"reply_count":0,"highest_post_number":3,"image_url":null,"created_at":"2013-04-30T11:11:08-04:00","last_posted_at":"2013-07-22T03:29:07-04:00","bumped":true,"bumped_at":"2013-07-22T03:29:07-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":8543,"title":"\"Upload file\" doesn't upload a file from the web (i.e. rehost)","fancy_title":"“Upload file” doesn’t upload a file from the web (i.e. rehost)","slug":"upload-file-doesnt-upload-a-file-from-the-web-i-e-rehost","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1458/f953490a46d2ef8f.png","created_at":"2013-07-21T05:02:25-04:00","last_posted_at":"2013-07-21T05:02:25-04:00","bumped":false,"bumped_at":"2013-07-21T05:02:25-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false}]},{"id":7,"name":"dev","color":"000","text_color":"FFFFFF","slug":"dev","topic_count":183,"topics_week":5,"topics_month":18,"topics_year":183,"description":"This category is for topics related to hacking on Discourse: submitting pull requests, configuring development environments, coding conventions, and so forth.","description_excerpt":"This category is for topics related to hacking on Discourse: submitting pull requests, configuring development environments, coding conventions, and so forth.","featured_user_ids":[1,32,19,1995,1274],"topics":[{"id":3823,"title":"So, you want to help out with Discourse","fancy_title":"So, you want to help out with Discourse","slug":"so-you-want-to-help-out-with-discourse","posts_count":24,"reply_count":21,"highest_post_number":42,"image_url":null,"created_at":"2013-02-23T00:46:11-05:00","last_posted_at":"2013-07-17T19:44:06-04:00","bumped":true,"bumped_at":"2013-07-17T19:44:06-04:00","unseen":false,"pinned":true,"excerpt":"People are wondering, how it is they can help out with Discourse. \n\nWe have seen some chattering both here and on Github. \n\nI wanted to create a topic @eviltrout , @codinghorror and myself can keep up to date with clear…","visible":true,"closed":false,"archived":false},{"id":8605,"title":"Not finding any client translations","fancy_title":"Not finding any client translations","slug":"not-finding-any-client-translations","posts_count":5,"reply_count":2,"highest_post_number":5,"image_url":null,"created_at":"2013-07-23T14:15:08-04:00","last_posted_at":"2013-07-23T15:59:52-04:00","bumped":true,"bumped_at":"2013-07-23T15:59:52-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":4046,"title":"When should we upgrade to Rails 4?","fancy_title":"When should we upgrade to Rails 4?","slug":"when-should-we-upgrade-to-rails-4","posts_count":36,"reply_count":17,"highest_post_number":37,"image_url":null,"created_at":"2013-02-25T19:51:20-05:00","last_posted_at":"2013-07-23T04:12:17-04:00","bumped":true,"bumped_at":"2013-07-23T04:12:17-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":7763,"title":"Translation Tools: Transifex? Localeapp?","fancy_title":"Translation Tools: Transifex? Localeapp?","slug":"translation-tools-transifex-localeapp","posts_count":23,"reply_count":13,"highest_post_number":23,"image_url":null,"created_at":"2013-06-25T11:54:53-04:00","last_posted_at":"2013-07-22T18:10:36-04:00","bumped":true,"bumped_at":"2013-07-22T18:10:36-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":8393,"title":"Brazilian Portuguese translation","fancy_title":"Brazilian Portuguese translation","slug":"brazilian-portuguese-translation","posts_count":18,"reply_count":14,"highest_post_number":18,"image_url":null,"created_at":"2013-07-15T13:56:34-04:00","last_posted_at":"2013-07-22T11:43:56-04:00","bumped":true,"bumped_at":"2013-07-22T11:43:56-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":8363,"title":"Translators need a way to contribute localized username reservations","fancy_title":"Translators need a way to contribute localized username reservations","slug":"translators-need-a-way-to-contribute-localized-username-reservations","posts_count":7,"reply_count":3,"highest_post_number":7,"image_url":null,"created_at":"2013-07-14T11:19:28-04:00","last_posted_at":"2013-07-22T11:17:22-04:00","bumped":true,"bumped_at":"2013-07-22T11:17:22-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false}]},{"id":5,"name":"extensibility ","color":"FE8432","text_color":"FFFFFF","slug":"extensibility","topic_count":37,"topics_week":3,"topics_month":9,"topics_year":37,"description":"Topics about extending the functionality of Discourse with plugins, themes, add-ons, or other mechanisms for extensibility. ","description_excerpt":"Topics about extending the functionality of Discourse with plugins, themes, add-ons, or other mechanisms for extensibility.","featured_user_ids":[1,32,714,5351,810],"topics":[{"id":7464,"title":"CSS documentation?","fancy_title":"CSS documentation?","slug":"css-documentation","posts_count":3,"reply_count":1,"highest_post_number":3,"image_url":null,"created_at":"2013-06-13T18:25:19-04:00","last_posted_at":"2013-07-24T02:21:38-04:00","bumped":true,"bumped_at":"2013-07-24T06:57:54-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":31,"title":"What is the most awesome plugin for Discourse, that does not yet exist?","fancy_title":"What is the most awesome plugin for Discourse, that does not yet exist?","slug":"what-is-the-most-awesome-plugin-for-discourse-that-does-not-yet-exist","posts_count":164,"reply_count":115,"highest_post_number":170,"image_url":null,"created_at":"2013-02-03T06:43:18-05:00","last_posted_at":"2013-07-24T03:54:47-04:00","bumped":true,"bumped_at":"2013-07-24T03:54:47-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":8567,"title":"SSO Between Discourse and XMPP","fancy_title":"SSO Between Discourse and XMPP","slug":"sso-between-discourse-and-xmpp","posts_count":7,"reply_count":3,"highest_post_number":7,"image_url":null,"created_at":"2013-07-22T11:10:25-04:00","last_posted_at":"2013-07-22T21:40:34-04:00","bumped":true,"bumped_at":"2013-07-22T21:40:34-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":8578,"title":"Integrating Discourse with a knowledge base","fancy_title":"Integrating Discourse with a knowledge base","slug":"integrating-discourse-with-a-knowledge-base","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2013-07-22T17:03:42-04:00","last_posted_at":"2013-07-22T17:03:42-04:00","bumped":false,"bumped_at":"2013-07-22T17:03:42-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":531,"title":"Discourse and Wordpress Integration","fancy_title":"Discourse and Wordpress Integration","slug":"discourse-and-wordpress-integration","posts_count":65,"reply_count":55,"highest_post_number":67,"image_url":null,"created_at":"2013-02-05T18:56:37-05:00","last_posted_at":"2013-07-20T06:52:01-04:00","bumped":true,"bumped_at":"2013-07-20T06:52:01-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":8473,"title":"Plugin: The Konami Code","fancy_title":"Plugin: The Konami Code","slug":"plugin-the-konami-code","posts_count":5,"reply_count":0,"highest_post_number":5,"image_url":null,"created_at":"2013-07-18T11:53:04-04:00","last_posted_at":"2013-07-18T16:24:33-04:00","bumped":true,"bumped_at":"2013-07-18T16:24:33-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false}]},{"id":4,"name":"faq","color":"33b","text_color":"FFFFFF","slug":"faq","topic_count":41,"topics_week":2,"topics_month":3,"topics_year":41,"description":"Topics that come up very often when discussing Discourse will eventually be classified into this Frequently Asked Questions category. Should only be added to popular topics.","description_excerpt":"Topics that come up very often when discussing Discourse will eventually be classified into this Frequently Asked Questions category. Should only be added to popular topics.","featured_user_ids":[32,1,4,4263,2465],"topics":[{"id":8606,"title":"Latest vs. New vs. Unread","fancy_title":"Latest vs. New vs. Unread","slug":"latest-vs-new-vs-unread","posts_count":11,"reply_count":8,"highest_post_number":11,"image_url":null,"created_at":"2013-07-23T15:10:56-04:00","last_posted_at":"2013-07-24T09:35:48-04:00","bumped":true,"bumped_at":"2013-07-24T09:35:48-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":8458,"title":"What editor does Discourse use for CSS manipulation?","fancy_title":"What editor does Discourse use for CSS manipulation?","slug":"what-editor-does-discourse-use-for-css-manipulation","posts_count":3,"reply_count":1,"highest_post_number":3,"image_url":null,"created_at":"2013-07-18T05:52:38-04:00","last_posted_at":"2013-07-18T06:51:44-04:00","bumped":true,"bumped_at":"2013-07-18T06:51:44-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":7755,"title":"What do the dates on the bottom of the categories page mean?","fancy_title":"What do the dates on the bottom of the categories page mean?","slug":"what-do-the-dates-on-the-bottom-of-the-categories-page-mean","posts_count":7,"reply_count":5,"highest_post_number":7,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1218/87b3b53c9641c86e.jpeg","created_at":"2013-06-25T04:24:56-04:00","last_posted_at":"2013-07-02T00:08:41-04:00","bumped":true,"bumped_at":"2013-07-02T00:08:41-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":866,"title":"UX confusion - why sometimes I see \"x reply(s) below\" and sometimes I don't","fancy_title":"UX confusion - why sometimes I see “x reply(s) below” and sometimes I don’t","slug":"ux-confusion-why-sometimes-i-see-x-reply-s-below-and-sometimes-i-dont","posts_count":5,"reply_count":3,"highest_post_number":5,"image_url":null,"created_at":"2013-02-06T00:31:46-05:00","last_posted_at":"2013-06-25T23:34:34-04:00","bumped":true,"bumped_at":"2013-06-25T23:34:34-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":2408,"title":"Private Discourse Forum","fancy_title":"Private Discourse Forum","slug":"private-discourse-forum","posts_count":18,"reply_count":10,"highest_post_number":18,"image_url":null,"created_at":"2013-02-08T08:25:22-05:00","last_posted_at":"2013-06-20T17:45:35-04:00","bumped":true,"bumped_at":"2013-06-20T17:47:47-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":6724,"title":"Where is this development roadmap?","fancy_title":"Where is this development roadmap?","slug":"where-is-this-development-roadmap","posts_count":12,"reply_count":8,"highest_post_number":12,"image_url":null,"created_at":"2013-05-19T15:15:19-04:00","last_posted_at":"2013-06-17T11:03:07-04:00","bumped":true,"bumped_at":"2013-06-17T11:03:07-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false}]},{"id":null,"name":"uncategorized","color":"AB9364","text_color":"FFFFFF","slug":"uncategorized","topic_count":187,"topics_week":1,"topics_month":13,"topics_year":187,"description":null,"description_excerpt":null,"is_uncategorized":true,"featured_user_ids":[],"topics":[{"id":8604,"title":"Hide sensitive site settings","fancy_title":"Hide sensitive site settings","slug":"hide-sensitive-site-settings","posts_count":5,"reply_count":2,"highest_post_number":5,"image_url":null,"created_at":"2013-07-23T13:51:07-04:00","last_posted_at":"2013-07-23T19:15:26-04:00","bumped":true,"bumped_at":"2013-07-23T19:15:26-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":7501,"title":"Discourse not working on Opera Mini","fancy_title":"Discourse not working on Opera Mini","slug":"discourse-not-working-on-opera-mini","posts_count":5,"reply_count":3,"highest_post_number":5,"image_url":null,"created_at":"2013-06-15T05:45:39-04:00","last_posted_at":"2013-07-23T10:21:01-04:00","bumped":true,"bumped_at":"2013-07-23T10:21:01-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":7318,"title":"Where can we discuss the Markdown spec?","fancy_title":"Where can we discuss the Markdown spec?","slug":"where-can-we-discuss-the-markdown-spec","posts_count":4,"reply_count":1,"highest_post_number":4,"image_url":"https://www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s=40&r=pg&d=identicon","created_at":"2013-06-09T04:23:28-04:00","last_posted_at":"2013-07-20T07:48:29-04:00","bumped":true,"bumped_at":"2013-07-20T07:48:29-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":4483,"title":"Why was the Popular page chosen as the landing page?","fancy_title":"Why was the Popular page chosen as the landing page?","slug":"why-was-the-popular-page-chosen-as-the-landing-page","posts_count":11,"reply_count":6,"highest_post_number":11,"image_url":null,"created_at":"2013-03-05T16:44:52-05:00","last_posted_at":"2013-07-20T07:07:06-04:00","bumped":true,"bumped_at":"2013-07-20T07:07:06-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":724,"title":"Libelous quote-to-reply","fancy_title":"Libelous quote-to-reply","slug":"libelous-quote-to-reply","posts_count":12,"reply_count":9,"highest_post_number":12,"image_url":"http://www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s=40&r=pg&d=identicon","created_at":"2013-02-05T21:20:36-05:00","last_posted_at":"2013-07-18T17:52:42-04:00","bumped":true,"bumped_at":"2013-07-18T17:52:42-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":8443,"title":"Using Discourse as a base for a Social Network? Am I crazy?","fancy_title":"Using Discourse as a base for a Social Network? Am I crazy?","slug":"using-discourse-as-a-base-for-a-social-network-am-i-crazy","posts_count":12,"reply_count":4,"highest_post_number":12,"image_url":null,"created_at":"2013-07-17T14:27:09-04:00","last_posted_at":"2013-07-18T17:12:23-04:00","bumped":true,"bumped_at":"2013-07-18T17:19:43-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false}]},{"id":10,"name":"howto","color":"76923C","text_color":"FFFFFF","slug":"howto","topic_count":45,"topics_week":0,"topics_month":6,"topics_year":45,"description":"Tutorial topics that describe how to set up, configure, or install Discourse using a specific platform or environment.","description_excerpt":"Tutorial topics that describe how to set up, configure, or install Discourse using a specific platform or environment.","featured_user_ids":[1,2839,2600,32,2664],"topics":[{"id":6743,"title":"Bare Bones Installer Notes for cPanel Server","fancy_title":"Bare Bones Installer Notes for cPanel Server","slug":"bare-bones-installer-notes-for-cpanel-server","posts_count":5,"reply_count":3,"highest_post_number":6,"image_url":null,"created_at":"2013-05-20T15:46:37-04:00","last_posted_at":"2013-07-23T23:41:38-04:00","bumped":true,"bumped_at":"2013-07-23T23:41:38-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":4874,"title":"Multisite setup instructions","fancy_title":"Multisite setup instructions","slug":"multisite-setup-instructions","posts_count":3,"reply_count":1,"highest_post_number":3,"image_url":null,"created_at":"2013-03-18T12:18:18-04:00","last_posted_at":"2013-07-23T18:39:00-04:00","bumped":true,"bumped_at":"2013-07-23T18:39:00-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":6353,"title":"Deploy Discourse to an Ubuntu VPS using Capistrano","fancy_title":"Deploy Discourse to an Ubuntu VPS using Capistrano","slug":"deploy-discourse-to-an-ubuntu-vps-using-capistrano","posts_count":37,"reply_count":31,"highest_post_number":38,"image_url":null,"created_at":"2013-05-02T21:09:26-04:00","last_posted_at":"2013-07-15T17:38:52-04:00","bumped":true,"bumped_at":"2013-07-15T17:38:52-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":2349,"title":"Installing Discourse on Debian","fancy_title":"Installing Discourse on Debian","slug":"installing-discourse-on-debian","posts_count":94,"reply_count":69,"highest_post_number":95,"image_url":null,"created_at":"2013-02-08T02:43:23-05:00","last_posted_at":"2013-07-13T07:39:49-04:00","bumped":true,"bumped_at":"2013-07-13T07:39:49-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":8305,"title":"Git pull anytime vs after tag?","fancy_title":"Git pull anytime vs after tag?","slug":"git-pull-anytime-vs-after-tag","posts_count":4,"reply_count":2,"highest_post_number":4,"image_url":null,"created_at":"2013-07-11T17:28:50-04:00","last_posted_at":"2013-07-11T17:42:00-04:00","bumped":true,"bumped_at":"2013-07-11T17:42:00-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":7229,"title":"How to set up image uploads to S3?","fancy_title":"How to set up image uploads to S3?","slug":"how-to-set-up-image-uploads-to-s3","posts_count":8,"reply_count":6,"highest_post_number":8,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1019/782cbc7e309ce43f.png","created_at":"2013-06-06T15:37:43-04:00","last_posted_at":"2013-07-11T01:08:21-04:00","bumped":true,"bumped_at":"2013-07-11T01:08:21-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false}]},{"id":3,"name":"meta","color":"aaa","text_color":"FFFFFF","slug":"meta","topic_count":66,"topics_week":0,"topics_month":4,"topics_year":66,"description":"Discussion about meta.discourse.org itself, the organization of this forum about Discourse, how it works, and how we can improve this site.","description_excerpt":"Discussion about meta.discourse.org itself, the organization of this forum about Discourse, how it works, and how we can improve this site.","featured_user_ids":[32,1,38,2128,811],"topics":[{"id":5249,"title":"What is \"Meta\"?","fancy_title":"What is “Meta”?","slug":"what-is-meta","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":null,"created_at":"2013-03-25T18:00:52-04:00","last_posted_at":"2013-03-25T18:00:56-04:00","bumped":false,"bumped_at":"2013-03-25T18:00:52-04:00","unseen":false,"pinned":true,"excerpt":"What is "Meta"?\n\nMeta means discussion of the discussion itself instead of the actual topic of the discussion. For example, discussions about... \n\n\nThe style of discussion.\nThe participants in the discussion.\nThe setting…","visible":true,"closed":false,"archived":false},{"id":3102,"title":"Please visit our Discourse Forum! (Directory)","fancy_title":"Please visit our Discourse Forum! (Directory)","slug":"please-visit-our-discourse-forum-directory","posts_count":49,"reply_count":18,"highest_post_number":49,"image_url":null,"created_at":"2013-02-14T14:30:38-05:00","last_posted_at":"2013-07-22T18:40:59-04:00","bumped":true,"bumped_at":"2013-07-22T18:40:59-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":8364,"title":"TIL: Discourse has smart @mentions","fancy_title":"TIL: Discourse has smart @mentions","slug":"til-discourse-has-smart-mentions","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1400/bd71ba5aef5a6c07.png","created_at":"2013-07-14T11:30:10-04:00","last_posted_at":"2013-07-15T03:40:50-04:00","bumped":true,"bumped_at":"2013-07-15T03:40:50-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":3436,"title":"Using Discourse as a chat application","fancy_title":"Using Discourse as a chat application","slug":"using-discourse-as-a-chat-application","posts_count":12,"reply_count":7,"highest_post_number":12,"image_url":null,"created_at":"2013-02-19T11:34:06-05:00","last_posted_at":"2013-07-08T08:57:27-04:00","bumped":true,"bumped_at":"2013-07-08T08:57:27-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":8153,"title":"What's the best way to integrate Discours's WMD editor to my own site?","fancy_title":"What’s the best way to integrate Discours’s WMD editor to my own site?","slug":"whats-the-best-way-to-integrate-discourss-wmd-editor-to-my-own-site","posts_count":2,"reply_count":1,"highest_post_number":2,"image_url":null,"created_at":"2013-07-06T05:38:21-04:00","last_posted_at":"2013-07-06T06:12:38-04:00","bumped":true,"bumped_at":"2013-07-06T06:12:38-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":8042,"title":"Duplicated content: FAQ and Privacy appear twice!","fancy_title":"Duplicated content: FAQ and Privacy appear twice!","slug":"duplicated-content-faq-and-privacy-appear-twice","posts_count":9,"reply_count":3,"highest_post_number":9,"image_url":null,"created_at":"2013-07-02T16:06:09-04:00","last_posted_at":"2013-07-04T00:12:53-04:00","bumped":true,"bumped_at":"2013-07-03T18:55:20-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":true}]},{"id":8,"name":"hosting","color":"25AAE1","text_color":"FFFFFF","slug":"hosting","topic_count":45,"topics_week":0,"topics_month":4,"topics_year":45,"description":"Topics about hosting Discourse, either on your own servers, in the cloud, or with specific hosting services.","description_excerpt":"Topics about hosting Discourse, either on your own servers, in the cloud, or with specific hosting services.","featured_user_ids":[1,32,2291,1674,2981],"topics":[{"id":1195,"title":"Cheap Postgre / RoR hosting providers?","fancy_title":"Cheap Postgre / RoR hosting providers?","slug":"cheap-postgre-ror-hosting-providers","posts_count":46,"reply_count":30,"highest_post_number":46,"image_url":null,"created_at":"2013-02-06T07:34:58-05:00","last_posted_at":"2013-07-18T08:45:49-04:00","bumped":true,"bumped_at":"2013-07-18T08:45:49-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":6265,"title":"Discourse Hosting Proposal","fancy_title":"Discourse Hosting Proposal","slug":"discourse-hosting-proposal","posts_count":25,"reply_count":19,"highest_post_number":25,"image_url":null,"created_at":"2013-04-30T17:20:32-04:00","last_posted_at":"2013-07-18T02:22:30-04:00","bumped":true,"bumped_at":"2013-07-18T02:22:30-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":8365,"title":"DiscourseHosting.com","fancy_title":"DiscourseHosting.com","slug":"discoursehosting-com","posts_count":4,"reply_count":3,"highest_post_number":4,"image_url":null,"created_at":"2013-07-14T12:16:54-04:00","last_posted_at":"2013-07-14T14:13:32-04:00","bumped":true,"bumped_at":"2013-07-14T14:13:32-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":803,"title":"Stack Requirements for a DIY Discourse","fancy_title":"Stack Requirements for a DIY Discourse","slug":"stack-requirements-for-a-diy-discourse","posts_count":26,"reply_count":16,"highest_post_number":26,"image_url":null,"created_at":"2013-02-05T22:43:14-05:00","last_posted_at":"2013-07-12T11:47:04-04:00","bumped":true,"bumped_at":"2013-07-12T11:47:04-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":8268,"title":"List of Discourse sites","fancy_title":"List of Discourse sites","slug":"list-of-discourse-sites","posts_count":5,"reply_count":2,"highest_post_number":5,"image_url":null,"created_at":"2013-07-10T10:17:51-04:00","last_posted_at":"2013-07-10T10:32:35-04:00","bumped":true,"bumped_at":"2013-07-10T10:32:35-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":6749,"title":"On Heroku, does scheduler replace clockwork's functionality?","fancy_title":"On Heroku, does scheduler replace clockwork’s functionality?","slug":"on-heroku-does-scheduler-replace-clockworks-functionality","posts_count":2,"reply_count":1,"highest_post_number":2,"image_url":null,"created_at":"2013-05-20T20:26:05-04:00","last_posted_at":"2013-07-08T03:28:35-04:00","bumped":true,"bumped_at":"2013-07-08T03:54:16-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false}]},{"id":13,"name":"blog","color":"ED207B","text_color":"FFFFFF","slug":"blog","topic_count":9,"topics_week":0,"topics_month":2,"topics_year":9,"description":"Discussion topics generated from the official Discourse Blog. These topics are linked from the bottom of each blog entry where the blog comments would normally be.","description_excerpt":"Discussion topics generated from the official Discourse Blog. These topics are linked from the bottom of each blog entry where the blog comments would normally be.","featured_user_ids":[32,1,5468,1995,4217],"topics":[{"id":5366,"title":"Forums, As Seen On TV","fancy_title":"Forums, As Seen On TV","slug":"forums-as-seen-on-tv","posts_count":7,"reply_count":5,"highest_post_number":7,"image_url":"http://blog.discourse.org/wp-uploads/2013/03/30-rock-forums-1.jpg","created_at":"2013-03-28T16:53:41-04:00","last_posted_at":"2013-04-19T16:20:08-04:00","bumped":true,"bumped_at":"2013-07-22T08:21:22-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":7478,"title":"Discourse on Ubuntu: Video Walkthrough","fancy_title":"Discourse on Ubuntu: Video Walkthrough","slug":"discourse-on-ubuntu-video-walkthrough","posts_count":11,"reply_count":7,"highest_post_number":11,"image_url":null,"created_at":"2013-06-14T10:47:53-04:00","last_posted_at":"2013-07-20T02:59:44-04:00","bumped":true,"bumped_at":"2013-07-20T02:59:44-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":8140,"title":"Improved Image Handling","fancy_title":"Improved Image Handling","slug":"improved-image-handling","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2013-07-05T17:11:38-04:00","last_posted_at":"2013-07-05T17:11:38-04:00","bumped":true,"bumped_at":"2013-07-05T17:11:38-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":5751,"title":"Discourse as Your First Rails App","fancy_title":"Discourse as Your First Rails App","slug":"discourse-as-your-first-rails-app","posts_count":47,"reply_count":33,"highest_post_number":53,"image_url":null,"created_at":"2013-04-09T19:08:33-04:00","last_posted_at":"2013-07-03T11:49:32-04:00","bumped":true,"bumped_at":"2013-07-03T11:49:32-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":7933,"title":"Forums Are Dead, Long Live Forums","fancy_title":"Forums Are Dead, Long Live Forums","slug":"forums-are-dead-long-live-forums","posts_count":16,"reply_count":15,"highest_post_number":16,"image_url":null,"created_at":"2013-06-29T01:19:45-04:00","last_posted_at":"2013-07-01T16:19:16-04:00","bumped":true,"bumped_at":"2013-06-30T22:39:44-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":5575,"title":"Our First Partner: How-To Geek","fancy_title":"Our First Partner: How-To Geek","slug":"our-first-partner-how-to-geek","posts_count":22,"reply_count":16,"highest_post_number":23,"image_url":null,"created_at":"2013-04-03T18:42:46-04:00","last_posted_at":"2013-06-07T19:27:46-04:00","bumped":true,"bumped_at":"2013-06-07T19:27:46-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false}]},{"id":11,"name":"login","color":"edb400","text_color":"FFFFFF","slug":"login","topic_count":16,"topics_week":0,"topics_month":1,"topics_year":16,"description":"Topics about logging in to Discourse, using any standard third party provider (Twitter, Facebook, Google), traditional username and password, or with a custom plugin.","description_excerpt":"Topics about logging in to Discourse, using any standard third party provider (Twitter, Facebook, Google), traditional username and password, or with a custom plugin.","featured_user_ids":[32,2,1,4939,3507],"topics":[{"id":1420,"title":"Please add Persona as an authentication option","fancy_title":"Please add Persona as an authentication option","slug":"please-add-persona-as-an-authentication-option","posts_count":22,"reply_count":16,"highest_post_number":22,"image_url":null,"created_at":"2013-02-06T11:28:44-05:00","last_posted_at":"2013-07-01T19:51:27-04:00","bumped":true,"bumped_at":"2013-07-01T19:51:27-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":7909,"title":"OmniAuth integration documentation","fancy_title":"OmniAuth integration documentation","slug":"omniauth-integration-documentation","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2013-06-28T12:51:24-04:00","last_posted_at":"2013-06-28T12:51:24-04:00","bumped":false,"bumped_at":"2013-06-28T12:51:24-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":6869,"title":"Force use of an authentication provider","fancy_title":"Force use of an authentication provider","slug":"force-use-of-an-authentication-provider","posts_count":21,"reply_count":16,"highest_post_number":21,"image_url":null,"created_at":"2013-05-24T15:26:41-04:00","last_posted_at":"2013-06-15T16:58:09-04:00","bumped":true,"bumped_at":"2013-06-15T16:58:09-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":5800,"title":"UTF-8 to webalized char set transliteration for Facebook login","fancy_title":"UTF-8 to webalized char set transliteration for Facebook login","slug":"utf-8-to-webalized-char-set-transliteration-for-facebook-login","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2013-04-11T13:58:56-04:00","last_posted_at":"2013-04-11T13:58:56-04:00","bumped":false,"bumped_at":"2013-04-11T13:58:56-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":4011,"title":"I can't login using my password","fancy_title":"I can’t login using my password","slug":"i-can-t-login-using-my-password","posts_count":4,"reply_count":1,"highest_post_number":4,"image_url":null,"created_at":"2013-02-25T06:47:42-05:00","last_posted_at":"2013-03-13T19:36:48-04:00","bumped":true,"bumped_at":"2013-03-13T19:36:44-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":true},{"id":4738,"title":"Login support for browser password managers","fancy_title":"Login support for browser password managers","slug":"login-support-for-browser-password-managers","posts_count":5,"reply_count":2,"highest_post_number":5,"image_url":null,"created_at":"2013-03-13T17:55:29-04:00","last_posted_at":"2013-03-13T19:11:56-04:00","bumped":true,"bumped_at":"2013-03-13T19:11:56-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false}]},{"id":14,"name":"marketplace","color":"8C6238","text_color":"FFFFFF","slug":"marketplace","topic_count":5,"topics_week":0,"topics_month":1,"topics_year":5,"description":"About commercial Discourse related stuff: jobs or paid gigs, plugins, themes, hosting, etc.","description_excerpt":"About commercial Discourse related stuff: jobs or paid gigs, plugins, themes, hosting, etc.","featured_user_ids":[1263,32,406,2981,5460],"topics":[{"id":8372,"title":"I need help with Discoursed","fancy_title":"I need help with Discoursed","slug":"i-need-help-with-discoursed","posts_count":6,"reply_count":3,"highest_post_number":6,"image_url":null,"created_at":"2013-07-14T20:11:39-04:00","last_posted_at":"2013-07-17T18:00:52-04:00","bumped":true,"bumped_at":"2013-07-17T18:00:52-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":7305,"title":"I would like to hire someone to install discourse on my site","fancy_title":"I would like to hire someone to install discourse on my site","slug":"i-would-like-to-hire-someone-to-install-discourse-on-my-site","posts_count":3,"reply_count":1,"highest_post_number":3,"image_url":null,"created_at":"2013-06-08T18:32:07-04:00","last_posted_at":"2013-06-09T00:27:21-04:00","bumped":true,"bumped_at":"2013-06-09T00:27:21-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":7221,"title":"I want discourse for small business","fancy_title":"I want discourse for small business","slug":"i-want-discourse-for-small-business","posts_count":8,"reply_count":5,"highest_post_number":8,"image_url":null,"created_at":"2013-06-06T09:05:43-04:00","last_posted_at":"2013-06-06T19:52:47-04:00","bumped":true,"bumped_at":"2013-06-06T19:52:47-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":7054,"title":"Contract available: Web developer (RoR, JS, Node.JS, Discourse)","fancy_title":"Contract available: Web developer (RoR, JS, Node.JS, Discourse)","slug":"contract-available-web-developer-ror-js-node-js-discourse","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2013-05-31T19:30:52-04:00","last_posted_at":"2013-05-31T19:30:52-04:00","bumped":false,"bumped_at":"2013-05-31T19:30:52-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":5409,"title":"Looking for a Discourse specialist !!","fancy_title":"Looking for a Discourse specialist !!","slug":"looking-for-a-discourse-specialist","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2013-03-30T02:15:56-04:00","last_posted_at":"2013-03-30T02:15:56-04:00","bumped":false,"bumped_at":"2013-03-30T02:15:56-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false}]},{"id":12,"name":"discourse hub","color":"b2c79f","text_color":"FFFFFF","slug":"discourse-hub","topic_count":4,"topics_week":0,"topics_month":0,"topics_year":4,"description":"Topics about current or future Discourse Hub functionality at discourse.org including nickname registration, global user pages, and the site directory.","description_excerpt":"Topics about current or future Discourse Hub functionality at discourse.org including nickname registration, global user pages, and the site directory.","featured_user_ids":[32,2,704,461,1566],"topics":[{"id":6547,"title":"Where to get discourse_org_access_key?","fancy_title":"Where to get discourse_org_access_key?","slug":"where-to-get-discourse-org-access-key","posts_count":6,"reply_count":1,"highest_post_number":6,"image_url":null,"created_at":"2013-05-10T22:06:08-04:00","last_posted_at":"2013-06-18T11:49:18-04:00","bumped":true,"bumped_at":"2013-06-18T11:49:18-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":424,"title":"What are the 'consequences' of changing your name?","fancy_title":"What are the ‘consequences’ of changing your name?","slug":"what-are-the-consequences-of-changing-your-name","posts_count":33,"reply_count":32,"highest_post_number":33,"image_url":null,"created_at":"2013-02-05T17:37:52-05:00","last_posted_at":"2013-05-17T11:28:00-04:00","bumped":true,"bumped_at":"2013-06-12T13:22:10-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":2544,"title":"Discourse central hub questions","fancy_title":"Discourse central hub questions","slug":"discourse-central-hub-questions","posts_count":48,"reply_count":41,"highest_post_number":49,"image_url":null,"created_at":"2013-02-09T04:28:21-05:00","last_posted_at":"2013-05-28T12:15:25-04:00","bumped":true,"bumped_at":"2013-05-28T12:15:25-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false},{"id":5664,"title":"Discourse Hub nickname uniqueness not working?","fancy_title":"Discourse Hub nickname uniqueness not working?","slug":"discourse-hub-nickname-uniqueness-not-working","posts_count":22,"reply_count":16,"highest_post_number":23,"image_url":null,"created_at":"2013-04-06T03:40:11-04:00","last_posted_at":"2013-04-09T10:56:46-04:00","bumped":true,"bumped_at":"2013-04-09T10:56:46-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false}]}]}}; -Discourse.URL_FIXTURES["/category/bug/latest.json"] = {"categories":[{"id":1,"name":"bug","color":"ae3a27","text_color":"FFFFFF","slug":"bug","topic_count":442,"description":"Bug reports on Discourse. Do be sure to search prior to submitting bugs. Include repro steps, and only describe one bug per topic please.","topic_url":"/t/category-definition-for-bug/2","hotness":5.0,"read_restricted":false,"permission":null}],"users":[{"id":3987,"username":"Sander78","avatar_template":"https://www.gravatar.com/avatar/e7069beb46df22270a41afc7b277fe50.png?s={size}&r=pg&d=identicon"},{"id":1,"username":"sam","avatar_template":"https://www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon"},{"id":19,"username":"eviltrout","avatar_template":"https://www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon"},{"id":32,"username":"codinghorror","avatar_template":"https://www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon"},{"id":3681,"username":"Ajarn","avatar_template":"https://www.gravatar.com/avatar/bdfe9d9defc060d689ccd31c07e1bc19.png?s={size}&r=pg&d=identicon"},{"id":6205,"username":"senny","avatar_template":"https://www.gravatar.com/avatar/3d698e2872c07061a455d9e250861235.png?s={size}&r=pg&d=identicon"},{"id":6197,"username":"pinecone","avatar_template":"https://www.gravatar.com/avatar/a7e15f8c5bac7d8bb5a6ea7ae0eb2092.png?s={size}&r=pg&d=identicon"},{"id":3,"username":"supermathie","avatar_template":"https://www.gravatar.com/avatar/44ae1b2d44d48aed3d432129a5703942.png?s={size}&r=pg&d=identicon"},{"id":3062,"username":"Sailsman63","avatar_template":"https://www.gravatar.com/avatar/d2afe59f03e33f57760fbaacc35949d5.png?s={size}&r=pg&d=identicon"},{"id":6208,"username":"chromium_o2","avatar_template":"https://www.gravatar.com/avatar/a5d0ac66c4b8a5ac23b58b109d068a20.png?s={size}&r=pg&d=identicon"},{"id":1995,"username":"zogstrip","avatar_template":"https://www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon"},{"id":2,"username":"Neil","avatar_template":"https://www.gravatar.com/avatar/42776c4982dff1fa45ee8248532f8ad0.png?s={size}&r=pg&d=identicon"},{"id":795,"username":"mlinksva","avatar_template":"https://www.gravatar.com/avatar/7e3038f9bbba96ceb14a097e4ee128ff.png?s={size}&r=pg&d=identicon"},{"id":184,"username":"Jeremy","avatar_template":"https://www.gravatar.com/avatar/8022129f3ef00ca4f42bbd494b216310.png?s={size}&r=pg&d=identicon"},{"id":5446,"username":"expyron","avatar_template":"https://www.gravatar.com/avatar/697b750fd66f4e60779152ff1c3fc97e.png?s={size}&r=pg&d=identicon"},{"id":5546,"username":"adrianlang","avatar_template":"https://www.gravatar.com/avatar/9a38887baf481569db05e89d38bc5797.png?s={size}&r=pg&d=identicon"},{"id":5372,"username":"computerdruid","avatar_template":"https://www.gravatar.com/avatar/34c3b45c075a6d85555beb674892d0d8.png?s={size}&r=pg&d=identicon"},{"id":3932,"username":"flyingsheep","avatar_template":"https://www.gravatar.com/avatar/da56018fec1036eb1e02305d09a0bce8.png?s={size}&r=pg&d=identicon"},{"id":2287,"username":"fgonzal","avatar_template":"https://www.gravatar.com/avatar/4079bc13f142ea46e0144d1ca9426aa9.png?s={size}&r=pg&d=identicon"},{"id":761,"username":"marcoceppi","avatar_template":"https://www.gravatar.com/avatar/4ddc8924e79bcec03256821af65fca91.png?s={size}&r=pg&d=identicon"},{"id":5483,"username":"briangillespie","avatar_template":"https://www.gravatar.com/avatar/3baf9989e97ccf45aff1cf61fb730931.png?s={size}&r=pg&d=identicon"},{"id":2625,"username":"kpfleming","avatar_template":"https://www.gravatar.com/avatar/26bf5a02583eaf63d1f8063bb3a6bc00.png?s={size}&r=pg&d=identicon"},{"id":5526,"username":"geoffers747","avatar_template":"https://www.gravatar.com/avatar/fe1b6d588bfd97692f4172e41b378c09.png?s={size}&r=pg&d=identicon"},{"id":5912,"username":"jbruni","avatar_template":"https://www.gravatar.com/avatar/27dacda91150eca332526bf8a8ee7e03.png?s={size}&r=pg&d=identicon"},{"id":2933,"username":"gugalp","avatar_template":"https://www.gravatar.com/avatar/a143639f87eead196bb94bcd10380ff4.png?s={size}&r=pg&d=identicon"},{"id":5821,"username":"ven88","avatar_template":"https://www.gravatar.com/avatar/39fc4d1c6dcefe9c1ae9730f99c65af7.png?s={size}&r=pg&d=identicon"},{"id":5271,"username":"royguo","avatar_template":"https://www.gravatar.com/avatar/7e795755fe8a817981c3a81620faf359.png?s={size}&r=pg&d=identicon"},{"id":2602,"username":"georgekaplan59","avatar_template":"https://www.gravatar.com/avatar/503623c769903342cba73e722a364061.png?s={size}&r=pg&d=identicon"},{"id":6124,"username":"matthewalbone","avatar_template":"https://www.gravatar.com/avatar/82ec94bea07cd4ace35c93d8ad404917.png?s={size}&r=pg&d=identicon"},{"id":5351,"username":"erlend_sh","avatar_template":"https://www.gravatar.com/avatar/69fda0df8b4878fb6a18deffa972d26a.png?s={size}&r=pg&d=identicon"},{"id":4457,"username":"Lee_Ars","avatar_template":"https://www.gravatar.com/avatar/eff1b72d56a97459a27161ccf7f20c89.png?s={size}&r=pg&d=identicon"},{"id":4263,"username":"mcwumbly","avatar_template":"https://www.gravatar.com/avatar/e217128117fe24525c7af5ebc5e45745.png?s={size}&r=pg&d=identicon"},{"id":5477,"username":"phanimahesh","avatar_template":"https://www.gravatar.com/avatar/42ca770299eab441ddabae5a1ad5f799.png?s={size}&r=pg&d=identicon"},{"id":471,"username":"BhaelOchon","avatar_template":"https://www.gravatar.com/avatar/413ef976f0d2ca993005c9aee4769254.png?s={size}&r=pg&d=identicon"}],"topic_list":{"can_create_topic":false,"more_topics_url":"/category/bug.json?page=1","draft":null,"draft_key":"new_topic","draft_sequence":null,"topics":[{"id":7288,"title":"Digest mail ignores secure groups","fancy_title":"Digest mail ignores secure groups","slug":"digest-mail-ignores-secure-groups","posts_count":7,"reply_count":3,"highest_post_number":7,"image_url":"http://cdn.discourse.org/assets/emoji/smile.png","created_at":"2013-06-08T08:54:12-04:00","last_posted_at":"2013-06-08T13:00:38-04:00","bumped":true,"bumped_at":"2013-06-08T13:00:38-04:00","unseen":false,"pinned":true,"excerpt":"People receiving the digest mail can easily read posts not meant for them. That's because the digest mail ignores the secure groups a member has access to or not. \n\nQuite a problem as I unfortunately found out. [smile]","visible":true,"closed":false,"archived":false,"views":233,"like_count":3,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":3987},{"extras":null,"description":"Most Posts","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":19}]},{"id":2,"title":"Category definition for bug","fancy_title":"Category definition for bug","slug":"category-definition-for-bug","posts_count":2,"reply_count":0,"highest_post_number":3,"image_url":null,"created_at":"2013-01-31T23:56:34-05:00","last_posted_at":"2013-03-07T22:42:27-05:00","bumped":true,"bumped_at":"2013-02-26T18:52:56-05:00","unseen":false,"pinned":true,"excerpt":"Bug reports on Discourse. Do be sure to search prior to submitting bugs. Include repro steps, and only describe one bug per topic please.","visible":true,"closed":false,"archived":false,"views":287,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":8198,"title":"Unable to create group","fancy_title":"Unable to create group","slug":"unable-to-create-group","posts_count":12,"reply_count":6,"highest_post_number":12,"image_url":null,"created_at":"2013-07-08T13:58:49-04:00","last_posted_at":"2013-07-24T09:22:00-04:00","bumped":true,"bumped_at":"2013-07-24T09:22:00-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":139,"like_count":2,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":3681},{"extras":null,"description":"Most Posts","user_id":3987},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":6205},{"extras":"latest","description":"Most Recent Poster","user_id":6197}]},{"id":8542,"title":"Add user to filter when explicitly requesting their post","fancy_title":"Add user to filter when explicitly requesting their post","slug":"add-user-to-filter-when-explicitly-requesting-their-post","posts_count":3,"reply_count":1,"highest_post_number":3,"image_url":null,"created_at":"2013-07-21T04:43:39-04:00","last_posted_at":"2013-07-23T22:17:30-04:00","bumped":true,"bumped_at":"2013-07-23T22:17:30-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":48,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":3},{"extras":null,"description":"Most Posts","user_id":32}]},{"id":7051,"title":"Image upload fails silently","fancy_title":"Image upload fails silently","slug":"image-upload-fails-silently","posts_count":5,"reply_count":2,"highest_post_number":5,"image_url":null,"created_at":"2013-05-31T16:12:56-04:00","last_posted_at":"2013-07-23T16:50:31-04:00","bumped":true,"bumped_at":"2013-07-23T16:50:31-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":129,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":3062},{"extras":null,"description":"Most Posts","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":6208},{"extras":"latest","description":"Most Recent Poster","user_id":1995}]},{"id":8600,"title":"Modal when deleting post not disappearing","fancy_title":"Modal when deleting post not disappearing","slug":"modal-when-deleting-post-not-disappearing","posts_count":5,"reply_count":0,"highest_post_number":5,"image_url":null,"created_at":"2013-07-23T11:20:35-04:00","last_posted_at":"2013-07-23T15:24:36-04:00","bumped":true,"bumped_at":"2013-07-23T15:24:32-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":true,"views":36,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":3987},{"extras":null,"description":"Most Posts","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":19}]},{"id":6731,"title":"Can't delete a user if a deleted topic exists","fancy_title":"Can’t delete a user if a deleted topic exists","slug":"cant-delete-a-user-if-a-deleted-topic-exists","posts_count":3,"reply_count":0,"highest_post_number":3,"image_url":null,"created_at":"2013-05-20T07:22:51-04:00","last_posted_at":"2013-07-23T14:32:03-04:00","bumped":true,"bumped_at":"2013-07-23T12:19:42-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":true,"views":127,"like_count":5,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":3987},{"extras":"latest","description":"Most Recent Poster","user_id":2}]},{"id":8233,"title":"Category pages don't auto-update","fancy_title":"Category pages don’t auto-update","slug":"category-pages-dont-auto-update","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":null,"created_at":"2013-07-09T13:00:11-04:00","last_posted_at":"2013-07-23T10:26:25-04:00","bumped":true,"bumped_at":"2013-07-23T10:26:25-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":69,"like_count":2,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":3681}]},{"id":882,"title":"Usability of 'About Me' bio","fancy_title":"Usability of ‘About Me’ bio","slug":"usability-of-about-me-bio","posts_count":10,"reply_count":6,"highest_post_number":10,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/57/blob.png","created_at":"2013-02-06T00:53:57-05:00","last_posted_at":"2013-07-23T10:23:43-04:00","bumped":true,"bumped_at":"2013-07-23T10:23:36-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":true,"views":285,"like_count":4,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":3},{"extras":null,"description":"Most Posts","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":795},{"extras":null,"description":"Frequent Poster","user_id":184},{"extras":"latest","description":"Most Recent Poster","user_id":19}]},{"id":8537,"title":"Can't save adding a group permission to a category","fancy_title":"Can’t save adding a group permission to a category","slug":"cant-save-adding-a-group-permission-to-a-category","posts_count":5,"reply_count":0,"highest_post_number":5,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1456/cf0ea1b99c6a84d7.png","created_at":"2013-07-20T18:00:09-04:00","last_posted_at":"2013-07-23T20:11:23-04:00","bumped":true,"bumped_at":"2013-07-23T07:55:19-04:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":true,"views":46,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":3681},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":7275,"title":"ActiveRecord::StatementInvalid exception raised in models/user_action.rb","fancy_title":"ActiveRecord::StatementInvalid exception raised in models/user_action.rb","slug":"activerecord-statementinvalid-exception-raised-in-models-user-action-rb","posts_count":7,"reply_count":3,"highest_post_number":7,"image_url":null,"created_at":"2013-06-07T18:17:02-04:00","last_posted_at":"2013-07-23T06:54:37-04:00","bumped":true,"bumped_at":"2013-07-23T06:54:37-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":131,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":5446},{"extras":null,"description":"Most Posts","user_id":6205},{"extras":null,"description":"Frequent Poster","user_id":5546},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":7297,"title":"Firefox: Middle-click triggers pop-up blocker","fancy_title":"Firefox: Middle-click triggers pop-up blocker","slug":"firefox-middle-click-triggers-pop-up-blocker","posts_count":8,"reply_count":3,"highest_post_number":10,"image_url":null,"created_at":"2013-06-08T14:35:59-04:00","last_posted_at":"2013-07-23T04:41:51-04:00","bumped":true,"bumped_at":"2013-07-23T04:41:51-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":144,"like_count":4,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":5372},{"extras":null,"description":"Most Posts","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":3932}]},{"id":7457,"title":"Unintended tooltip text on the 'edited' icon","fancy_title":"Unintended tooltip text on the ‘edited’ icon","slug":"unintended-tooltip-text-on-the-edited-icon","posts_count":4,"reply_count":2,"highest_post_number":4,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1099/cfe5999315be767d.jpeg","created_at":"2013-06-13T16:04:03-04:00","last_posted_at":"2013-07-23T03:42:01-04:00","bumped":true,"bumped_at":"2013-07-23T03:32:09-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":true,"views":61,"like_count":4,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":2287},{"extras":null,"description":"Most Posts","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":8576,"title":"Moderators have the interface to increase trust, but resource is 403","fancy_title":"Moderators have the interface to increase trust, but resource is 403","slug":"moderators-have-the-interface-to-increase-trust-but-resource-is-403","posts_count":5,"reply_count":2,"highest_post_number":5,"image_url":null,"created_at":"2013-07-22T17:02:14-04:00","last_posted_at":"2013-07-23T19:14:23-04:00","bumped":true,"bumped_at":"2013-07-22T19:14:14-04:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":39,"like_count":1,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":761},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":8508,"title":"Reply by Email doesn't process @name","fancy_title":"Reply by Email doesn’t process @name","slug":"reply-by-email-doesnt-process-name","posts_count":14,"reply_count":8,"highest_post_number":14,"image_url":null,"created_at":"2013-07-19T11:37:04-04:00","last_posted_at":"2013-07-22T16:24:07-04:00","bumped":true,"bumped_at":"2013-07-22T16:24:07-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":139,"like_count":2,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":5483},{"extras":null,"description":"Most Posts","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":2625}]},{"id":8570,"title":"Messages with multiple users obstructs title bar","fancy_title":"Messages with multiple users obstructs title bar","slug":"messages-with-multiple-users-obstructs-title-bar","posts_count":5,"reply_count":3,"highest_post_number":5,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/_optimized/17f/c50/cdae5eae0f6_690x324.PNG","created_at":"2013-07-22T13:10:16-04:00","last_posted_at":"2013-07-22T13:43:41-04:00","bumped":true,"bumped_at":"2013-07-22T13:43:41-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":41,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":5526},{"extras":null,"description":"Most Posts","user_id":3681}]},{"id":8504,"title":"[missing \"en.composer.quote_post_title\" translation]","fancy_title":"[missing “en.composer.quote_post_title” translation]","slug":"missing-en-composer-quote-post-title-translation","posts_count":4,"reply_count":0,"highest_post_number":4,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1448/bc346ff20c3b3d64.png","created_at":"2013-07-19T09:38:24-04:00","last_posted_at":"2013-07-22T12:18:19-04:00","bumped":true,"bumped_at":"2013-07-22T11:19:15-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":true,"views":56,"like_count":2,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":5912},{"extras":"latest","description":"Most Recent Poster, Most Posts","user_id":32}]},{"id":8545,"title":"New post/thread button bar: Foreground color left on default, background color defined","fancy_title":"New post/thread button bar: Foreground color left on default, background color defined","slug":"new-post-thread-button-bar-foreground-color-left-on-default-background-color-defined","posts_count":3,"reply_count":0,"highest_post_number":3,"image_url":null,"created_at":"2013-07-21T05:54:31-04:00","last_posted_at":"2013-07-21T13:38:01-04:00","bumped":true,"bumped_at":"2013-07-21T13:38:01-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":57,"like_count":1,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":3932},{"extras":null,"description":"Most Posts","user_id":32}]},{"id":3522,"title":"Add a deselect all option on user filter","fancy_title":"Add a deselect all option on user filter","slug":"add-a-deselect-all-option-on-user-filter","posts_count":5,"reply_count":3,"highest_post_number":5,"image_url":null,"created_at":"2013-02-20T13:40:16-05:00","last_posted_at":"2013-07-21T04:47:57-04:00","bumped":true,"bumped_at":"2013-07-21T06:04:35-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":131,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":2933},{"extras":null,"description":"Most Posts","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":3}]},{"id":8395,"title":"Editing topics bug","fancy_title":"Editing topics bug","slug":"editing-topics-bug","posts_count":6,"reply_count":3,"highest_post_number":6,"image_url":null,"created_at":"2013-07-15T15:35:33-04:00","last_posted_at":"2013-07-20T17:37:07-04:00","bumped":true,"bumped_at":"2013-07-20T17:37:07-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":97,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":5821},{"extras":null,"description":"Most Posts","user_id":32}]},{"id":7401,"title":"Shall we add category names in top_menu?","fancy_title":"Shall we add category names in top_menu?","slug":"shall-we-add-category-names-in-top-menu","posts_count":9,"reply_count":5,"highest_post_number":9,"image_url":null,"created_at":"2013-06-11T22:47:34-04:00","last_posted_at":"2013-07-20T07:52:49-04:00","bumped":true,"bumped_at":"2013-07-20T07:52:49-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":153,"like_count":3,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":5271},{"extras":null,"description":"Most Posts","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":2602},{"extras":"latest","description":"Most Recent Poster","user_id":3987}]},{"id":8506,"title":"Category featured topic error keeps getting hit when trying to o an import","fancy_title":"Category featured topic error keeps getting hit when trying to o an import","slug":"category-featured-topic-error-keeps-getting-hit-when-trying-to-o-an-import","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2013-07-19T10:49:00-04:00","last_posted_at":"2013-07-19T10:49:01-04:00","bumped":true,"bumped_at":"2013-07-19T10:49:01-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":29,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":6124}]},{"id":8482,"title":"Suggested topics keep failing after posting","fancy_title":"Suggested topics keep failing after posting","slug":"suggested-topics-keep-failing-after-posting","posts_count":3,"reply_count":0,"highest_post_number":3,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1442/0a33552a6f3cd0a2.png","created_at":"2013-07-18T17:27:52-04:00","last_posted_at":"2013-07-18T17:36:49-04:00","bumped":true,"bumped_at":"2013-07-18T17:33:37-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":true,"views":33,"like_count":1,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":5351},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":8477,"title":"Forum embeds need a fallback for when they're quoted","fancy_title":"Forum embeds need a fallback for when they’re quoted","slug":"forum-embeds-need-a-fallback-for-when-theyre-quoted","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":null,"created_at":"2013-07-18T14:53:27-04:00","last_posted_at":"2013-07-18T14:55:39-04:00","bumped":true,"bumped_at":"2013-07-18T14:55:39-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":38,"like_count":1,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":5351},{"extras":"latest","description":"Most Recent Poster","user_id":3681}]},{"id":8468,"title":"When the \"catagory\" page is your homepage, under certain conditions you will end up on it not scrolled to the top","fancy_title":"When the “catagory” page is your homepage, under certain conditions you will end up on it not scrolled to the top","slug":"when-the-catagory-page-is-your-homepage-under-certain-conditions-you-will-end-up-on-it-not-scrolled-to-the-top","posts_count":4,"reply_count":1,"highest_post_number":4,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1436/bc79d3f967e07312.png","created_at":"2013-07-18T09:55:51-04:00","last_posted_at":"2013-07-18T12:29:27-04:00","bumped":true,"bumped_at":"2013-07-18T12:29:27-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":40,"like_count":1,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":3681},{"extras":null,"description":"Most Posts","user_id":4457},{"extras":null,"description":"Frequent Poster","user_id":32}]},{"id":8467,"title":"Typo in modal dialog","fancy_title":"Typo in modal dialog","slug":"typo-in-modal-dialog","posts_count":3,"reply_count":1,"highest_post_number":3,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1435/4fad02817a590e4f.png","created_at":"2013-07-18T09:51:38-04:00","last_posted_at":"2013-07-18T12:27:17-04:00","bumped":true,"bumped_at":"2013-07-18T12:27:17-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":42,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":3681},{"extras":null,"description":"Most Posts","user_id":32}]},{"id":8267,"title":"Heart (like) button disappears after clicking","fancy_title":"Heart (like) button disappears after clicking","slug":"heart-like-button-disappears-after-clicking","posts_count":10,"reply_count":6,"highest_post_number":10,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/_optimized/96c/703/80f9efb15bd_690x255.png","created_at":"2013-07-10T10:14:02-04:00","last_posted_at":"2013-07-18T12:01:11-04:00","bumped":true,"bumped_at":"2013-07-18T12:01:11-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":117,"like_count":13,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":5351},{"extras":null,"description":"Most Posts","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":3681},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":null,"description":"Frequent Poster","user_id":5477}]},{"id":8469,"title":"Private message button doesn't fill in user","fancy_title":"Private message button doesn’t fill in user","slug":"private-message-button-doesnt-fill-in-user","posts_count":3,"reply_count":0,"highest_post_number":3,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1437/deee0f52298d7fb4.png","created_at":"2013-07-18T10:03:13-04:00","last_posted_at":"2013-07-18T10:46:23-04:00","bumped":true,"bumped_at":"2013-07-18T10:46:19-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":true,"views":36,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":3681},{"extras":"latest","description":"Most Recent Poster","user_id":19}]},{"id":8229,"title":"Post stream sometimes not pulling latest posts","fancy_title":"Post stream sometimes not pulling latest posts","slug":"post-stream-sometimes-not-pulling-latest-posts","posts_count":10,"reply_count":4,"highest_post_number":10,"image_url":null,"created_at":"2013-07-09T10:58:45-04:00","last_posted_at":"2013-07-18T10:44:56-04:00","bumped":true,"bumped_at":"2013-07-18T10:44:56-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":82,"like_count":2,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":3681},{"extras":null,"description":"Most Posts","user_id":471},{"extras":null,"description":"Frequent Poster","user_id":5477},{"extras":null,"description":"Frequent Poster","user_id":4457}]},{"id":8208,"title":"Unread state (or topic state) gets stale (on meta)","fancy_title":"Unread state (or topic state) gets stale (on meta)","slug":"unread-state-or-topic-state-gets-stale-on-meta","posts_count":10,"reply_count":6,"highest_post_number":10,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1361/4720c3b52cf473d7.png","created_at":"2013-07-08T18:00:30-04:00","last_posted_at":"2013-07-18T08:58:11-04:00","bumped":true,"bumped_at":"2013-07-18T10:07:17-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":100,"like_count":4,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":3681},{"extras":null,"description":"Most Posts","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":5372},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":4457}]}]}}; +Discourse.URL_FIXTURES["/category/bug/l/latest.json"] = {"categories":[{"id":1,"name":"bug","color":"ae3a27","text_color":"FFFFFF","slug":"bug","topic_count":442,"description":"Bug reports on Discourse. Do be sure to search prior to submitting bugs. Include repro steps, and only describe one bug per topic please.","topic_url":"/t/category-definition-for-bug/2","hotness":5.0,"read_restricted":false,"permission":null}],"users":[{"id":3987,"username":"Sander78","avatar_template":"https://www.gravatar.com/avatar/e7069beb46df22270a41afc7b277fe50.png?s={size}&r=pg&d=identicon"},{"id":1,"username":"sam","avatar_template":"https://www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon"},{"id":19,"username":"eviltrout","avatar_template":"https://www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon"},{"id":32,"username":"codinghorror","avatar_template":"https://www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon"},{"id":3681,"username":"Ajarn","avatar_template":"https://www.gravatar.com/avatar/bdfe9d9defc060d689ccd31c07e1bc19.png?s={size}&r=pg&d=identicon"},{"id":6205,"username":"senny","avatar_template":"https://www.gravatar.com/avatar/3d698e2872c07061a455d9e250861235.png?s={size}&r=pg&d=identicon"},{"id":6197,"username":"pinecone","avatar_template":"https://www.gravatar.com/avatar/a7e15f8c5bac7d8bb5a6ea7ae0eb2092.png?s={size}&r=pg&d=identicon"},{"id":3,"username":"supermathie","avatar_template":"https://www.gravatar.com/avatar/44ae1b2d44d48aed3d432129a5703942.png?s={size}&r=pg&d=identicon"},{"id":3062,"username":"Sailsman63","avatar_template":"https://www.gravatar.com/avatar/d2afe59f03e33f57760fbaacc35949d5.png?s={size}&r=pg&d=identicon"},{"id":6208,"username":"chromium_o2","avatar_template":"https://www.gravatar.com/avatar/a5d0ac66c4b8a5ac23b58b109d068a20.png?s={size}&r=pg&d=identicon"},{"id":1995,"username":"zogstrip","avatar_template":"https://www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon"},{"id":2,"username":"Neil","avatar_template":"https://www.gravatar.com/avatar/42776c4982dff1fa45ee8248532f8ad0.png?s={size}&r=pg&d=identicon"},{"id":795,"username":"mlinksva","avatar_template":"https://www.gravatar.com/avatar/7e3038f9bbba96ceb14a097e4ee128ff.png?s={size}&r=pg&d=identicon"},{"id":184,"username":"Jeremy","avatar_template":"https://www.gravatar.com/avatar/8022129f3ef00ca4f42bbd494b216310.png?s={size}&r=pg&d=identicon"},{"id":5446,"username":"expyron","avatar_template":"https://www.gravatar.com/avatar/697b750fd66f4e60779152ff1c3fc97e.png?s={size}&r=pg&d=identicon"},{"id":5546,"username":"adrianlang","avatar_template":"https://www.gravatar.com/avatar/9a38887baf481569db05e89d38bc5797.png?s={size}&r=pg&d=identicon"},{"id":5372,"username":"computerdruid","avatar_template":"https://www.gravatar.com/avatar/34c3b45c075a6d85555beb674892d0d8.png?s={size}&r=pg&d=identicon"},{"id":3932,"username":"flyingsheep","avatar_template":"https://www.gravatar.com/avatar/da56018fec1036eb1e02305d09a0bce8.png?s={size}&r=pg&d=identicon"},{"id":2287,"username":"fgonzal","avatar_template":"https://www.gravatar.com/avatar/4079bc13f142ea46e0144d1ca9426aa9.png?s={size}&r=pg&d=identicon"},{"id":761,"username":"marcoceppi","avatar_template":"https://www.gravatar.com/avatar/4ddc8924e79bcec03256821af65fca91.png?s={size}&r=pg&d=identicon"},{"id":5483,"username":"briangillespie","avatar_template":"https://www.gravatar.com/avatar/3baf9989e97ccf45aff1cf61fb730931.png?s={size}&r=pg&d=identicon"},{"id":2625,"username":"kpfleming","avatar_template":"https://www.gravatar.com/avatar/26bf5a02583eaf63d1f8063bb3a6bc00.png?s={size}&r=pg&d=identicon"},{"id":5526,"username":"geoffers747","avatar_template":"https://www.gravatar.com/avatar/fe1b6d588bfd97692f4172e41b378c09.png?s={size}&r=pg&d=identicon"},{"id":5912,"username":"jbruni","avatar_template":"https://www.gravatar.com/avatar/27dacda91150eca332526bf8a8ee7e03.png?s={size}&r=pg&d=identicon"},{"id":2933,"username":"gugalp","avatar_template":"https://www.gravatar.com/avatar/a143639f87eead196bb94bcd10380ff4.png?s={size}&r=pg&d=identicon"},{"id":5821,"username":"ven88","avatar_template":"https://www.gravatar.com/avatar/39fc4d1c6dcefe9c1ae9730f99c65af7.png?s={size}&r=pg&d=identicon"},{"id":5271,"username":"royguo","avatar_template":"https://www.gravatar.com/avatar/7e795755fe8a817981c3a81620faf359.png?s={size}&r=pg&d=identicon"},{"id":2602,"username":"georgekaplan59","avatar_template":"https://www.gravatar.com/avatar/503623c769903342cba73e722a364061.png?s={size}&r=pg&d=identicon"},{"id":6124,"username":"matthewalbone","avatar_template":"https://www.gravatar.com/avatar/82ec94bea07cd4ace35c93d8ad404917.png?s={size}&r=pg&d=identicon"},{"id":5351,"username":"erlend_sh","avatar_template":"https://www.gravatar.com/avatar/69fda0df8b4878fb6a18deffa972d26a.png?s={size}&r=pg&d=identicon"},{"id":4457,"username":"Lee_Ars","avatar_template":"https://www.gravatar.com/avatar/eff1b72d56a97459a27161ccf7f20c89.png?s={size}&r=pg&d=identicon"},{"id":4263,"username":"mcwumbly","avatar_template":"https://www.gravatar.com/avatar/e217128117fe24525c7af5ebc5e45745.png?s={size}&r=pg&d=identicon"},{"id":5477,"username":"phanimahesh","avatar_template":"https://www.gravatar.com/avatar/42ca770299eab441ddabae5a1ad5f799.png?s={size}&r=pg&d=identicon"},{"id":471,"username":"BhaelOchon","avatar_template":"https://www.gravatar.com/avatar/413ef976f0d2ca993005c9aee4769254.png?s={size}&r=pg&d=identicon"}],"topic_list":{"can_create_topic":false,"more_topics_url":"/category/bug.json?page=1","draft":null,"draft_key":"new_topic","draft_sequence":null,"topics":[{"id":7288,"title":"Digest mail ignores secure groups","fancy_title":"Digest mail ignores secure groups","slug":"digest-mail-ignores-secure-groups","posts_count":7,"reply_count":3,"highest_post_number":7,"image_url":"http://cdn.discourse.org/assets/emoji/smile.png","created_at":"2013-06-08T08:54:12-04:00","last_posted_at":"2013-06-08T13:00:38-04:00","bumped":true,"bumped_at":"2013-06-08T13:00:38-04:00","unseen":false,"pinned":true,"excerpt":"People receiving the digest mail can easily read posts not meant for them. That's because the digest mail ignores the secure groups a member has access to or not. \n\nQuite a problem as I unfortunately found out. [smile]","visible":true,"closed":false,"archived":false,"views":233,"like_count":3,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":3987},{"extras":null,"description":"Most Posts","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":19}]},{"id":2,"title":"Category definition for bug","fancy_title":"Category definition for bug","slug":"category-definition-for-bug","posts_count":2,"reply_count":0,"highest_post_number":3,"image_url":null,"created_at":"2013-01-31T23:56:34-05:00","last_posted_at":"2013-03-07T22:42:27-05:00","bumped":true,"bumped_at":"2013-02-26T18:52:56-05:00","unseen":false,"pinned":true,"excerpt":"Bug reports on Discourse. Do be sure to search prior to submitting bugs. Include repro steps, and only describe one bug per topic please.","visible":true,"closed":false,"archived":false,"views":287,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":8198,"title":"Unable to create group","fancy_title":"Unable to create group","slug":"unable-to-create-group","posts_count":12,"reply_count":6,"highest_post_number":12,"image_url":null,"created_at":"2013-07-08T13:58:49-04:00","last_posted_at":"2013-07-24T09:22:00-04:00","bumped":true,"bumped_at":"2013-07-24T09:22:00-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":139,"like_count":2,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":3681},{"extras":null,"description":"Most Posts","user_id":3987},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":6205},{"extras":"latest","description":"Most Recent Poster","user_id":6197}]},{"id":8542,"title":"Add user to filter when explicitly requesting their post","fancy_title":"Add user to filter when explicitly requesting their post","slug":"add-user-to-filter-when-explicitly-requesting-their-post","posts_count":3,"reply_count":1,"highest_post_number":3,"image_url":null,"created_at":"2013-07-21T04:43:39-04:00","last_posted_at":"2013-07-23T22:17:30-04:00","bumped":true,"bumped_at":"2013-07-23T22:17:30-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":48,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":3},{"extras":null,"description":"Most Posts","user_id":32}]},{"id":7051,"title":"Image upload fails silently","fancy_title":"Image upload fails silently","slug":"image-upload-fails-silently","posts_count":5,"reply_count":2,"highest_post_number":5,"image_url":null,"created_at":"2013-05-31T16:12:56-04:00","last_posted_at":"2013-07-23T16:50:31-04:00","bumped":true,"bumped_at":"2013-07-23T16:50:31-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":129,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":3062},{"extras":null,"description":"Most Posts","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":6208},{"extras":"latest","description":"Most Recent Poster","user_id":1995}]},{"id":8600,"title":"Modal when deleting post not disappearing","fancy_title":"Modal when deleting post not disappearing","slug":"modal-when-deleting-post-not-disappearing","posts_count":5,"reply_count":0,"highest_post_number":5,"image_url":null,"created_at":"2013-07-23T11:20:35-04:00","last_posted_at":"2013-07-23T15:24:36-04:00","bumped":true,"bumped_at":"2013-07-23T15:24:32-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":true,"views":36,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":3987},{"extras":null,"description":"Most Posts","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":19}]},{"id":6731,"title":"Can't delete a user if a deleted topic exists","fancy_title":"Can’t delete a user if a deleted topic exists","slug":"cant-delete-a-user-if-a-deleted-topic-exists","posts_count":3,"reply_count":0,"highest_post_number":3,"image_url":null,"created_at":"2013-05-20T07:22:51-04:00","last_posted_at":"2013-07-23T14:32:03-04:00","bumped":true,"bumped_at":"2013-07-23T12:19:42-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":true,"views":127,"like_count":5,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":3987},{"extras":"latest","description":"Most Recent Poster","user_id":2}]},{"id":8233,"title":"Category pages don't auto-update","fancy_title":"Category pages don’t auto-update","slug":"category-pages-dont-auto-update","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":null,"created_at":"2013-07-09T13:00:11-04:00","last_posted_at":"2013-07-23T10:26:25-04:00","bumped":true,"bumped_at":"2013-07-23T10:26:25-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":69,"like_count":2,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":3681}]},{"id":882,"title":"Usability of 'About Me' bio","fancy_title":"Usability of ‘About Me’ bio","slug":"usability-of-about-me-bio","posts_count":10,"reply_count":6,"highest_post_number":10,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/57/blob.png","created_at":"2013-02-06T00:53:57-05:00","last_posted_at":"2013-07-23T10:23:43-04:00","bumped":true,"bumped_at":"2013-07-23T10:23:36-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":true,"views":285,"like_count":4,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":3},{"extras":null,"description":"Most Posts","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":795},{"extras":null,"description":"Frequent Poster","user_id":184},{"extras":"latest","description":"Most Recent Poster","user_id":19}]},{"id":8537,"title":"Can't save adding a group permission to a category","fancy_title":"Can’t save adding a group permission to a category","slug":"cant-save-adding-a-group-permission-to-a-category","posts_count":5,"reply_count":0,"highest_post_number":5,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1456/cf0ea1b99c6a84d7.png","created_at":"2013-07-20T18:00:09-04:00","last_posted_at":"2013-07-23T20:11:23-04:00","bumped":true,"bumped_at":"2013-07-23T07:55:19-04:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":true,"views":46,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":3681},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":7275,"title":"ActiveRecord::StatementInvalid exception raised in models/user_action.rb","fancy_title":"ActiveRecord::StatementInvalid exception raised in models/user_action.rb","slug":"activerecord-statementinvalid-exception-raised-in-models-user-action-rb","posts_count":7,"reply_count":3,"highest_post_number":7,"image_url":null,"created_at":"2013-06-07T18:17:02-04:00","last_posted_at":"2013-07-23T06:54:37-04:00","bumped":true,"bumped_at":"2013-07-23T06:54:37-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":131,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":5446},{"extras":null,"description":"Most Posts","user_id":6205},{"extras":null,"description":"Frequent Poster","user_id":5546},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":7297,"title":"Firefox: Middle-click triggers pop-up blocker","fancy_title":"Firefox: Middle-click triggers pop-up blocker","slug":"firefox-middle-click-triggers-pop-up-blocker","posts_count":8,"reply_count":3,"highest_post_number":10,"image_url":null,"created_at":"2013-06-08T14:35:59-04:00","last_posted_at":"2013-07-23T04:41:51-04:00","bumped":true,"bumped_at":"2013-07-23T04:41:51-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":144,"like_count":4,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":5372},{"extras":null,"description":"Most Posts","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":3932}]},{"id":7457,"title":"Unintended tooltip text on the 'edited' icon","fancy_title":"Unintended tooltip text on the ‘edited’ icon","slug":"unintended-tooltip-text-on-the-edited-icon","posts_count":4,"reply_count":2,"highest_post_number":4,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1099/cfe5999315be767d.jpeg","created_at":"2013-06-13T16:04:03-04:00","last_posted_at":"2013-07-23T03:42:01-04:00","bumped":true,"bumped_at":"2013-07-23T03:32:09-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":true,"views":61,"like_count":4,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":2287},{"extras":null,"description":"Most Posts","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":8576,"title":"Moderators have the interface to increase trust, but resource is 403","fancy_title":"Moderators have the interface to increase trust, but resource is 403","slug":"moderators-have-the-interface-to-increase-trust-but-resource-is-403","posts_count":5,"reply_count":2,"highest_post_number":5,"image_url":null,"created_at":"2013-07-22T17:02:14-04:00","last_posted_at":"2013-07-23T19:14:23-04:00","bumped":true,"bumped_at":"2013-07-22T19:14:14-04:00","unseen":false,"pinned":false,"visible":true,"closed":true,"archived":false,"views":39,"like_count":1,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":761},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":8508,"title":"Reply by Email doesn't process @name","fancy_title":"Reply by Email doesn’t process @name","slug":"reply-by-email-doesnt-process-name","posts_count":14,"reply_count":8,"highest_post_number":14,"image_url":null,"created_at":"2013-07-19T11:37:04-04:00","last_posted_at":"2013-07-22T16:24:07-04:00","bumped":true,"bumped_at":"2013-07-22T16:24:07-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":139,"like_count":2,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":5483},{"extras":null,"description":"Most Posts","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":2625}]},{"id":8570,"title":"Messages with multiple users obstructs title bar","fancy_title":"Messages with multiple users obstructs title bar","slug":"messages-with-multiple-users-obstructs-title-bar","posts_count":5,"reply_count":3,"highest_post_number":5,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/_optimized/17f/c50/cdae5eae0f6_690x324.PNG","created_at":"2013-07-22T13:10:16-04:00","last_posted_at":"2013-07-22T13:43:41-04:00","bumped":true,"bumped_at":"2013-07-22T13:43:41-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":41,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":5526},{"extras":null,"description":"Most Posts","user_id":3681}]},{"id":8504,"title":"[missing \"en.composer.quote_post_title\" translation]","fancy_title":"[missing “en.composer.quote_post_title” translation]","slug":"missing-en-composer-quote-post-title-translation","posts_count":4,"reply_count":0,"highest_post_number":4,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1448/bc346ff20c3b3d64.png","created_at":"2013-07-19T09:38:24-04:00","last_posted_at":"2013-07-22T12:18:19-04:00","bumped":true,"bumped_at":"2013-07-22T11:19:15-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":true,"views":56,"like_count":2,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":5912},{"extras":"latest","description":"Most Recent Poster, Most Posts","user_id":32}]},{"id":8545,"title":"New post/thread button bar: Foreground color left on default, background color defined","fancy_title":"New post/thread button bar: Foreground color left on default, background color defined","slug":"new-post-thread-button-bar-foreground-color-left-on-default-background-color-defined","posts_count":3,"reply_count":0,"highest_post_number":3,"image_url":null,"created_at":"2013-07-21T05:54:31-04:00","last_posted_at":"2013-07-21T13:38:01-04:00","bumped":true,"bumped_at":"2013-07-21T13:38:01-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":57,"like_count":1,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":3932},{"extras":null,"description":"Most Posts","user_id":32}]},{"id":3522,"title":"Add a deselect all option on user filter","fancy_title":"Add a deselect all option on user filter","slug":"add-a-deselect-all-option-on-user-filter","posts_count":5,"reply_count":3,"highest_post_number":5,"image_url":null,"created_at":"2013-02-20T13:40:16-05:00","last_posted_at":"2013-07-21T04:47:57-04:00","bumped":true,"bumped_at":"2013-07-21T06:04:35-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":131,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":2933},{"extras":null,"description":"Most Posts","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":"latest","description":"Most Recent Poster","user_id":3}]},{"id":8395,"title":"Editing topics bug","fancy_title":"Editing topics bug","slug":"editing-topics-bug","posts_count":6,"reply_count":3,"highest_post_number":6,"image_url":null,"created_at":"2013-07-15T15:35:33-04:00","last_posted_at":"2013-07-20T17:37:07-04:00","bumped":true,"bumped_at":"2013-07-20T17:37:07-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":97,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":5821},{"extras":null,"description":"Most Posts","user_id":32}]},{"id":7401,"title":"Shall we add category names in top_menu?","fancy_title":"Shall we add category names in top_menu?","slug":"shall-we-add-category-names-in-top-menu","posts_count":9,"reply_count":5,"highest_post_number":9,"image_url":null,"created_at":"2013-06-11T22:47:34-04:00","last_posted_at":"2013-07-20T07:52:49-04:00","bumped":true,"bumped_at":"2013-07-20T07:52:49-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":153,"like_count":3,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":5271},{"extras":null,"description":"Most Posts","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":2602},{"extras":"latest","description":"Most Recent Poster","user_id":3987}]},{"id":8506,"title":"Category featured topic error keeps getting hit when trying to o an import","fancy_title":"Category featured topic error keeps getting hit when trying to o an import","slug":"category-featured-topic-error-keeps-getting-hit-when-trying-to-o-an-import","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2013-07-19T10:49:00-04:00","last_posted_at":"2013-07-19T10:49:01-04:00","bumped":true,"bumped_at":"2013-07-19T10:49:01-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":29,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":6124}]},{"id":8482,"title":"Suggested topics keep failing after posting","fancy_title":"Suggested topics keep failing after posting","slug":"suggested-topics-keep-failing-after-posting","posts_count":3,"reply_count":0,"highest_post_number":3,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1442/0a33552a6f3cd0a2.png","created_at":"2013-07-18T17:27:52-04:00","last_posted_at":"2013-07-18T17:36:49-04:00","bumped":true,"bumped_at":"2013-07-18T17:33:37-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":true,"views":33,"like_count":1,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":5351},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":8477,"title":"Forum embeds need a fallback for when they're quoted","fancy_title":"Forum embeds need a fallback for when they’re quoted","slug":"forum-embeds-need-a-fallback-for-when-theyre-quoted","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":null,"created_at":"2013-07-18T14:53:27-04:00","last_posted_at":"2013-07-18T14:55:39-04:00","bumped":true,"bumped_at":"2013-07-18T14:55:39-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":38,"like_count":1,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":5351},{"extras":"latest","description":"Most Recent Poster","user_id":3681}]},{"id":8468,"title":"When the \"catagory\" page is your homepage, under certain conditions you will end up on it not scrolled to the top","fancy_title":"When the “catagory” page is your homepage, under certain conditions you will end up on it not scrolled to the top","slug":"when-the-catagory-page-is-your-homepage-under-certain-conditions-you-will-end-up-on-it-not-scrolled-to-the-top","posts_count":4,"reply_count":1,"highest_post_number":4,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1436/bc79d3f967e07312.png","created_at":"2013-07-18T09:55:51-04:00","last_posted_at":"2013-07-18T12:29:27-04:00","bumped":true,"bumped_at":"2013-07-18T12:29:27-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":40,"like_count":1,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":3681},{"extras":null,"description":"Most Posts","user_id":4457},{"extras":null,"description":"Frequent Poster","user_id":32}]},{"id":8467,"title":"Typo in modal dialog","fancy_title":"Typo in modal dialog","slug":"typo-in-modal-dialog","posts_count":3,"reply_count":1,"highest_post_number":3,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1435/4fad02817a590e4f.png","created_at":"2013-07-18T09:51:38-04:00","last_posted_at":"2013-07-18T12:27:17-04:00","bumped":true,"bumped_at":"2013-07-18T12:27:17-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":42,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":3681},{"extras":null,"description":"Most Posts","user_id":32}]},{"id":8267,"title":"Heart (like) button disappears after clicking","fancy_title":"Heart (like) button disappears after clicking","slug":"heart-like-button-disappears-after-clicking","posts_count":10,"reply_count":6,"highest_post_number":10,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/_optimized/96c/703/80f9efb15bd_690x255.png","created_at":"2013-07-10T10:14:02-04:00","last_posted_at":"2013-07-18T12:01:11-04:00","bumped":true,"bumped_at":"2013-07-18T12:01:11-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":117,"like_count":13,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":5351},{"extras":null,"description":"Most Posts","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":3681},{"extras":null,"description":"Frequent Poster","user_id":4263},{"extras":null,"description":"Frequent Poster","user_id":5477}]},{"id":8469,"title":"Private message button doesn't fill in user","fancy_title":"Private message button doesn’t fill in user","slug":"private-message-button-doesnt-fill-in-user","posts_count":3,"reply_count":0,"highest_post_number":3,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1437/deee0f52298d7fb4.png","created_at":"2013-07-18T10:03:13-04:00","last_posted_at":"2013-07-18T10:46:23-04:00","bumped":true,"bumped_at":"2013-07-18T10:46:19-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":true,"views":36,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":3681},{"extras":"latest","description":"Most Recent Poster","user_id":19}]},{"id":8229,"title":"Post stream sometimes not pulling latest posts","fancy_title":"Post stream sometimes not pulling latest posts","slug":"post-stream-sometimes-not-pulling-latest-posts","posts_count":10,"reply_count":4,"highest_post_number":10,"image_url":null,"created_at":"2013-07-09T10:58:45-04:00","last_posted_at":"2013-07-18T10:44:56-04:00","bumped":true,"bumped_at":"2013-07-18T10:44:56-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":82,"like_count":2,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":3681},{"extras":null,"description":"Most Posts","user_id":471},{"extras":null,"description":"Frequent Poster","user_id":5477},{"extras":null,"description":"Frequent Poster","user_id":4457}]},{"id":8208,"title":"Unread state (or topic state) gets stale (on meta)","fancy_title":"Unread state (or topic state) gets stale (on meta)","slug":"unread-state-or-topic-state-gets-stale-on-meta","posts_count":10,"reply_count":6,"highest_post_number":10,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1361/4720c3b52cf473d7.png","created_at":"2013-07-08T18:00:30-04:00","last_posted_at":"2013-07-18T08:58:11-04:00","bumped":true,"bumped_at":"2013-07-18T10:07:17-04:00","unseen":false,"pinned":false,"visible":true,"closed":false,"archived":false,"views":100,"like_count":4,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":3681},{"extras":null,"description":"Most Posts","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":5372},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":4457}]}]}}; diff --git a/test/javascripts/helpers/assertions.js b/test/javascripts/helpers/assertions.js index a192cd8b3..19cb2e648 100644 --- a/test/javascripts/helpers/assertions.js +++ b/test/javascripts/helpers/assertions.js @@ -1,12 +1,4 @@ // Test helpers -// var resolvingPromise = Ember.Deferred.promise(function (p) { -// p.resolve(); -// }); - -// var resolvingPromiseWith = function(result) { -// return Ember.Deferred.promise(function (p) { p.resolve(result); }); -// }; - function exists(selector) { return !!count(selector); } diff --git a/test/javascripts/helpers/parse_html.js b/test/javascripts/helpers/parse_html.js new file mode 100644 index 000000000..8b1f9d13e --- /dev/null +++ b/test/javascripts/helpers/parse_html.js @@ -0,0 +1,7 @@ +function parseHTML(rawHtml) { + var builder = new Tautologistics.NodeHtmlParser.HtmlBuilder(), + parser = new Tautologistics.NodeHtmlParser.Parser(builder); + + parser.parseComplete(rawHtml); + return builder.dom; +} \ No newline at end of file diff --git a/test/javascripts/jshint_all.js.erb b/test/javascripts/jshint_all.js.erb index 05dbfaaa9..b7a55e78a 100644 --- a/test/javascripts/jshint_all.js.erb +++ b/test/javascripts/jshint_all.js.erb @@ -124,6 +124,7 @@ var jsHintOpts = { "controllerFor", "testController", "containsInstance", + "parseHTML", "deepEqual", "notEqual", "Blob", diff --git a/test/javascripts/lib/html_test.js b/test/javascripts/lib/html_test.js new file mode 100644 index 000000000..cc6834073 --- /dev/null +++ b/test/javascripts/lib/html_test.js @@ -0,0 +1,43 @@ +module("Discourse.HTML"); + +var html = Discourse.HTML; + +test("categoryLink without a category", function() { + blank(Discourse.HTML.categoryLink(), "it returns no HTML"); +}); + +test("Regular categoryLink", function() { + var category = Discourse.Category.create({ + name: 'hello', + id: 123, + description: 'cool description', + color: 'ff0', + text_color: 'f00' + }), + tag = parseHTML(Discourse.HTML.categoryLink(category))[0]; + + equal(tag.name, 'a', 'it creates an `a` tag'); + equal(tag.attributes['class'], 'badge-category', 'it has the correct class'); + equal(tag.attributes.title, 'cool description', 'it has the correct title'); + + ok(tag.attributes.style.indexOf('#ff0') !== -1, "it has the color style"); + ok(tag.attributes.style.indexOf('#f00') !== -1, "it has the textColor style"); + + equal(tag.children[0].data, 'hello', 'it has the category name'); +}); + +test("undefined color", function() { + var noColor = Discourse.Category.create({ name: 'hello', id: 123 }), + tag = parseHTML(Discourse.HTML.categoryLink(noColor))[0]; + + blank(tag.attributes.style, "it has no color style because there are no colors"); +}); + +test("allowUncategorized", function() { + var uncategorized = Discourse.Category.create({name: 'uncategorized', id: 345}); + this.stub(Discourse.Site, 'currentProp').withArgs('uncategorized_category_id').returns(345); + + blank(Discourse.HTML.categoryLink(uncategorized), "it doesn't return HTML for uncategorized by default"); + present(Discourse.HTML.categoryLink(uncategorized, {allowUncategorized: true}), "it returns HTML"); +}); + diff --git a/test/javascripts/test_helper.js b/test/javascripts/test_helper.js index 49522e70b..797080c81 100644 --- a/test/javascripts/test_helper.js +++ b/test/javascripts/test_helper.js @@ -50,6 +50,7 @@ //= require mousetrap.js //= require rsvp.js //= require show-html.js +//= require htmlparser.js // Stuff we need to load first //= require main_include diff --git a/vendor/assets/javascripts/htmlparser.js b/vendor/assets/javascripts/htmlparser.js new file mode 100644 index 000000000..04668e065 --- /dev/null +++ b/vendor/assets/javascripts/htmlparser.js @@ -0,0 +1,993 @@ +/*********************************************** +Copyright 2010 - 2012 Chris Winberry . All rights reserved. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. +***********************************************/ +/* v2.0.0 */ + +(function () { + +var exports; +if (typeof(module) !== 'undefined' && typeof(module.exports) !== 'undefined') { + exports = module.exports; +} else { + exports = {}; + if (!this.Tautologistics) { + this.Tautologistics = {}; + } + if (this.Tautologistics.NodeHtmlParser) { + return; + } + this.Tautologistics.NodeHtmlParser = exports; +} + +function inherits (ctor, superCtor) { + var tempCtor = function(){}; + tempCtor.prototype = superCtor.prototype; + ctor.super_ = superCtor; + ctor.prototype = new tempCtor(); + ctor.prototype.constructor = ctor; +} + +var Mode = { + Text: 'text', + Tag: 'tag', + Attr: 'attr', + CData: 'cdata', + Doctype: 'doctype', + Comment: 'comment' +}; + +function Parser (builder, options) { + this._options = options ? options : { }; + // if (this._options.includeLocation === undefined) { + // this._options.includeLocation = false; //Include position of element (row, col) on nodes + // } + this._validateBuilder(builder); + var self = this; + this._builder = builder; + this.reset(); +} + +if (typeof(module) !== 'undefined' && typeof(module.exports) !== 'undefined') { + + var Stream = require('stream'); + inherits(Parser, Stream); + + Parser.prototype.writable = true; + Parser.prototype.write = function(data) { + if(data instanceof Buffer) { + data = data.toString(); + } + this.parseChunk(data); + }; + + Parser.prototype.end = function(data) { + if (arguments.length) { + this.write(data); + } + this.writable = false; + this.done(); + }; + + Parser.prototype.destroy = function() { + this.writable = false; + }; + +} + + //**Public**// + Parser.prototype.reset = function Parser$reset () { + this._state = { + mode: Mode.Text, + pos: 0, + data: null, + pendingText: null, + pendingWrite: null, + lastTag: null, + isScript: false, + needData: false, + output: [], + done: false//, + // line: 1, + // col: 1 + }; + this._builder.reset(); + }; + + Parser.prototype.parseChunk = function Parser$parseChunk (chunk) { + this._state.needData = false; + this._state.data = (this._state.data !== null) ? + this._state.data.substr(this.pos) + chunk + : + chunk + ; + while (this._state.pos < this._state.data.length && !this._state.needData) { + this._parse(this._state); + } + }; + + Parser.prototype.parseComplete = function Parser$parseComplete (data) { + this.reset(); + this.parseChunk(data); + this.done(); + }; + + Parser.prototype.done = function Parser$done () { + this._state.done = true; + this._parse(this._state); + this._flushWrite(); + this._builder.done(); + }; + + //**Private**// + Parser.prototype._validateBuilder = function Parser$_validateBuilder (builder) { + if ((typeof builder) != "object") { + throw new Error("Builder is not an object"); + } + if ((typeof builder.reset) != "function") { + throw new Error("Builder method 'reset' is invalid"); + } + if ((typeof builder.done) != "function") { + throw new Error("Builder method 'done' is invalid"); + } + if ((typeof builder.write) != "function") { + throw new Error("Builder method 'write' is invalid"); + } + if ((typeof builder.error) != "function") { + throw new Error("Builder method 'error' is invalid"); + } + }; + + Parser.prototype._parse = function Parser$_parse () { + switch (this._state.mode) { + case Mode.Text: + return this._parseText(this._state); + case Mode.Tag: + return this._parseTag(this._state); + case Mode.Attr: + return this._parseAttr(this._state); + case Mode.CData: + return this._parseCData(this._state); + case Mode.Doctype: + return this._parseDoctype(this._state); + case Mode.Comment: + return this._parseComment(this._state); + } + }; + + Parser.prototype._writePending = function Parser$_writePending (node) { + if (!this._state.pendingWrite) { + this._state.pendingWrite = []; + } + this._state.pendingWrite.push(node); + }; + + Parser.prototype._flushWrite = function Parser$_flushWrite () { + if (this._state.pendingWrite) { + for (var i = 0, len = this._state.pendingWrite.length; i < len; i++) { + var node = this._state.pendingWrite[i]; + this._builder.write(node); + } + this._state.pendingWrite = null; + } + }; + + Parser.prototype._write = function Parser$_write (node) { + this._flushWrite(); + this._builder.write(node); + }; + + Parser._re_parseText_scriptClose = /<\s*\/\s*script/ig; + Parser.prototype._parseText = function Parser$_parseText () { + var state = this._state; + var foundPos; + if (state.isScript) { + Parser._re_parseText_scriptClose.lastIndex = state.pos; + foundPos = Parser._re_parseText_scriptClose.exec(state.data); + foundPos = (foundPos) ? + foundPos.index + : + -1 + ; + } else { + foundPos = state.data.indexOf('<', state.pos); + } + var text = (foundPos === -1) ? state.data.substring(state.pos, state.data.length) : state.data.substring(state.pos, foundPos); + if (foundPos < 0 && state.done) { + foundPos = state.data.length; + } + if (foundPos < 0) { + if (state.isScript) { + state.needData = true; + return; + } + if (!state.pendingText) { + state.pendingText = []; + } + state.pendingText.push(state.data.substring(state.pos, state.data.length)); + state.pos = state.data.length; + } else { + if (state.pendingText) { + state.pendingText.push(state.data.substring(state.pos, foundPos)); + text = state.pendingText.join(''); + state.pendingText = null; + } else { + text = state.data.substring(state.pos, foundPos); + } + if (text !== '') { + this._write({ type: Mode.Text, data: text }); + } + state.pos = foundPos + 1; + state.mode = Mode.Tag; + } + }; + + Parser.re_parseTag = /\s*(\/?)\s*([^\s>\/]+)(\s*)\??(>?)/g; + Parser.prototype._parseTag = function Parser$_parseTag () { + var state = this._state; + Parser.re_parseTag.lastIndex = state.pos; + var match = Parser.re_parseTag.exec(state.data); + if (match) { + if (!match[1] && match[2].substr(0, 3) === '!--') { + state.mode = Mode.Comment; + state.pos += 3; + return; + } + if (!match[1] && match[2].substr(0, 8) === '![CDATA[') { + state.mode = Mode.CData; + state.pos += 8; + return; + } + if (!match[1] && match[2].substr(0, 8) === '!DOCTYPE') { + state.mode = Mode.Doctype; + state.pos += 8; + return; + } + if (!state.done && (state.pos + match[0].length) === state.data.length) { + //We're at the and of the data, might be incomplete + state.needData = true; + return; + } + var raw; + if (match[4] === '>') { + state.mode = Mode.Text; + raw = match[0].substr(0, match[0].length - 1); + } else { + state.mode = Mode.Attr; + raw = match[0]; + } + state.pos += match[0].length; + var tag = { type: Mode.Tag, name: match[1] + match[2], raw: raw }; + if (state.mode === Mode.Attr) { + state.lastTag = tag; + } + if (tag.name.toLowerCase() === 'script') { + state.isScript = true; + } else if (tag.name.toLowerCase() === '/script') { + state.isScript = false; + } + if (state.mode === Mode.Attr) { + this._writePending(tag); + } else { + this._write(tag); + } + } else { + //TODO: end of tag? + //TODO: push to pending? + state.needData = true; + } + }; + + Parser.re_parseAttr_findName = /\s*([^=<>\s'"\/]+)\s*/g; + Parser.prototype._parseAttr_findName = function Parser$_parseAttr_findName () { + Parser.re_parseAttr_findName.lastIndex = this._state.pos; + var match = Parser.re_parseAttr_findName.exec(this._state.data); + if (!match) { + return null; + } + if (this._state.pos + match[0].length !== Parser.re_parseAttr_findName.lastIndex) { + return null; + } + return { + match: match[0] + , name: match[1] + }; + }; + Parser.re_parseAttr_findValue = /\s*=\s*(?:'([^']*)'|"([^"]*)"|([^'"\s\/>]+))\s*/g; + Parser.re_parseAttr_findValue_last = /\s*=\s*['"]?(.*)$/g; + Parser.prototype._parseAttr_findValue = function Parser$_parseAttr_findValue () { + var state = this._state; + Parser.re_parseAttr_findValue.lastIndex = state.pos; + var match = Parser.re_parseAttr_findValue.exec(state.data); + if (!match) { + if (!state.done) { + return null; + } + Parser.re_parseAttr_findValue_last.lastIndex = state.pos; + match = Parser.re_parseAttr_findValue_last.exec(state.data); + if (!match) { + return null; + } + return { + match: match[0] + , value: (match[1] !== '') ? match[1] : null + }; + } + if (state.pos + match[0].length !== Parser.re_parseAttr_findValue.lastIndex) { + return null; + } + return { + match: match[0] + , value: match[1] || match[2] || match[3] + }; + }; + Parser.re_parseAttr_splitValue = /\s*=\s*['"]?/g; + Parser.re_parseAttr_selfClose = /(\s*\/\s*)(>?)/g; + Parser.prototype._parseAttr = function Parser$_parseAttr () { + var state = this._state; + var name_data = this._parseAttr_findName(state); + if (!name_data || name_data.name === '?') { + Parser.re_parseAttr_selfClose.lastIndex = state.pos; + var matchTrailingSlash = Parser.re_parseAttr_selfClose.exec(state.data); + if (matchTrailingSlash && matchTrailingSlash.index === state.pos) { + if (!state.done && !matchTrailingSlash[2] && state.pos + matchTrailingSlash[0].length === state.data.length) { + state.needData = true; + return; + } + state.lastTag.raw += matchTrailingSlash[1]; + // state.output.push({ type: Mode.Tag, name: '/' + state.lastTag.name, raw: null }); + this._write({ type: Mode.Tag, name: '/' + state.lastTag.name, raw: null }); + state.pos += matchTrailingSlash[1].length; + } + var foundPos = state.data.indexOf('>', state.pos); + if (foundPos < 0) { + if (state.done) { //TODO: is this needed? + state.lastTag.raw += state.data.substr(state.pos); + state.pos = state.data.length; + return; + } + state.needData = true; + } else { + // state.lastTag = null; + state.pos = foundPos + 1; + state.mode = Mode.Text; + } + return; + } + if (!state.done && state.pos + name_data.match.length === state.data.length) { + state.needData = true; + return null; + } + state.pos += name_data.match.length; + var value_data = this._parseAttr_findValue(state); + if (value_data) { + if (!state.done && state.pos + value_data.match.length === state.data.length) { + state.needData = true; + state.pos -= name_data.match.length; + return; + } + state.pos += value_data.match.length; + } else { + Parser.re_parseAttr_splitValue.lastIndex = state.pos; + if (Parser.re_parseAttr_splitValue.exec(state.data)) { + state.needData = true; + state.pos -= name_data.match.length; + return; + } + value_data = { + match: '' + , value: null + }; + } + state.lastTag.raw += name_data.match + value_data.match; + + this._writePending({ type: Mode.Attr, name: name_data.name, data: value_data.value }); + }; + + Parser.re_parseCData_findEnding = /\]{1,2}$/; + Parser.prototype._parseCData = function Parser$_parseCData () { + var state = this._state; + var foundPos = state.data.indexOf(']]>', state.pos); + if (foundPos < 0 && state.done) { + foundPos = state.data.length; + } + if (foundPos < 0) { + Parser.re_parseCData_findEnding.lastIndex = state.pos; + var matchPartialCDataEnd = Parser.re_parseCData_findEnding.exec(state.data); + if (matchPartialCDataEnd) { + state.needData = true; + return; + } + if (!state.pendingText) { + state.pendingText = []; + } + state.pendingText.push(state.data.substr(state.pos, state.data.length)); + state.pos = state.data.length; + state.needData = true; + } else { + var text; + if (state.pendingText) { + state.pendingText.push(state.data.substring(state.pos, foundPos)); + text = state.pendingText.join(''); + state.pendingText = null; + } else { + text = state.data.substring(state.pos, foundPos); + } + this._write({ type: Mode.CData, data: text }); + state.mode = Mode.Text; + state.pos = foundPos + 3; + } + }; + + Parser.prototype._parseDoctype = function Parser$_parseDoctype () { + var state = this._state; + var foundPos = state.data.indexOf('>', state.pos); + if (foundPos < 0 && state.done) { + foundPos = state.data.length; + } + if (foundPos < 0) { + Parser.re_parseCData_findEnding.lastIndex = state.pos; + if (!state.pendingText) { + state.pendingText = []; + } + state.pendingText.push(state.data.substr(state.pos, state.data.length)); + state.pos = state.data.length; + state.needData = true; + } else { + var text; + if (state.pendingText) { + state.pendingText.push(state.data.substring(state.pos, foundPos)); + text = state.pendingText.join(''); + state.pendingText = null; + } else { + text = state.data.substring(state.pos, foundPos); + } + this._write({ type: Mode.Doctype, data: text }); + state.mode = Mode.Text; + state.pos = foundPos + 1; + } + }; + + Parser.re_parseComment_findEnding = /\-{1,2}$/; + Parser.prototype._parseComment = function Parser$_parseComment () { + var state = this._state; + var foundPos = state.data.indexOf('-->', state.pos); + if (foundPos < 0 && state.done) { + foundPos = state.data.length; + } + if (foundPos < 0) { + Parser.re_parseComment_findEnding.lastIndex = state.pos; + var matchPartialCommentEnd = Parser.re_parseComment_findEnding.exec(state.data); + if (matchPartialCommentEnd) { + state.needData = true; + return; + } + if (!state.pendingText) { + state.pendingText = []; + } + state.pendingText.push(state.data.substr(state.pos, state.data.length)); + state.pos = state.data.length; + state.needData = true; + } else { + var text; + if (state.pendingText) { + state.pendingText.push(state.data.substring(state.pos, foundPos)); + text = state.pendingText.join(''); + state.pendingText = null; + } else { + text = state.data.substring(state.pos, foundPos); + } + // state.output.push({ type: Mode.Comment, data: text }); + this._write({ type: Mode.Comment, data: text }); + state.mode = Mode.Text; + state.pos = foundPos + 3; + } + }; + + +function HtmlBuilder (callback, options) { + this.reset(); + this._options = options ? options : { }; + if (this._options.ignoreWhitespace === undefined) { + this._options.ignoreWhitespace = false; //Keep whitespace-only text nodes + } + if (this._options.includeLocation === undefined) { + this._options.includeLocation = false; //Include position of element (row, col) on nodes + } + if (this._options.verbose === undefined) { + this._options.verbose = true; //Keep data property for tags and raw property for all + } + if (this._options.enforceEmptyTags === undefined) { + this._options.enforceEmptyTags = true; //Don't allow children for HTML tags defined as empty in spec + } + if (this._options.caseSensitiveTags === undefined) { + this._options.caseSensitiveTags = false; //Lowercase all tag names + } + if (this._options.caseSensitiveAttr === undefined) { + this._options.caseSensitiveAttr = false; //Lowercase all attribute names + } + if ((typeof callback) == "function") { + this._callback = callback; + } +} + + //**"Static"**// + //HTML Tags that shouldn't contain child nodes + HtmlBuilder._emptyTags = { + area: 1 + , base: 1 + , basefont: 1 + , br: 1 + , col: 1 + , frame: 1 + , hr: 1 + , img: 1 + , input: 1 + , isindex: 1 + , link: 1 + , meta: 1 + , param: 1 + , embed: 1 + , '?xml': 1 + }; + //Regex to detect whitespace only text nodes + HtmlBuilder.reWhitespace = /^\s*$/; + + //**Public**// + //Properties// + HtmlBuilder.prototype.dom = null; //The hierarchical object containing the parsed HTML + //Methods// + //Resets the builder back to starting state + HtmlBuilder.prototype.reset = function HtmlBuilder$reset() { + this.dom = []; + // this._raw = []; + this._done = false; + this._tagStack = []; + this._lastTag = null; + this._tagStack.last = function HtmlBuilder$_tagStack$last () { + return(this.length ? this[this.length - 1] : null); + }; + this._line = 1; + this._col = 1; + }; + //Signals the builder that parsing is done + HtmlBuilder.prototype.done = function HtmlBuilder$done () { + this._done = true; + this.handleCallback(null); + }; + + HtmlBuilder.prototype.error = function HtmlBuilder$error (error) { + this.handleCallback(error); + }; + + HtmlBuilder.prototype.handleCallback = function HtmlBuilder$handleCallback (error) { + if ((typeof this._callback) != "function") { + if (error) { + throw error; + } else { + return; + } + } + this._callback(error, this.dom); + }; + + HtmlBuilder.prototype.isEmptyTag = function HtmlBuilder$isEmptyTag (element) { + var name = element.name.toLowerCase(); + if (name.charAt(0) == '?') { + return true; + } + if (name.charAt(0) == '/') { + name = name.substring(1); + } + return this._options.enforceEmptyTags && !!HtmlBuilder._emptyTags[name]; + }; + + HtmlBuilder.prototype._getLocation = function HtmlBuilder$_getLocation () { + return { line: this._line, col: this._col }; + }; + + // HtmlBuilder.reLineSplit = /(\r\n|\r|\n)/g; + HtmlBuilder.prototype._updateLocation = function HtmlBuilder$_updateLocation (node) { + var positionData = (node.type === Mode.Tag) ? node.raw : node.data; + if (positionData === null) { + return; + } + // var lines = positionData.split(HtmlBuilder.reLineSplit); + var lines = positionData.split("\n"); + this._line += lines.length - 1; + if (lines.length > 1) { + this._col = 1; + } + this._col += lines[lines.length - 1].length; + if (node.type === Mode.Tag) { + this._col += 2; + } else if (node.type === Mode.Comment) { + this._col += 7; + } else if (node.type === Mode.CData) { + this._col += 12; + } + }; + + HtmlBuilder.prototype._copyElement = function HtmlBuilder$_copyElement (element) { + var newElement = { type: element.type }; + + if (this._options.verbose && element['raw'] !== undefined) { + newElement.raw = element.raw; + } + if (element['name'] !== undefined) { + switch (element.type) { + + case Mode.Tag: + newElement.name = this._options.caseSensitiveTags ? + element.name + : + element.name.toLowerCase() + ; + break; + + case Mode.Attr: + newElement.name = this._options.caseSensitiveAttr ? + element.name + : + element.name.toLowerCase() + ; + break; + + default: + newElement.name = this._options.caseSensitiveTags ? + element.name + : + element.name.toLowerCase() + ; + break; + + } + } + if (element['data'] !== undefined) { + newElement.data = element.data; + } + if (element.location) { + newElement.location = { line: element.location.line, col: element.location.col }; + } + + return newElement; + }; + + HtmlBuilder.prototype.write = function HtmlBuilder$write (element) { + // this._raw.push(element); + if (this._done) { + this.handleCallback(new Error("Writing to the builder after done() called is not allowed without a reset()")); + } + if (this._options.includeLocation) { + if (element.type !== Mode.Attr) { + element.location = this._getLocation(); + this._updateLocation(element); + } + } + if (element.type === Mode.Text && this._options.ignoreWhitespace) { + if (HtmlBuilder.reWhitespace.test(element.data)) { + return; + } + } + var parent; + var node; + if (!this._tagStack.last()) { //There are no parent elements + //If the element can be a container, add it to the tag stack and the top level list + if (element.type === Mode.Tag) { + if (element.name.charAt(0) != "/") { //Ignore closing tags that obviously don't have an opening tag + node = this._copyElement(element); + this.dom.push(node); + if (!this.isEmptyTag(node)) { //Don't add tags to the tag stack that can't have children + this._tagStack.push(node); + } + this._lastTag = node; + } + } else if (element.type === Mode.Attr && this._lastTag) { + if (!this._lastTag.attributes) { + this._lastTag.attributes = {}; + } + this._lastTag.attributes[this._options.caseSensitiveAttr ? element.name : element.name.toLowerCase()] = + element.data; + } else { //Otherwise just add to the top level list + this.dom.push(this._copyElement(element)); + } + } else { //There are parent elements + //If the element can be a container, add it as a child of the element + //on top of the tag stack and then add it to the tag stack + if (element.type === Mode.Tag) { + if (element.name.charAt(0) == "/") { + //This is a closing tag, scan the tagStack to find the matching opening tag + //and pop the stack up to the opening tag's parent + var baseName = this._options.caseSensitiveTags ? + element.name.substring(1) + : + element.name.substring(1).toLowerCase() + ; + if (!this.isEmptyTag(element)) { + var pos = this._tagStack.length - 1; + while (pos > -1 && this._tagStack[pos--].name != baseName) { } + if (pos > -1 || this._tagStack[0].name == baseName) { + while (pos < this._tagStack.length - 1) { + this._tagStack.pop(); + } + } + } + } + else { //This is not a closing tag + parent = this._tagStack.last(); + if (element.type === Mode.Attr) { + if (!parent.attributes) { + parent.attributes = {}; + } + parent.attributes[this._options.caseSensitiveAttr ? element.name : element.name.toLowerCase()] = + element.data; + } else { + node = this._copyElement(element); + if (!parent.children) { + parent.children = []; + } + parent.children.push(node); + if (!this.isEmptyTag(node)) { //Don't add tags to the tag stack that can't have children + this._tagStack.push(node); + } + if (element.type === Mode.Tag) { + this._lastTag = node; + } + } + } + } + else { //This is not a container element + parent = this._tagStack.last(); + if (element.type === Mode.Attr) { + if (!parent.attributes) { + parent.attributes = {}; + } + parent.attributes[this._options.caseSensitiveAttr ? element.name : element.name.toLowerCase()] = + element.data; + } else { + if (!parent.children) { + parent.children = []; + } + parent.children.push(this._copyElement(element)); + } + } + } + }; + + + //**Private**// + //Properties// + HtmlBuilder.prototype._options = null; //Builder options for how to behave + HtmlBuilder.prototype._callback = null; //Callback to respond to when parsing done + HtmlBuilder.prototype._done = false; //Flag indicating whether builder has been notified of parsing completed + HtmlBuilder.prototype._tagStack = null; //List of parents to the currently element being processed + //Methods// + + +function RssBuilder (callback) { + RssBuilder.super_.call(this, callback, { ignoreWhitespace: true, verbose: false, enforceEmptyTags: false, caseSensitiveTags: true }); +} +inherits(RssBuilder, HtmlBuilder); + + RssBuilder.prototype.done = function RssBuilder$done () { + var feed = {}; + var feedRoot; + + var found = DomUtils.getElementsByTagName(function (value) { return(value == "rss" || value == "feed"); }, this.dom, false); + if (found.length) { + feedRoot = found[0]; + } + if (feedRoot) { + if (feedRoot.name == "rss") { + feed.type = "rss"; + feedRoot = feedRoot.children[0]; // + feed.id = ""; + try { + feed.title = DomUtils.getElementsByTagName("title", feedRoot.children, false)[0].children[0].data; + } catch (ex) { } + try { + feed.link = DomUtils.getElementsByTagName("link", feedRoot.children, false)[0].children[0].data; + } catch (ex) { } + try { + feed.description = DomUtils.getElementsByTagName("description", feedRoot.children, false)[0].children[0].data; + } catch (ex) { } + try { + feed.updated = new Date(DomUtils.getElementsByTagName("lastBuildDate", feedRoot.children, false)[0].children[0].data); + } catch (ex) { } + try { + feed.author = DomUtils.getElementsByTagName("managingEditor", feedRoot.children, false)[0].children[0].data; + } catch (ex) { } + feed.items = []; + DomUtils.getElementsByTagName("item", feedRoot.children).forEach(function (item, index, list) { + var entry = {}; + try { + entry.id = DomUtils.getElementsByTagName("guid", item.children, false)[0].children[0].data; + } catch (ex) { } + try { + entry.title = DomUtils.getElementsByTagName("title", item.children, false)[0].children[0].data; + } catch (ex) { } + try { + entry.link = DomUtils.getElementsByTagName("link", item.children, false)[0].children[0].data; + } catch (ex) { } + try { + entry.description = DomUtils.getElementsByTagName("description", item.children, false)[0].children[0].data; + } catch (ex) { } + try { + entry.pubDate = new Date(DomUtils.getElementsByTagName("pubDate", item.children, false)[0].children[0].data); + } catch (ex) { } + feed.items.push(entry); + }); + } else { + feed.type = "atom"; + try { + feed.id = DomUtils.getElementsByTagName("id", feedRoot.children, false)[0].children[0].data; + } catch (ex) { } + try { + feed.title = DomUtils.getElementsByTagName("title", feedRoot.children, false)[0].children[0].data; + } catch (ex) { } + try { + feed.link = DomUtils.getElementsByTagName("link", feedRoot.children, false)[0].attributes.href; + } catch (ex) { } + try { + feed.description = DomUtils.getElementsByTagName("subtitle", feedRoot.children, false)[0].children[0].data; + } catch (ex) { } + try { + feed.updated = new Date(DomUtils.getElementsByTagName("updated", feedRoot.children, false)[0].children[0].data); + } catch (ex) { } + try { + feed.author = DomUtils.getElementsByTagName("email", feedRoot.children, true)[0].children[0].data; + } catch (ex) { } + feed.items = []; + DomUtils.getElementsByTagName("entry", feedRoot.children).forEach(function (item, index, list) { + var entry = {}; + try { + entry.id = DomUtils.getElementsByTagName("id", item.children, false)[0].children[0].data; + } catch (ex) { } + try { + entry.title = DomUtils.getElementsByTagName("title", item.children, false)[0].children[0].data; + } catch (ex) { } + try { + entry.link = DomUtils.getElementsByTagName("link", item.children, false)[0].attributes.href; + } catch (ex) { } + try { + entry.description = DomUtils.getElementsByTagName("summary", item.children, false)[0].children[0].data; + } catch (ex) { } + try { + entry.pubDate = new Date(DomUtils.getElementsByTagName("updated", item.children, false)[0].children[0].data); + } catch (ex) { } + feed.items.push(entry); + }); + } + + this.dom = feed; + } + RssBuilder.super_.prototype.done.call(this); + }; + + var DomUtils = { + testElement: function DomUtils$testElement (options, element) { + if (!element) { + return false; + } + + for (var key in options) { + if (!options.hasOwnProperty(key)) { + continue; + } + if (key == "tag_name") { + if (element.type !== Mode.Tag) { + return false; + } + if (!options["tag_name"](element.name)) { + return false; + } + } else if (key == "tag_type") { + if (!options["tag_type"](element.type)) { + return false; + } + } else if (key == "tag_contains") { + if (element.type !== Mode.Text && element.type !== Mode.Comment && element.type !== Mode.CData) { + return false; + } + if (!options["tag_contains"](element.data)) { + return false; + } + } else { + if (!element.attributes || !options[key](element.attributes[key])) { + return false; + } + } + } + + return true; + } + + , getElements: function DomUtils$getElements (options, currentElement, recurse, limit) { + recurse = (recurse === undefined || recurse === null) || !!recurse; + limit = isNaN(parseInt(limit)) ? -1 : parseInt(limit); + + if (!currentElement) { + return([]); + } + + var found = []; + var elementList; + + function getTest (checkVal) { + return function (value) { + return(value == checkVal); + }; + } + for (var key in options) { + if ((typeof options[key]) != "function") { + options[key] = getTest(options[key]); + } + } + + if (DomUtils.testElement(options, currentElement)) { + found.push(currentElement); + } + + if (limit >= 0 && found.length >= limit) { + return(found); + } + + if (recurse && currentElement.children) { + elementList = currentElement.children; + } else if (currentElement instanceof Array) { + elementList = currentElement; + } else { + return(found); + } + + for (var i = 0; i < elementList.length; i++) { + found = found.concat(DomUtils.getElements(options, elementList[i], recurse, limit)); + if (limit >= 0 && found.length >= limit) { + break; + } + } + + return(found); + } + + , getElementById: function DomUtils$getElementById (id, currentElement, recurse) { + var result = DomUtils.getElements({ id: id }, currentElement, recurse, 1); + return(result.length ? result[0] : null); + } + + , getElementsByTagName: function DomUtils$getElementsByTagName (name, currentElement, recurse, limit) { + return(DomUtils.getElements({ tag_name: name }, currentElement, recurse, limit)); + } + + , getElementsByTagType: function DomUtils$getElementsByTagType (type, currentElement, recurse, limit) { + return(DomUtils.getElements({ tag_type: type }, currentElement, recurse, limit)); + } + }; + +exports.Parser = Parser; + +exports.HtmlBuilder = HtmlBuilder; + +exports.RssBuilder = RssBuilder; + +exports.ElementType = Mode; + +exports.DomUtils = DomUtils; + +})();