{"users":[{"id":115923,"username":"Discourse","name":null,"avatar_template":"/user_avatar/meta.discourse.org/discourse/{size}/148734_2.png","admin":true,"trust_level":4},{"id":100484,"username":"JammyDodger","name":"","avatar_template":"/user_avatar/meta.discourse.org/jammydodger/{size}/254611_2.png","trust_level":3},{"id":-1,"username":"system","name":"system","avatar_template":"/user_avatar/meta.discourse.org/system/{size}/443519_2.png","admin":true,"moderator":true,"trust_level":4},{"id":135392,"username":"NateDhaliwal","name":"Nate Dhaliwal","avatar_template":"/user_avatar/meta.discourse.org/natedhaliwal/{size}/313494_2.png","flair_name":"plugin_authors","flair_url":"plug","flair_bg_color":"dddddd","flair_color":"111111","flair_group_id":48,"trust_level":3},{"id":23163,"username":"j.jaffeux","name":"Joffrey Jaffeux","avatar_template":"/user_avatar/meta.discourse.org/j.jaffeux/{size}/60297_2.png","flair_name":"team","flair_url":"https://global.discourse-cdn.com/meta/original/3X/e/b/ebee30bd98aef20357e4a177a5a1e45b877ce088.svg","flair_color":"111","flair_group_id":47,"primary_group_name":"team","admin":true,"trust_level":2},{"id":2770,"username":"awesomerobot","name":"Kris","avatar_template":"/user_avatar/meta.discourse.org/awesomerobot/{size}/142900_2.png","flair_name":"team","flair_url":"https://global.discourse-cdn.com/meta/original/3X/e/b/ebee30bd98aef20357e4a177a5a1e45b877ce088.svg","flair_color":"111","flair_group_id":47,"primary_group_name":"team","admin":true,"trust_level":3},{"id":15209,"username":"pfaffman","name":"Jay Pfaffman","avatar_template":"/user_avatar/meta.discourse.org/pfaffman/{size}/120154_2.png","flair_name":"support-experts","flair_url":"https://global.discourse-cdn.com/meta/original/3X/e/2/e250ec403580530d19e6a9ed42d0d525a51a9dbe.svg","flair_bg_color":"FFFFFF","flair_group_id":142,"trust_level":4},{"id":27384,"username":"merefield","name":"Robert","avatar_template":"/user_avatar/meta.discourse.org/merefield/{size}/176214_2.png","trust_level":3},{"id":23968,"username":"david","name":"David Taylor","avatar_template":"/user_avatar/meta.discourse.org/david/{size}/157490_2.png","flair_name":"team","flair_url":"https://global.discourse-cdn.com/meta/original/3X/e/b/ebee30bd98aef20357e4a177a5a1e45b877ce088.svg","flair_color":"111","flair_group_id":47,"primary_group_name":"team","admin":true,"trust_level":3},{"id":406,"username":"RGJ","name":"Richard - Communiteq","avatar_template":"/user_avatar/meta.discourse.org/rgj/{size}/523185_2.png","flair_name":"support-experts","flair_url":"https://global.discourse-cdn.com/meta/original/3X/e/2/e250ec403580530d19e6a9ed42d0d525a51a9dbe.svg","flair_bg_color":"FFFFFF","flair_group_id":142,"trust_level":4},{"id":21029,"username":"pmusaraj","name":"Penar Musaraj","avatar_template":"/user_avatar/meta.discourse.org/pmusaraj/{size}/119489_2.png","flair_name":"team","flair_url":"https://global.discourse-cdn.com/meta/original/3X/e/b/ebee30bd98aef20357e4a177a5a1e45b877ce088.svg","flair_color":"111","flair_group_id":47,"primary_group_name":"team","admin":true,"trust_level":3},{"id":125035,"username":"misham","name":"Mykhailo","avatar_template":"/user_avatar/meta.discourse.org/misham/{size}/282796_2.png","trust_level":1},{"id":13378,"username":"angus","name":"Angus McLeod","avatar_template":"/user_avatar/meta.discourse.org/angus/{size}/341715_2.png","flair_name":"support-experts","flair_url":"https://global.discourse-cdn.com/meta/original/3X/e/2/e250ec403580530d19e6a9ed42d0d525a51a9dbe.svg","flair_bg_color":"FFFFFF","flair_group_id":142,"trust_level":4},{"id":66204,"username":"fzngagan","name":"Faizaan Gagan","avatar_template":"/user_avatar/meta.discourse.org/fzngagan/{size}/259349_2.png","flair_name":"team","flair_url":"https://global.discourse-cdn.com/meta/original/3X/e/b/ebee30bd98aef20357e4a177a5a1e45b877ce088.svg","flair_color":"111","flair_group_id":47,"primary_group_name":"team","admin":true,"trust_level":3},{"id":13900,"username":"thoka","name":"Thomas Kalka","avatar_template":"/user_avatar/meta.discourse.org/thoka/{size}/115652_2.png","trust_level":2},{"id":108265,"username":"pangbo","name":"","avatar_template":"/user_avatar/meta.discourse.org/pangbo/{size}/538562_2.png","trust_level":2},{"id":36685,"username":"Arkshine","name":"","avatar_template":"/user_avatar/meta.discourse.org/arkshine/{size}/298682_2.png","flair_name":"support-advocates","flair_url":"https://global.discourse-cdn.com/meta/original/3X/e/4/e4038d4d9848de2eabab38e17b8bdb69da154024.svg","flair_bg_color":"FFFFFF","flair_group_id":148,"trust_level":3},{"id":133750,"username":"Firepup650","name":"Firepup Sixfifty","avatar_template":"/user_avatar/meta.discourse.org/firepup650/{size}/465200_2.png","flair_name":"theme_authors","flair_url":"paintbrush","flair_bg_color":"ddd","flair_color":"111","flair_group_id":73,"trust_level":2},{"id":19,"username":"eviltrout","name":"Robin Ward","avatar_template":"/user_avatar/meta.discourse.org/eviltrout/{size}/5275_2.png","trust_level":4},{"id":8486,"username":"Nuck","name":"Emma Lejeck","avatar_template":"/user_avatar/meta.discourse.org/nuck/{size}/121732_2.png","trust_level":2},{"id":108257,"username":"MarkDoerr","name":"","avatar_template":"/user_avatar/meta.discourse.org/markdoerr/{size}/549630_2.png","flair_name":"team","flair_url":"https://global.discourse-cdn.com/meta/original/3X/e/b/ebee30bd98aef20357e4a177a5a1e45b877ce088.svg","flair_color":"111","flair_group_id":47,"primary_group_name":"team","admin":true,"trust_level":3},{"id":1,"username":"sam","name":"Sam Saffron","avatar_template":"/user_avatar/meta.discourse.org/sam/{size}/102149_2.png","flair_name":"team","flair_url":"https://global.discourse-cdn.com/meta/original/3X/e/b/ebee30bd98aef20357e4a177a5a1e45b877ce088.svg","flair_color":"111","flair_group_id":47,"primary_group_name":"team","admin":true,"trust_level":3},{"id":93320,"username":"swong","name":"Simon Wong","avatar_template":"https://avatars.discourse-cdn.com/v4/letter/s/a3d4f5/{size}.png","trust_level":2},{"id":57788,"username":"nathank","name":"Nathan Kershaw","avatar_template":"/user_avatar/meta.discourse.org/nathank/{size}/290039_2.png","flair_name":"support-advocates","flair_url":"https://global.discourse-cdn.com/meta/original/3X/e/4/e4038d4d9848de2eabab38e17b8bdb69da154024.svg","flair_bg_color":"FFFFFF","flair_group_id":148,"trust_level":4},{"id":91919,"username":"keegan","name":"Keegan George","avatar_template":"/user_avatar/meta.discourse.org/keegan/{size}/383395_2.png","flair_name":"team","flair_url":"https://global.discourse-cdn.com/meta/original/3X/e/b/ebee30bd98aef20357e4a177a5a1e45b877ce088.svg","flair_color":"111","flair_group_id":47,"primary_group_name":"team","admin":true,"trust_level":3},{"id":103315,"username":"Simon_Manning","name":"Simon Manning","avatar_template":"/user_avatar/meta.discourse.org/simon_manning/{size}/198596_2.png","trust_level":2},{"id":119375,"username":"elmuerte","name":"","avatar_template":"/user_avatar/meta.discourse.org/elmuerte/{size}/456517_2.png","trust_level":2},{"id":8617,"username":"Mittineague","name":"Mittineague","avatar_template":"/user_avatar/meta.discourse.org/mittineague/{size}/114259_2.png","trust_level":1},{"id":143688,"username":"davidag","name":"David","avatar_template":"/user_avatar/meta.discourse.org/davidag/{size}/363501_2.png","trust_level":1}],"primary_groups":[{"id":47,"name":"team"}],"flair_groups":[{"id":48,"name":"plugin_authors","flair_url":"plug","flair_bg_color":"dddddd","flair_color":"111111"},{"id":47,"name":"team","flair_url":"https://global.discourse-cdn.com/meta/original/3X/e/b/ebee30bd98aef20357e4a177a5a1e45b877ce088.svg","flair_bg_color":"","flair_color":"111"},{"id":142,"name":"support-experts","flair_url":"https://global.discourse-cdn.com/meta/original/3X/e/2/e250ec403580530d19e6a9ed42d0d525a51a9dbe.svg","flair_bg_color":"FFFFFF","flair_color":""},{"id":148,"name":"support-advocates","flair_url":"https://global.discourse-cdn.com/meta/original/3X/e/4/e4038d4d9848de2eabab38e17b8bdb69da154024.svg","flair_bg_color":"FFFFFF","flair_color":""},{"id":73,"name":"theme_authors","flair_url":"paintbrush","flair_bg_color":"ddd","flair_color":"111"}],"topic_list":{"can_create_topic":false,"filter":"latest","more_topics_url":"/c/documentation/developer-guides/56?page=1","per_page":30,"top_tags":[{"id":478,"name":"사용-방법","slug":"how-to"},{"id":820,"name":"테마-가이드","slug":"theme-guides"},{"id":819,"name":"코드","slug":"code"},{"id":274,"name":"플러그인-가이드","slug":"plugin-guides"},{"id":484,"name":"튜토리얼","slug":"tutorial"},{"id":150,"name":"개발용-설치","slug":"dev-install"},{"id":482,"name":"참고","slug":"reference"},{"id":479,"name":"설명","slug":"explanation"},{"id":70,"name":"잉거","slug":"ember"},{"id":58,"name":"테스트","slug":"testing"},{"id":543,"name":"ai","slug":"ai"},{"id":643,"name":"자동-다크","slug":"auto-dark"},{"id":275,"name":"자동화","slug":"automation"},{"id":436,"name":"css","slug":"css"},{"id":814,"name":"커스터마이징","slug":"customization"},{"id":24,"name":"docker","slug":"docker"},{"id":799,"name":"인덱스","slug":"index"},{"id":52,"name":"마크다운","slug":"markdown"},{"id":328,"name":"plugin-api","slug":"plugin-api"},{"id":566,"name":"테마-생성기","slug":"theme-creator"},{"id":16,"name":"번역","slug":"translation"},{"id":25,"name":"위키-게시물","slug":"wiki-posts"}],"topics":[{"fancy_title":"개발자 가이드 인덱스","fancy_title_localized":true,"locale":"en","id":308036,"title":"Developer Guides Index","slug":"developer-guides-index","posts_count":1,"reply_count":1,"highest_post_number":1,"image_url":null,"created_at":"2024-05-15T06:05:51.350Z","last_posted_at":"2024-05-15T06:05:51.457Z","bumped":true,"bumped_at":"2026-08-31T17:35:05.615Z","archetype":"regular","unseen":false,"pinned":true,"unpinned":null,"excerpt":"플러그인, 테마, 테마 구성 요소로 Discourse를 확장하고, 코어 코드와 작업하며, Discourse API를 사용하는 방법에 대한 문서입니다.\n도입부\n\n도입부: Discourse 개발 입문\n\n개발&hellip;","visible":true,"closed":true,"archived":false,"bookmarked":null,"liked":null,"thumbnails":null,"tags":[{"id":799,"name":"인덱스","slug":"index"}],"tags_descriptions":{"인덱스":"문서 카테고리 인덱스 주제."},"views":2202,"like_count":14,"has_summary":false,"last_poster_username":"Discourse","category_id":56,"op_like_count":14,"pinned_globally":false,"featured_link":null,"ai_topic_gist":null,"has_accepted_answer":false,"can_vote":false,"posters":[{"extras":"latest","description":"원본 게시자, 최근 게시자","user_id":115923,"primary_group_id":null,"flair_group_id":null},{"extras":null,"description":"Recent Poster","user_id":100484,"primary_group_id":null,"flair_group_id":null}]},{"fancy_title":"Using Transformers to customize client-side values and behavior","fancy_title_localized":false,"locale":null,"id":349954,"title":"Using Transformers to customize client-side values and behavior","slug":"using-transformers-to-customize-client-side-values-and-behavior","posts_count":3,"reply_count":0,"highest_post_number":3,"image_url":null,"created_at":"2025-01-31T20:19:51.229Z","last_posted_at":"2026-09-05T02:53:05.790Z","bumped":true,"bumped_at":"2026-09-05T02:53:05.790Z","archetype":"regular","unseen":false,"pinned":false,"unpinned":null,"excerpt":"Discourse core includes a number of “transformer” hooks which can be used to customize client behavior. These fall into two categories: \n\n\nValue Transformers take an output from Discourse core, and optionally modify it, &hellip;","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"thumbnails":null,"tags":[],"tags_descriptions":{},"views":729,"like_count":13,"has_summary":false,"last_poster_username":"NateDhaliwal","category_id":56,"op_like_count":10,"pinned_globally":false,"featured_link":null,"ai_topic_gist":"A user reported that the documentation for Discourse's client-side transformer hooks contains incorrect file path links, which should point to lib/registry/transformers.js instead of the non-existent lib/transformer/registry.js.","has_accepted_answer":false,"can_vote":false,"posters":[{"extras":null,"description":"원본 게시자","user_id":-1,"primary_group_id":null,"flair_group_id":null},{"extras":"latest","description":"최근 게시자","user_id":135392,"primary_group_id":null,"flair_group_id":48}]},{"fancy_title":"Discourse toolkit to render forms","fancy_title_localized":false,"locale":null,"id":326439,"title":"Discourse toolkit to render forms","slug":"discourse-toolkit-to-render-forms","posts_count":29,"reply_count":18,"highest_post_number":33,"image_url":null,"created_at":"2024-09-13T21:20:27.941Z","last_posted_at":"2025-12-23T17:55:56.356Z","bumped":true,"bumped_at":"2026-09-01T18:53:43.134Z","archetype":"regular","unseen":false,"pinned":false,"unpinned":null,"excerpt":"Basic Usage\nFormKit exposes a single component as its public API: &lt;Form /&gt;. All other elements are yielded as contextual components, modifiers, or plain data. \nEvery form is composed of one or multiple fields, represen&hellip;","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"thumbnails":null,"tags":[],"tags_descriptions":{},"views":1807,"like_count":55,"has_summary":false,"last_poster_username":"merefield","category_id":56,"op_like_count":6,"pinned_globally":false,"featured_link":null,"ai_topic_gist":"A discussion about correcting the parameter structure for the validateUsername function in FormKit, clarifying that it should accept { data, addError } instead of (name, value, data, { addError }) to avoid destructuring errors.","has_accepted_answer":false,"can_vote":false,"posters":[{"extras":null,"description":"원본 게시자","user_id":-1,"primary_group_id":null,"flair_group_id":null},{"extras":null,"description":"자주 게시하는 사용자","user_id":23163,"primary_group_id":47,"flair_group_id":47},{"extras":null,"description":"자주 게시하는 사용자","user_id":2770,"primary_group_id":47,"flair_group_id":47},{"extras":null,"description":"Recent Poster","user_id":15209,"primary_group_id":null,"flair_group_id":142},{"extras":"latest","description":"최근 게시자","user_id":27384,"primary_group_id":null,"flair_group_id":null}]},{"fancy_title":"The UI kit of shared Discourse components, helpers, and modifiers","fancy_title_localized":false,"locale":null,"id":411319,"title":"The UI kit of shared Discourse components, helpers, and modifiers","slug":"the-ui-kit-of-shared-discourse-components-helpers-and-modifiers","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2026-08-31T17:34:15.933Z","last_posted_at":"2026-08-31T17:34:16.178Z","bumped":true,"bumped_at":"2026-09-01T18:53:39.183Z","archetype":"regular","unseen":false,"pinned":false,"unpinned":null,"excerpt":"ui-kit is the layer of reusable, domain-free building blocks that core, plugins, and themes compose their interfaces from. It lives under frontend/discourse/app/ui-kit/ and ships three kinds of primitive: \n\nComponents:&hellip;","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"thumbnails":null,"tags":[],"tags_descriptions":{},"views":82,"like_count":3,"has_summary":false,"last_poster_username":"system","category_id":56,"op_like_count":3,"pinned_globally":false,"featured_link":null,"ai_topic_gist":"The ui-kit is Discourse's layer of reusable, domain-free UI primitives—components, helpers, and modifiers—imported from the discourse/ui-kit namespace, serving as public API for plugins and themes to compose interfaces.","has_accepted_answer":false,"can_vote":false,"posters":[{"extras":"latest single","description":"원본 게시자, 최근 게시자","user_id":-1,"primary_group_id":null,"flair_group_id":null}]},{"fancy_title":"Theme Developer Tutorial: 7. Wrapping up","fancy_title_localized":false,"locale":null,"id":357802,"title":"Theme Developer Tutorial: 7. Wrapping up","slug":"theme-developer-tutorial-7-wrapping-up","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2025-03-18T15:59:12.182Z","last_posted_at":"2025-03-18T15:59:12.273Z","bumped":true,"bumped_at":"2026-08-31T17:35:04.265Z","archetype":"regular","unseen":false,"pinned":false,"unpinned":null,"excerpt":"This tutorial has been a whistle-stop tour through the process of creating a Discourse theme and experimenting with a few of the most common APIs. Of course, there’s plenty more to learn, so let’s map out some more place&hellip;","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"thumbnails":null,"tags":[],"tags_descriptions":{},"views":352,"like_count":2,"has_summary":false,"last_poster_username":"system","category_id":56,"op_like_count":2,"pinned_globally":false,"featured_link":null,"ai_topic_gist":"This tutorial covered creating a Discourse theme, experimenting with APIs, and provided resources for further learning and exploration of theme development.","has_accepted_answer":false,"can_vote":false,"posters":[{"extras":"latest single","description":"원본 게시자, 최근 게시자","user_id":-1,"primary_group_id":null,"flair_group_id":null}]},{"fancy_title":"Drag, resize, and gesture primitives","fancy_title_localized":false,"locale":null,"id":410549,"title":"Drag, resize, and gesture primitives","slug":"drag-resize-and-gesture-primitives","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2026-08-20T16:44:51.931Z","last_posted_at":"2026-08-20T16:44:52.183Z","bumped":true,"bumped_at":"2026-08-31T17:35:02.656Z","archetype":"regular","unseen":false,"pinned":false,"unpinned":null,"excerpt":"ui-kit ships the input-driven gesture primitives: dragging a payload onto a \ntarget, resizing a region, and reading a swipe or a pointer drag. This page is \nthe usage reference. Each primitive’s own TSDoc carries the f&hellip;","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"thumbnails":null,"tags":[],"tags_descriptions":{},"views":91,"like_count":5,"has_summary":false,"last_poster_username":"system","category_id":56,"op_like_count":5,"pinned_globally":false,"featured_link":null,"ai_topic_gist":"The ui-kit documentation describes input-driven gesture primitives for drag-and-drop, resizing, and pointer tracking, detailing modifiers like dDragAndDropSource and dDragAndDropTarget, the dragAndDrop service, and related auto-scroll and monitor utilities.","has_accepted_answer":false,"can_vote":false,"posters":[{"extras":"latest single","description":"원본 게시자, 최근 게시자","user_id":-1,"primary_group_id":null,"flair_group_id":null}]},{"fancy_title":"Designing for Responsive Widths (Breakpoints, Viewport &amp; Containers)","fancy_title_localized":false,"locale":null,"id":409279,"title":"Designing for Responsive Widths (Breakpoints, Viewport & Containers)","slug":"designing-for-responsive-widths-breakpoints-viewport-containers","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2026-08-04T15:57:19.956Z","last_posted_at":"2026-08-04T15:57:20.124Z","bumped":true,"bumped_at":"2026-08-31T17:35:01.003Z","archetype":"regular","unseen":false,"pinned":false,"unpinned":null,"excerpt":"This document outlines the APIs used to adapt Discourse’s user interface to different widths — both the browser viewport, and individual containers on the page. \nWe design “mobile first” and then add customizations for l&hellip;","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"thumbnails":null,"tags":[],"tags_descriptions":{},"views":99,"like_count":3,"has_summary":false,"last_poster_username":"system","category_id":56,"op_like_count":3,"pinned_globally":false,"featured_link":null,"ai_topic_gist":"Discourse documentation outlines responsive design APIs, defining breakpoints for viewport and container queries to adapt UI layouts based on browser width or specific component sizes using SCSS mixins and Ember capabilities.","has_accepted_answer":false,"can_vote":false,"posters":[{"extras":"latest single","description":"원본 게시자, 최근 게시자","user_id":-1,"primary_group_id":null,"flair_group_id":null}]},{"fancy_title":"Designing for Different Devices (Touch &amp; Hover)","fancy_title_localized":false,"locale":null,"id":367810,"title":"Designing for Different Devices (Touch & Hover)","slug":"designing-for-different-devices-touch-hover","posts_count":15,"reply_count":11,"highest_post_number":15,"image_url":null,"created_at":"2025-05-27T18:17:05.719Z","last_posted_at":"2026-01-25T21:34:26.908Z","bumped":true,"bumped_at":"2026-08-31T17:34:59.184Z","archetype":"regular","unseen":false,"pinned":false,"unpinned":null,"excerpt":"This document outlines the APIs used to adapt Discourse’s user interface for different devices. \nTouch &amp; Hover\nSome devices only have touchscreens, some only have a traditional mouse pointer, and some have both. Importan&hellip;","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"thumbnails":null,"tags":[],"tags_descriptions":{},"views":1153,"like_count":26,"has_summary":false,"last_poster_username":"merefield","category_id":56,"op_like_count":13,"pinned_globally":false,"featured_link":null,"ai_topic_gist":"Discourse is phasing out legacy mobile/desktop modes in favor of viewport and touch detection; users discuss deprecating outdated classes like pull-left and adapting core components for responsive layouts across devices.","has_accepted_answer":false,"can_vote":false,"posters":[{"extras":null,"description":"원본 게시자","user_id":-1,"primary_group_id":null,"flair_group_id":null},{"extras":null,"description":"자주 게시하는 사용자","user_id":23968,"primary_group_id":47,"flair_group_id":47},{"extras":null,"description":"자주 게시하는 사용자","user_id":135392,"primary_group_id":null,"flair_group_id":48},{"extras":null,"description":"Recent Poster","user_id":406,"primary_group_id":null,"flair_group_id":142},{"extras":"latest","description":"최근 게시자","user_id":27384,"primary_group_id":null,"flair_group_id":null}]},{"fancy_title":"JavaScript type hinting &amp; validation (typescript)","fancy_title_localized":false,"locale":null,"id":395136,"title":"JavaScript type hinting & validation (typescript)","slug":"javascript-type-hinting-validation-typescript","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2026-02-04T10:38:25.830Z","last_posted_at":"2026-02-04T10:38:25.913Z","bumped":true,"bumped_at":"2026-08-31T17:34:58.115Z","archetype":"regular","unseen":false,"pinned":false,"unpinned":null,"excerpt":"Discourse ships type information for its JavaScript code. This can provide inline documentation, autocomplete, and other useful IDE features. It can also be used for some basic type validation, using the @ts-check direct&hellip;","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"thumbnails":null,"tags":[],"tags_descriptions":{},"views":213,"like_count":8,"has_summary":false,"last_poster_username":"system","category_id":56,"op_like_count":8,"pinned_globally":false,"featured_link":null,"ai_topic_gist":"Discourse provides JavaScript type information for IDE features and basic validation via @ts-check, requiring specific setup for .gjs files and plugins, with known limitations and workarounds.","has_accepted_answer":false,"can_vote":false,"posters":[{"extras":"latest single","description":"원본 게시자, 최근 게시자","user_id":-1,"primary_group_id":null,"flair_group_id":null}]},{"fancy_title":"Guidelines for CSS classes using BEM","fancy_title_localized":false,"locale":null,"id":361851,"title":"Guidelines for CSS classes using BEM","slug":"guidelines-for-css-classes-using-bem","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2025-04-15T05:48:23.418Z","last_posted_at":"2025-04-15T05:48:23.483Z","bumped":true,"bumped_at":"2026-08-31T17:34:57.108Z","archetype":"regular","unseen":false,"pinned":false,"unpinned":null,"excerpt":"Background\nWhen writing CSS classes for Discourse components, themes, or plugins, we follow a modified variant of Block Element Modifier (BEM). Following these guidelines will make it much less likely for CSS conflicts t&hellip;","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"thumbnails":null,"tags":[],"tags_descriptions":{},"views":360,"like_count":8,"has_summary":false,"last_poster_username":"system","category_id":56,"op_like_count":8,"pinned_globally":false,"featured_link":null,"ai_topic_gist":"Discourse uses a modified BEM variant for CSS classes, following specific syntax and guidelines to minimize conflicts and improve specificity.","has_accepted_answer":false,"can_vote":false,"posters":[{"extras":"latest single","description":"원본 게시자, 최근 게시자","user_id":-1,"primary_group_id":null,"flair_group_id":null}]},{"fancy_title":"Customizing the topic list","fancy_title_localized":false,"locale":null,"id":350411,"title":"Customizing the topic list","slug":"customizing-the-topic-list","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2025-02-04T10:40:33.076Z","last_posted_at":"2025-02-04T10:40:33.148Z","bumped":true,"bumped_at":"2026-08-31T17:34:55.904Z","archetype":"regular","unseen":false,"pinned":false,"unpinned":null,"excerpt":"The topic-list is one of the most-used and most-customized user-interfaces in Discourse. There are many different tools available to theme and plugin developers to achieve this customization, each with their own advantag&hellip;","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"thumbnails":null,"tags":[],"tags_descriptions":{},"views":834,"like_count":8,"has_summary":false,"last_poster_username":"system","category_id":56,"op_like_count":8,"pinned_globally":false,"featured_link":null,"ai_topic_gist":"Topic-list customization is commonly achieved through CSS, with other methods available via JS plugin API for adding, removing, and rearranging columns.","has_accepted_answer":false,"can_vote":false,"posters":[{"extras":"latest single","description":"원본 게시자, 최근 게시자","user_id":-1,"primary_group_id":null,"flair_group_id":null}]},{"fancy_title":"AppEvents Triggers Reference","fancy_title_localized":false,"locale":null,"id":338465,"title":"AppEvents Triggers Reference","slug":"appevents-triggers-reference","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2024-11-26T10:20:08.061Z","last_posted_at":"2024-11-26T10:20:08.461Z","bumped":true,"bumped_at":"2026-08-31T17:34:52.470Z","archetype":"regular","unseen":false,"pinned":false,"unpinned":null,"excerpt":"AppEvents\nThe AppEvent system in Discourse provides a pub/sub mechanism for handling UI updates and component interactions - and these events are triggered via calls of AppEvent.trigger. \nThis topic consolidates a list&hellip;","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"thumbnails":null,"tags":[],"tags_descriptions":{},"views":538,"like_count":10,"has_summary":false,"last_poster_username":"system","category_id":56,"op_like_count":10,"pinned_globally":false,"featured_link":null,"ai_topic_gist":"Discourse's AppEvent system provides a pub/sub mechanism for handling UI updates and component interactions, with events triggered via `AppEvent.trigger` calls, and this topic consolidates a list of event triggers and their arguments.","has_accepted_answer":false,"can_vote":false,"posters":[{"extras":"latest single","description":"원본 게시자, 최근 게시자","user_id":-1,"primary_group_id":null,"flair_group_id":null}]},{"fancy_title":"Write end-to-end system specs for the Discourse user interface","fancy_title_localized":false,"locale":null,"id":325937,"title":"Write end-to-end system specs for the Discourse user interface","slug":"write-end-to-end-system-specs-for-the-discourse-user-interface","posts_count":4,"reply_count":2,"highest_post_number":5,"image_url":"https://global.discourse-cdn.com/meta/original/4X/5/5/5/55573c386666cc876d212e64995fd6a7a8bccc64.png","created_at":"2024-09-11T04:07:31.148Z","last_posted_at":"2025-08-28T14:51:13.004Z","bumped":true,"bumped_at":"2026-08-31T17:34:46.127Z","archetype":"regular","unseen":false,"pinned":false,"unpinned":null,"excerpt":"Background\nRails system specs are used to simulate the actions of a real user using the app in a browser. We use the Playwright ruby driver which is becoming an industry standard. The tests run locally and in CI out of t&hellip;","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"thumbnails":[{"max_width":null,"max_height":null,"width":990,"height":602,"url":"https://global.discourse-cdn.com/meta/original/4X/5/5/5/55573c386666cc876d212e64995fd6a7a8bccc64.png"},{"max_width":800,"max_height":800,"width":800,"height":486,"url":"https://global.discourse-cdn.com/meta/optimized/4X/5/5/5/55573c386666cc876d212e64995fd6a7a8bccc64_2_800x486.png"},{"max_width":600,"max_height":600,"width":600,"height":364,"url":"https://global.discourse-cdn.com/meta/optimized/4X/5/5/5/55573c386666cc876d212e64995fd6a7a8bccc64_2_600x364.png"},{"max_width":400,"max_height":400,"width":400,"height":243,"url":"https://global.discourse-cdn.com/meta/optimized/4X/5/5/5/55573c386666cc876d212e64995fd6a7a8bccc64_2_400x243.png"},{"max_width":300,"max_height":300,"width":300,"height":182,"url":"https://global.discourse-cdn.com/meta/optimized/4X/5/5/5/55573c386666cc876d212e64995fd6a7a8bccc64_2_300x182.png"},{"max_width":200,"max_height":200,"width":200,"height":121,"url":"https://global.discourse-cdn.com/meta/optimized/4X/5/5/5/55573c386666cc876d212e64995fd6a7a8bccc64_2_200x121.png"}],"tags":[],"tags_descriptions":{},"views":709,"like_count":12,"has_summary":false,"last_poster_username":"merefield","category_id":56,"op_like_count":9,"pinned_globally":false,"featured_link":null,"ai_topic_gist":"A user encountered test failures due to missing color schemes in the test database, which was resolved by resetting the test database using migration commands after confirming the issue was with the local Discourse instance setup.","has_accepted_answer":false,"can_vote":false,"posters":[{"extras":null,"description":"원본 게시자","user_id":-1,"primary_group_id":null,"flair_group_id":null},{"extras":null,"description":"Recent Poster","user_id":21029,"primary_group_id":47,"flair_group_id":47},{"extras":"latest","description":"최근 게시자","user_id":27384,"primary_group_id":null,"flair_group_id":null}]},{"fancy_title":"Using service objects in Discourse","fancy_title_localized":false,"locale":null,"id":333641,"title":"Using service objects in Discourse","slug":"using-service-objects-in-discourse","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2024-10-30T15:56:38.400Z","last_posted_at":"2024-10-30T15:56:38.536Z","bumped":true,"bumped_at":"2026-08-31T17:34:44.010Z","archetype":"regular","unseen":false,"pinned":false,"unpinned":null,"excerpt":"Overview\nA service is a small object that encompasses business logic for a given action. \nFrom outside, it should be seen as a sort of black box. You provide it with parameters, it runs (including all the side effects it&hellip;","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"thumbnails":null,"tags":[],"tags_descriptions":{},"views":898,"like_count":17,"has_summary":false,"last_poster_username":"system","category_id":56,"op_like_count":17,"pinned_globally":false,"featured_link":null,"ai_topic_gist":"Service objects in Discourse encapsulate business logic as stateless, step-driven processes that handle input validation, error handling, and outcome matching, inspired by Trailblazer and dry-transaction.","has_accepted_answer":false,"can_vote":false,"posters":[{"extras":"latest single","description":"원본 게시자, 최근 게시자","user_id":-1,"primary_group_id":null,"flair_group_id":null}]},{"fancy_title":"(비권장) 테마 또는 플러그인에서 Discourse 템플릿 오버라이드","fancy_title_localized":true,"locale":"en","id":247487,"title":"(not recommended) Overriding Discourse templates from a Theme or Plugin","slug":"not-recommended-overriding-discourse-templates-from-a-theme-or-plugin","posts_count":10,"reply_count":6,"highest_post_number":14,"image_url":null,"created_at":"2022-12-02T13:52:58.399Z","last_posted_at":"2024-03-07T13:20:54.842Z","bumped":true,"bumped_at":"2026-08-31T17:34:42.109Z","archetype":"regular","unseen":false,"pinned":false,"unpinned":null,"excerpt":"이상적으로는 Discourse를 테마/플러그인으로 커스터마이징할 때 CSS, JavaScript 플러그인 API 또는 플러그인 아웃렛을 사용해야 합니다. 이 중 어느 것도 사용 사례에 맞지 않는다면, Discourse 코어에 PR을 열거나 <span class=\"hashtag-icon-placeholder\"></span>Devel&hellip;을 시작해 주세요.","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"thumbnails":null,"visibility_reason_id":4,"tags":[{"id":478,"name":"사용-방법","slug":"how-to"}],"tags_descriptions":{"사용-방법":"단계별 가이드는 특정 문제를 해결하기 위해 따를 단계를 포함합니다"},"views":2880,"like_count":42,"has_summary":false,"last_poster_username":"merefield","category_id":56,"op_like_count":17,"pinned_globally":false,"featured_link":null,"ai_topic_gist":null,"has_accepted_answer":false,"can_vote":false,"posters":[{"extras":null,"description":"원본 게시자","user_id":115923,"primary_group_id":null,"flair_group_id":null},{"extras":null,"description":"자주 게시하는 사용자","user_id":23968,"primary_group_id":47,"flair_group_id":47},{"extras":null,"description":"자주 게시하는 사용자","user_id":125035,"primary_group_id":null,"flair_group_id":null},{"extras":null,"description":"Recent Poster","user_id":100484,"primary_group_id":null,"flair_group_id":null},{"extras":"latest","description":"최근 게시자","user_id":27384,"primary_group_id":null,"flair_group_id":null}]},{"fancy_title":"ActiveRecord 모델의 우발적 직렬화 방지","fancy_title_localized":true,"locale":"en","id":314495,"title":"Preventing accidental serialization of ActiveRecord models","slug":"preventing-accidental-serialization-of-activerecord-models","posts_count":3,"reply_count":1,"highest_post_number":5,"image_url":null,"created_at":"2024-07-01T19:58:28.233Z","last_posted_at":"2024-07-23T17:59:58.860Z","bumped":true,"bumped_at":"2026-08-31T17:34:40.981Z","archetype":"regular","unseen":false,"pinned":false,"unpinned":null,"excerpt":"시리얼라이즈할 필드를 지정하지 않고 ActiveRecord 모델을 실수로 시리얼라이즈하는 것을 방지하기 위해 패치를 도입했습니다. 이 변경 사항은 포함할 필드를 우리가 제어할 수 있도록 하여 잠재적인 is&hellip;","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"thumbnails":null,"tags":[{"id":482,"name":"참고","slug":"reference"}],"tags_descriptions":{},"views":520,"like_count":12,"has_summary":false,"last_poster_username":"pfaffman","category_id":56,"op_like_count":6,"pinned_globally":false,"featured_link":null,"ai_topic_gist":null,"has_accepted_answer":false,"can_vote":false,"posters":[{"extras":null,"description":"원본 게시자","user_id":115923,"primary_group_id":null,"flair_group_id":null},{"extras":null,"description":"Recent Poster","user_id":13378,"primary_group_id":null,"flair_group_id":142},{"extras":"latest","description":"최근 게시자","user_id":15209,"primary_group_id":null,"flair_group_id":142}]},{"fancy_title":"Adding a new &lsquo;managed&rsquo; authentication method to Discourse","fancy_title_localized":false,"locale":"en","id":106695,"title":"Adding a new 'managed' authentication method to Discourse","slug":"adding-a-new-managed-authentication-method-to-discourse","posts_count":3,"reply_count":1,"highest_post_number":7,"image_url":null,"created_at":"2019-01-16T13:44:45.295Z","last_posted_at":"2023-11-29T07:48:14.411Z","bumped":true,"bumped_at":"2026-08-31T17:34:39.871Z","archetype":"regular","unseen":false,"pinned":false,"unpinned":null,"excerpt":"Continuing from Future Social Authentication Improvements… \nWe are now in the process of moving all ‘associated account’ information into a single database table. This will help to significantly reduce duplicated logic, &hellip;","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"thumbnails":null,"tags":[{"id":479,"name":"설명","slug":"explanation"}],"tags_descriptions":{},"views":3773,"like_count":30,"has_summary":false,"last_poster_username":"thoka","category_id":56,"op_like_count":23,"pinned_globally":false,"featured_link":null,"ai_topic_gist":null,"has_accepted_answer":false,"can_vote":false,"posters":[{"extras":null,"description":"원본 게시자","user_id":115923,"primary_group_id":null,"flair_group_id":null},{"extras":null,"description":"Recent Poster","user_id":66204,"primary_group_id":47,"flair_group_id":47},{"extras":"latest","description":"최근 게시자","user_id":13900,"primary_group_id":null,"flair_group_id":null}]},{"fancy_title":"Creating Routes in Discourse and Showing Data","fancy_title_localized":false,"locale":"en","id":48827,"title":"Creating Routes in Discourse and Showing Data","slug":"creating-routes-in-discourse-and-showing-data","posts_count":1,"reply_count":25,"highest_post_number":1,"image_url":null,"created_at":"2016-08-18T20:18:49.501Z","last_posted_at":"2016-08-18T20:18:49.572Z","bumped":true,"bumped_at":"2026-08-31T17:34:38.704Z","archetype":"regular","unseen":false,"pinned":false,"unpinned":null,"excerpt":"Over time Discourse has grown in complexity and it can be daunting for beginners to understand how data gets all the way from the back end Ruby on Rails application to the Ember.js application in front. \nThis tutorial is&hellip;","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"thumbnails":null,"tags":[{"id":484,"name":"튜토리얼","slug":"tutorial"},{"id":70,"name":"잉거","slug":"ember"}],"tags_descriptions":{"튜토리얼":""},"views":11893,"like_count":46,"has_summary":false,"last_poster_username":"Discourse","category_id":56,"op_like_count":46,"pinned_globally":false,"featured_link":null,"ai_topic_gist":null,"has_accepted_answer":false,"can_vote":false,"posters":[{"extras":"latest","description":"원본 게시자, 최근 게시자","user_id":115923,"primary_group_id":null,"flair_group_id":null},{"extras":null,"description":"Recent Poster","user_id":100484,"primary_group_id":null,"flair_group_id":null}]},{"fancy_title":"modifyClass를 사용하여 핵심 동작 변경","fancy_title_localized":true,"locale":"en","id":262064,"title":"Using modifyClass to change core behavior","slug":"using-modifyclass-to-change-core-behavior","posts_count":7,"reply_count":14,"highest_post_number":26,"image_url":null,"created_at":"2023-04-18T10:24:36.929Z","last_posted_at":"2026-03-04T07:13:43.215Z","bumped":true,"bumped_at":"2026-08-31T17:34:37.504Z","archetype":"regular","unseen":false,"pinned":false,"unpinned":null,"excerpt":"고급 테마와 플러그인의 경우, Discourse는 modifyClass 시스템을 제공합니다. 이를 통해 코어의 자바스크립트 클래스 중 상당수의 기능을 확장하고 오버라이드할 수 있습니다. \nmodifyClass를 사용할 때\nmodifyClass는 마지막 수단으로 사용해야 합니다…","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"thumbnails":null,"tags":[],"tags_descriptions":{},"views":2540,"like_count":34,"has_summary":false,"last_poster_username":"pangbo","category_id":56,"op_like_count":16,"pinned_globally":false,"featured_link":null,"ai_topic_gist":null,"has_accepted_answer":false,"can_vote":false,"posters":[{"extras":null,"description":"원본 게시자","user_id":115923,"primary_group_id":null,"flair_group_id":null},{"extras":null,"description":"자주 게시하는 사용자","user_id":23968,"primary_group_id":47,"flair_group_id":47},{"extras":null,"description":"Recent Poster","user_id":27384,"primary_group_id":null,"flair_group_id":null},{"extras":"latest","description":"최근 게시자","user_id":108265,"primary_group_id":null,"flair_group_id":null}]},{"fancy_title":"Using Plugin Outlet Connectors from a Theme or Plugin","fancy_title_localized":false,"locale":"en","id":32727,"title":"Using Plugin Outlet Connectors from a Theme or Plugin","slug":"using-plugin-outlet-connectors-from-a-theme-or-plugin","posts_count":13,"reply_count":29,"highest_post_number":46,"image_url":null,"created_at":"2015-08-31T07:35:05.423Z","last_posted_at":"2024-10-14T10:37:16.924Z","bumped":true,"bumped_at":"2026-08-31T17:34:36.287Z","archetype":"regular","unseen":false,"pinned":false,"unpinned":null,"excerpt":"Discourse includes hundreds of Plugin Outlets which can be used to inject new content or replace existing contend in the Discourse UI. ‘Outlet arguments’ are made available so that content can be customized based on the &hellip;","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"thumbnails":null,"tags":[{"id":478,"name":"사용-방법","slug":"how-to"},{"id":819,"name":"코드","slug":"code"}],"tags_descriptions":{"사용-방법":"단계별 가이드는 특정 문제를 해결하기 위해 따를 단계를 포함합니다"},"views":19034,"like_count":48,"has_summary":false,"last_poster_username":"david","category_id":56,"op_like_count":39,"pinned_globally":false,"featured_link":null,"ai_topic_gist":null,"has_accepted_answer":false,"can_vote":false,"posters":[{"extras":null,"description":"원본 게시자","user_id":115923,"primary_group_id":null,"flair_group_id":null},{"extras":null,"description":"자주 게시하는 사용자","user_id":36685,"primary_group_id":null,"flair_group_id":148},{"extras":null,"description":"자주 게시하는 사용자","user_id":133750,"primary_group_id":null,"flair_group_id":73},{"extras":null,"description":"Recent Poster","user_id":135392,"primary_group_id":null,"flair_group_id":48},{"extras":"latest","description":"최근 게시자","user_id":23968,"primary_group_id":47,"flair_group_id":47}]},{"fancy_title":"Using the JS API","fancy_title_localized":false,"locale":"en","id":41281,"title":"Using the JS API","slug":"using-the-js-api","posts_count":19,"reply_count":13,"highest_post_number":23,"image_url":null,"created_at":"2016-03-18T18:52:02.380Z","last_posted_at":"2026-01-30T07:30:33.717Z","bumped":true,"bumped_at":"2026-08-31T17:34:35.085Z","archetype":"regular","unseen":false,"pinned":false,"unpinned":null,"excerpt":"Discourse’s JavaScript API allows themes and plugins to make extensive customizations to the user experience. The simplest way to use it is to create a new theme from the admin panel, click “Edit Code”, and then head to &hellip;","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"thumbnails":null,"tags":[{"id":479,"name":"설명","slug":"explanation"},{"id":328,"name":"plugin-api","slug":"plugin-api"},{"id":819,"name":"코드","slug":"code"}],"tags_descriptions":{"plugin-api":"플러그인/테마에서 공개된 Discourse 메서드를 호출하는 방법"},"views":12409,"like_count":79,"has_summary":false,"last_poster_username":"MarkDoerr","category_id":56,"op_like_count":39,"pinned_globally":false,"featured_link":null,"ai_topic_gist":null,"has_accepted_answer":false,"can_vote":false,"posters":[{"extras":null,"description":"원본 게시자","user_id":115923,"primary_group_id":null,"flair_group_id":null},{"extras":null,"description":"자주 게시하는 사용자","user_id":19,"primary_group_id":null,"flair_group_id":null},{"extras":null,"description":"자주 게시하는 사용자","user_id":8486,"primary_group_id":null,"flair_group_id":null},{"extras":null,"description":"Recent Poster","user_id":135392,"primary_group_id":null,"flair_group_id":48},{"extras":"latest","description":"최근 게시자","user_id":108257,"primary_group_id":47,"flair_group_id":47}]},{"fancy_title":"DModal API를 사용하여 Discourse에서 모달 창(팝업/대화상자) 렌더링","fancy_title_localized":true,"locale":"en","id":268304,"title":"Using the DModal API to render Modal windows (aka popups/dialogs) in Discourse","slug":"using-the-dmodal-api-to-render-modal-windows-aka-popups-dialogs-in-discourse","posts_count":1,"reply_count":1,"highest_post_number":1,"image_url":"https://global.discourse-cdn.com/meta/original/4X/4/0/b/40be9a7c253202136882269ba77d47ad86bd6d35.png","created_at":"2023-07-03T09:52:06.275Z","last_posted_at":"2023-07-03T09:52:06.275Z","bumped":true,"bumped_at":"2026-08-31T17:34:33.839Z","archetype":"regular","unseen":false,"pinned":false,"unpinned":null,"excerpt":"Discourse 3.1.0.beta6에는 완전히 새로운 <DModal> 컴포넌트 기반 API가 포함되어 있습니다. DModal은 UI 키트의 일부이며 discourse/ui-kit/d-modal에서 가져옵니다.\n\n:information_source: 이 API는 이전의 컨트롤러 기반 API를 대체합니다. &hellip;","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"thumbnails":[{"max_width":null,"max_height":null,"width":696,"height":258,"url":"https://global.discourse-cdn.com/meta/original/4X/4/0/b/40be9a7c253202136882269ba77d47ad86bd6d35.png"},{"max_width":600,"max_height":600,"width":600,"height":222,"url":"https://global.discourse-cdn.com/meta/optimized/4X/4/0/b/40be9a7c253202136882269ba77d47ad86bd6d35_2_600x222.png"},{"max_width":400,"max_height":400,"width":400,"height":148,"url":"https://global.discourse-cdn.com/meta/optimized/4X/4/0/b/40be9a7c253202136882269ba77d47ad86bd6d35_2_400x148.png"},{"max_width":300,"max_height":300,"width":300,"height":111,"url":"https://global.discourse-cdn.com/meta/optimized/4X/4/0/b/40be9a7c253202136882269ba77d47ad86bd6d35_2_300x111.png"},{"max_width":200,"max_height":200,"width":200,"height":74,"url":"https://global.discourse-cdn.com/meta/optimized/4X/4/0/b/40be9a7c253202136882269ba77d47ad86bd6d35_2_200x74.png"}],"tags":[{"id":819,"name":"코드","slug":"code"}],"tags_descriptions":{},"views":2208,"like_count":17,"has_summary":false,"last_poster_username":"Discourse","category_id":56,"op_like_count":17,"pinned_globally":false,"featured_link":null,"ai_topic_gist":null,"has_accepted_answer":false,"can_vote":false,"posters":[{"extras":"latest","description":"원본 게시자, 최근 게시자","user_id":115923,"primary_group_id":null,"flair_group_id":null},{"extras":null,"description":"Recent Poster","user_id":1,"primary_group_id":47,"flair_group_id":47}]},{"fancy_title":"레거시 컨트롤러의 모달을 새로운 DModal 컴포넌트 API로 변환하기","fancy_title_localized":true,"locale":"en","id":268057,"title":"Converting modals from legacy controllers to new DModal component API","slug":"converting-modals-from-legacy-controllers-to-new-dmodal-component-api","posts_count":10,"reply_count":5,"highest_post_number":15,"image_url":null,"created_at":"2023-07-03T09:52:14.660Z","last_posted_at":"2023-11-07T17:05:46.015Z","bumped":true,"bumped_at":"2026-08-31T17:34:31.889Z","archetype":"regular","unseen":false,"pinned":false,"unpinned":null,"excerpt":":information_source: 새로운 Modal을 구현하고 있다면, 여기 있는 주요 문서를 확인하세요. 이 주제는 기존 컨트롤러 기반 Modal을 새로운 컴포넌트 기반 API로 마이그레이션하는 방법에 대해 설명합니다.\n\n과거에 Discourse는&hellip;","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"thumbnails":null,"tags":[{"id":819,"name":"코드","slug":"code"}],"tags_descriptions":{},"views":5452,"like_count":47,"has_summary":false,"last_poster_username":"keegan","category_id":56,"op_like_count":20,"pinned_globally":false,"featured_link":null,"ai_topic_gist":null,"has_accepted_answer":false,"can_vote":false,"posters":[{"extras":null,"description":"원본 게시자","user_id":115923,"primary_group_id":null,"flair_group_id":null},{"extras":null,"description":"자주 게시하는 사용자","user_id":93320,"primary_group_id":null,"flair_group_id":null},{"extras":null,"description":"자주 게시하는 사용자","user_id":27384,"primary_group_id":null,"flair_group_id":null},{"extras":null,"description":"Recent Poster","user_id":57788,"primary_group_id":null,"flair_group_id":148},{"extras":"latest","description":"최근 게시자","user_id":91919,"primary_group_id":47,"flair_group_id":47}]},{"fancy_title":"Developer&rsquo;s guide to Markdown extensions","fancy_title_localized":false,"locale":"en","id":66023,"title":"Developer's guide to Markdown extensions","slug":"developers-guide-to-markdown-extensions","posts_count":2,"reply_count":13,"highest_post_number":24,"image_url":null,"created_at":"2017-07-11T21:23:25.941Z","last_posted_at":"2026-06-01T08:45:53.539Z","bumped":true,"bumped_at":"2026-08-31T17:34:30.628Z","archetype":"regular","unseen":false,"pinned":false,"unpinned":null,"excerpt":"Discourse uses a Markdown engine called Markdown-it. \nHere are some dev notes that will help you either fix bugs in core or create your new plugins. \nThe Basics\nDiscourse only contains a few helpers on top of the engine,&hellip;","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"thumbnails":null,"tags":[{"id":482,"name":"참고","slug":"reference"},{"id":52,"name":"마크다운","slug":"markdown"},{"id":819,"name":"코드","slug":"code"}],"tags_descriptions":{},"views":13686,"like_count":35,"has_summary":false,"last_poster_username":"NateDhaliwal","category_id":56,"op_like_count":35,"pinned_globally":false,"featured_link":null,"ai_topic_gist":null,"has_accepted_answer":false,"can_vote":false,"posters":[{"extras":null,"description":"원본 게시자","user_id":115923,"primary_group_id":null,"flair_group_id":null},{"extras":"latest","description":"최근 게시자","user_id":135392,"primary_group_id":null,"flair_group_id":48}]},{"fancy_title":"GitHub Actions를 사용하여 지속적 통합 설정하기","fancy_title_localized":true,"locale":"en","id":240150,"title":"Setup Continuous Integration using GitHub Actions","slug":"setup-continuous-integration-using-github-actions","posts_count":9,"reply_count":3,"highest_post_number":13,"image_url":"https://global.discourse-cdn.com/meta/optimized/4X/8/0/b/80b44095b66c3bb7b94b1c51c2b0cebfa9b955ba_2_1024x475.png","created_at":"2022-09-28T15:52:57.063Z","last_posted_at":"2025-03-03T09:12:26.800Z","bumped":true,"bumped_at":"2026-08-31T17:34:29.020Z","archetype":"regular","unseen":false,"pinned":false,"unpinned":null,"excerpt":":mag: 개요\nDiscourse용 견고한 확장 기능을 구축하려면 플러그인이나 테마 컴포넌트에 지속적 통합(CI)을 포함하는 것이 현명할 수 있습니다. 이를 통해 오류를 조기에 감지하고 버그 발생 가능성을 줄일 수 있습니다&hellip;","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"thumbnails":[{"max_width":null,"max_height":null,"width":2192,"height":1018,"url":"https://global.discourse-cdn.com/meta/original/4X/8/0/b/80b44095b66c3bb7b94b1c51c2b0cebfa9b955ba.png"},{"max_width":1024,"max_height":1024,"width":1024,"height":475,"url":"https://global.discourse-cdn.com/meta/optimized/4X/8/0/b/80b44095b66c3bb7b94b1c51c2b0cebfa9b955ba_2_1024x475.png"},{"max_width":800,"max_height":800,"width":800,"height":371,"url":"https://global.discourse-cdn.com/meta/optimized/4X/8/0/b/80b44095b66c3bb7b94b1c51c2b0cebfa9b955ba_2_800x371.png"},{"max_width":600,"max_height":600,"width":600,"height":278,"url":"https://global.discourse-cdn.com/meta/optimized/4X/8/0/b/80b44095b66c3bb7b94b1c51c2b0cebfa9b955ba_2_600x278.png"},{"max_width":400,"max_height":400,"width":400,"height":185,"url":"https://global.discourse-cdn.com/meta/optimized/4X/8/0/b/80b44095b66c3bb7b94b1c51c2b0cebfa9b955ba_2_400x185.png"},{"max_width":300,"max_height":300,"width":300,"height":139,"url":"https://global.discourse-cdn.com/meta/optimized/4X/8/0/b/80b44095b66c3bb7b94b1c51c2b0cebfa9b955ba_2_300x139.png"},{"max_width":200,"max_height":200,"width":200,"height":92,"url":"https://global.discourse-cdn.com/meta/optimized/4X/8/0/b/80b44095b66c3bb7b94b1c51c2b0cebfa9b955ba_2_200x92.png"}],"tags":[{"id":478,"name":"사용-방법","slug":"how-to"},{"id":819,"name":"코드","slug":"code"}],"tags_descriptions":{"사용-방법":"단계별 가이드는 특정 문제를 해결하기 위해 따를 단계를 포함합니다"},"views":1667,"like_count":39,"has_summary":false,"last_poster_username":"merefield","category_id":56,"op_like_count":15,"pinned_globally":false,"featured_link":null,"ai_topic_gist":null,"has_accepted_answer":false,"can_vote":false,"posters":[{"extras":null,"description":"원본 게시자","user_id":115923,"primary_group_id":null,"flair_group_id":null},{"extras":null,"description":"자주 게시하는 사용자","user_id":103315,"primary_group_id":null,"flair_group_id":null},{"extras":null,"description":"자주 게시하는 사용자","user_id":91919,"primary_group_id":47,"flair_group_id":47},{"extras":null,"description":"Recent Poster","user_id":23968,"primary_group_id":47,"flair_group_id":47},{"extras":"latest","description":"최근 게시자","user_id":27384,"primary_group_id":null,"flair_group_id":null}]},{"fancy_title":"구글의 &lsquo;tachometer&rsquo;를 사용해 Discourse의 JS 성능 변화를 측정하기","fancy_title_localized":true,"locale":"en","id":281158,"title":"Using Google's 'tachometer' to measure JS performance changes in Discourse","slug":"using-googles-tachometer-to-measure-js-performance-changes-in-discourse","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":"https://global.discourse-cdn.com/meta/optimized/4X/3/6/6/36680bd5dd66b51a4f85d3c70d2fbe250628bc85_2_1024x512.png","created_at":"2023-10-05T13:57:29.422Z","last_posted_at":"2023-10-05T13:57:29.614Z","bumped":true,"bumped_at":"2026-08-31T17:34:27.866Z","archetype":"regular","unseen":false,"pinned":false,"unpinned":null,"excerpt":"Discore 코어/플러그인/테마에서 클라이언트 사이드 작업을 수행할 때 성능 영향을 고려하는 것이 중요합니다. Google의 ‘Tachometer’ 프로젝트는 통계적으로 엄격한 벤치마킹 도구를 제공하며, 이를 통해 ...를 사용할 수 있습니다.","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"thumbnails":[{"max_width":null,"max_height":null,"width":1200,"height":600,"url":"https://global.discourse-cdn.com/meta/original/4X/3/6/6/36680bd5dd66b51a4f85d3c70d2fbe250628bc85.png"},{"max_width":1024,"max_height":1024,"width":1024,"height":512,"url":"https://global.discourse-cdn.com/meta/optimized/4X/3/6/6/36680bd5dd66b51a4f85d3c70d2fbe250628bc85_2_1024x512.png"},{"max_width":800,"max_height":800,"width":800,"height":400,"url":"https://global.discourse-cdn.com/meta/optimized/4X/3/6/6/36680bd5dd66b51a4f85d3c70d2fbe250628bc85_2_800x400.png"},{"max_width":600,"max_height":600,"width":600,"height":300,"url":"https://global.discourse-cdn.com/meta/optimized/4X/3/6/6/36680bd5dd66b51a4f85d3c70d2fbe250628bc85_2_600x300.png"},{"max_width":400,"max_height":400,"width":400,"height":200,"url":"https://global.discourse-cdn.com/meta/optimized/4X/3/6/6/36680bd5dd66b51a4f85d3c70d2fbe250628bc85_2_400x200.png"},{"max_width":300,"max_height":300,"width":300,"height":150,"url":"https://global.discourse-cdn.com/meta/optimized/4X/3/6/6/36680bd5dd66b51a4f85d3c70d2fbe250628bc85_2_300x150.png"},{"max_width":200,"max_height":200,"width":200,"height":100,"url":"https://global.discourse-cdn.com/meta/optimized/4X/3/6/6/36680bd5dd66b51a4f85d3c70d2fbe250628bc85_2_200x100.png"}],"tags":[{"id":819,"name":"코드","slug":"code"}],"tags_descriptions":{},"views":1053,"like_count":17,"has_summary":false,"last_poster_username":"Discourse","category_id":56,"op_like_count":17,"pinned_globally":false,"featured_link":null,"ai_topic_gist":null,"has_accepted_answer":false,"can_vote":false,"posters":[{"extras":"latest single","description":"원본 게시자, 최근 게시자","user_id":115923,"primary_group_id":null,"flair_group_id":null}]},{"fancy_title":"Ember 객체 소유권 (getOwner, 서비스 주입 등)","fancy_title_localized":true,"locale":"en","id":292080,"title":"Ember object ownership (getOwner, service injections, etc.)","slug":"ember-object-ownership-getowner-service-injections-etc","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2024-01-19T13:28:42.440Z","last_posted_at":"2024-01-19T13:28:42.440Z","bumped":true,"bumped_at":"2026-08-31T17:34:26.609Z","archetype":"regular","unseen":false,"pinned":false,"unpinned":null,"excerpt":":warning: discourse-common/lib/get-owner에서 getOwner를 가져오는 것은 더 이상 권장되지 않습니다.\n\n예를 들어 서비스에는 사용할 수 있는 몇 가지 방법이 있습니다.\n\n\n컴포넌트/컨트롤러/루트에서는 서비스 주입을 사용해야 합니다 &hellip;","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"thumbnails":null,"tags":[{"id":819,"name":"코드","slug":"code"}],"tags_descriptions":{},"views":1501,"like_count":7,"has_summary":false,"last_poster_username":"Discourse","category_id":56,"op_like_count":7,"pinned_globally":false,"featured_link":null,"ai_topic_gist":null,"has_accepted_answer":false,"can_vote":false,"posters":[{"extras":"latest single","description":"원본 게시자, 최근 게시자","user_id":115923,"primary_group_id":null,"flair_group_id":null}]},{"fancy_title":"구형 Discourse 설치에서 플러그인 및 테마 버전 고정 (d-compat 브랜치)","fancy_title_localized":true,"locale":"en","id":272665,"title":"Pinning plugin and theme versions for older Discourse installs (d-compat branches)","slug":"pinning-plugin-and-theme-versions-for-older-discourse-installs-d-compat-branches","posts_count":7,"reply_count":5,"highest_post_number":9,"image_url":null,"created_at":"2023-07-26T10:00:42.315Z","last_posted_at":"2026-07-17T10:56:56.339Z","bumped":true,"bumped_at":"2026-08-31T17:34:24.825Z","archetype":"regular","unseen":false,"pinned":false,"unpinned":null,"excerpt":":open_book: 배경\n테마 및 플러그인 개발자는 일반적으로 Discourse의 최신 릴리스를 대상으로 개발하되, 하위 호환성에 대해서는 걱정하지 않기를 원합니다. 하지만 구형 Discourse 릴리스를 실행 중인 사이트에는 여전히 특정 버전이 필요합니다&hellip;","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"thumbnails":null,"tags":[],"tags_descriptions":{},"views":1581,"like_count":31,"has_summary":false,"last_poster_username":"david","category_id":56,"op_like_count":17,"pinned_globally":false,"featured_link":null,"ai_topic_gist":null,"has_accepted_answer":false,"can_vote":false,"posters":[{"extras":null,"description":"원본 게시자","user_id":115923,"primary_group_id":null,"flair_group_id":null},{"extras":null,"description":"자주 게시하는 사용자","user_id":135392,"primary_group_id":null,"flair_group_id":48},{"extras":null,"description":"Recent Poster","user_id":119375,"primary_group_id":null,"flair_group_id":null},{"extras":"latest","description":"최근 게시자","user_id":23968,"primary_group_id":47,"flair_group_id":47}]},{"fancy_title":"How to run Discourse core, plugin and theme QUnit test suites","fancy_title_localized":false,"locale":"en","id":66857,"title":"How to run Discourse core, plugin and theme QUnit test suites","slug":"how-to-run-discourse-core-plugin-and-theme-qunit-test-suites","posts_count":1,"reply_count":2,"highest_post_number":1,"image_url":null,"created_at":"2017-07-26T14:09:58.032Z","last_posted_at":"2017-07-26T14:09:58.126Z","bumped":true,"bumped_at":"2026-08-31T17:34:23.607Z","archetype":"regular","unseen":false,"pinned":false,"unpinned":null,"excerpt":"Discourse has extensive frontend tests for core, plugins and themes. Once you have a functioning local development environment, those tests can be run locally in a number of different ways. \nRunning tests in the browser\nC&hellip;","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"thumbnails":null,"tags":[{"id":478,"name":"사용-방법","slug":"how-to"},{"id":819,"name":"코드","slug":"code"}],"tags_descriptions":{"사용-방법":"단계별 가이드는 특정 문제를 해결하기 위해 따를 단계를 포함합니다"},"views":2846,"like_count":20,"has_summary":false,"last_poster_username":"Discourse","category_id":56,"op_like_count":20,"pinned_globally":false,"featured_link":null,"ai_topic_gist":null,"has_accepted_answer":false,"can_vote":false,"posters":[{"extras":"latest single","description":"원본 게시자, 최근 게시자","user_id":115923,"primary_group_id":null,"flair_group_id":null}]},{"fancy_title":"Write acceptance tests and component tests for Ember code in Discourse","fancy_title_localized":false,"locale":"en","id":49167,"title":"Write acceptance tests and component tests for Ember code in Discourse","slug":"write-acceptance-tests-and-component-tests-for-ember-code-in-discourse","posts_count":4,"reply_count":1,"highest_post_number":4,"image_url":null,"created_at":"2016-08-24T20:48:02.492Z","last_posted_at":"2024-02-23T12:42:10.452Z","bumped":true,"bumped_at":"2026-08-31T17:34:22.443Z","archetype":"regular","unseen":false,"pinned":false,"unpinned":null,"excerpt":"Automated tests are a great way to protect your code against future regressions. Many people are familiar with how to do this in our Rails codebase with rspec, but the Javascript side can be somewhat of an enigma to some&hellip;","visible":true,"closed":false,"archived":false,"bookmarked":null,"liked":null,"thumbnails":null,"tags":[{"id":819,"name":"코드","slug":"code"},{"id":484,"name":"튜토리얼","slug":"tutorial"},{"id":70,"name":"잉거","slug":"ember"},{"id":58,"name":"테스트","slug":"testing"}],"tags_descriptions":{"튜토리얼":""},"views":4346,"like_count":23,"has_summary":false,"last_poster_username":"davidag","category_id":56,"op_like_count":15,"pinned_globally":false,"featured_link":null,"ai_topic_gist":null,"has_accepted_answer":false,"can_vote":false,"posters":[{"extras":null,"description":"원본 게시자","user_id":115923,"primary_group_id":null,"flair_group_id":null},{"extras":null,"description":"자주 게시하는 사용자","user_id":8617,"primary_group_id":null,"flair_group_id":null},{"extras":null,"description":"Recent Poster","user_id":19,"primary_group_id":null,"flair_group_id":null},{"extras":"latest","description":"최근 게시자","user_id":143688,"primary_group_id":null,"flair_group_id":null}]}]}}