Skip to content

Commit a92695d

Browse files
authored
Add category support for Gallery extensions (#132)
* Add category support for extensions * Add category linting * Add category instructions in CONTRIBUTING * Use id for category rather than title * Replace Jump Start tag with example category * List Extensions first in categories * Document the order of categories matters * Lowercase category titles
1 parent 1cebbea commit a92695d

File tree

19 files changed

+144
-67
lines changed

19 files changed

+144
-67
lines changed

.github/actions/lint-extension/action.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,35 @@ runs:
6565
fi
6666
shell: bash
6767

68+
# Ensures that the manifest.json category is valid
69+
- name: Check category
70+
run: |
71+
# Read in valid category IDs from extensions.json
72+
VALID_CATEGORY_IDS=$(jq -c '[.categories[] | .id]' ./extensions.json)
73+
74+
# Read in category from the extension's manifest.json
75+
EXTENSION_CATEGORY=$(jq -r '.extension.category // ""' ./extensions/${{ inputs.extension-name }}/manifest.json)
76+
77+
# If the extension's category is empty, skip validation
78+
if [ -z "$EXTENSION_CATEGORY" ]; then
79+
echo "No category specified in manifest.json"
80+
exit 0
81+
fi
82+
83+
# Check if extension category is in the valid categories ID list
84+
CATEGORY_VALID=$(jq -n --argjson global "$VALID_CATEGORY_IDS" --arg category "$EXTENSION_CATEGORY" '
85+
$global | index($category) != null
86+
')
87+
88+
# Check if the category is valid
89+
if [ "$CATEGORY_VALID" != "true" ]; then
90+
echo "Error: The category '$EXTENSION_CATEGORY' in manifest.json is not defined in extensions.json"
91+
echo "Valid categories are: $(jq -r 'join(", ")' <<< "$VALID_CATEGORY_IDS")"
92+
echo "Please use one of the valid category IDs or add a new category to the 'categories' array in extensions.json."
93+
exit 1
94+
fi
95+
shell: bash
96+
6897
# Ensures that the manifest.json has only valid tags
6998
- name: Check tags
7099
run: |

CONTRIBUTING.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ to the `manifest.json`:
4040
"title": "My Content Name",
4141
"description": "A lovely, detailed description of the content.",
4242
"homepage": "https://github.com/posit-dev/connect-extensions/tree/main/extensions/my-content-name",
43+
"category": "",
4344
"tags": [],
4445
"minimumConnectVersion": "2025.04.0",
4546
"version": "0.0.0"
@@ -51,6 +52,30 @@ It is recommended to begin with `"version": "0.0.0"` to avoid triggering a
5152
release during development of your content. When you are ready to release to
5253
the gallery check the [Adding content to the Connect Gallery](#adding-content-to-the-connect-gallery) section.
5354

55+
#### Category
56+
57+
The `category` field in the `extension` section of the `manifest.json` is
58+
required to group content in the Gallery.
59+
60+
```json
61+
// manifest.json
62+
63+
{
64+
...
65+
"extension": {
66+
"category": "extension,
67+
...
68+
}
69+
}
70+
```
71+
72+
Available categories are listed in the [`extensions.json`](./extensions.json)
73+
file. The category should match the `id`, and automations in the repository
74+
will check that the category is valid.
75+
76+
The order of the categories in [`extensions.json`](./extensions.json) determines
77+
the order in which they are displayed in the Connect Gallery.
78+
5479
#### Tags
5580

5681
The `tags` array in the `extension` section of the `manifest.json` is optional,

extensions.json

Lines changed: 43 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
11
{
2-
"tags": [
3-
"Jump Start"
2+
"categories": [
3+
{
4+
"id": "extension",
5+
"title": "extensions",
6+
"description": "Useful tools that utilize the Posit Connect API to extend the functionality of Connect."
7+
},
8+
{
9+
"id": "example",
10+
"title": "examples",
11+
"description": "Pre-built content to illustrate the types of content publishable on Posit Connect."
12+
}
413
],
14+
"tags": [],
515
"requiredFeatures": [
616
"API Publishing",
717
"OAuth Integrations",
@@ -13,6 +23,7 @@
1323
"title": "Connect Widgets Example",
1424
"description": "connectwidgets is an R package that can be used to query for a subset of your existing content items, then organize them within htmlwidget components in an R Markdown document or Shiny application.",
1525
"homepage": "https://github.com/posit-dev/connect-extensions/tree/main/extensions/connectwidgets-example",
26+
"category": "example",
1627
"latestVersion": {
1728
"version": "0.0.1",
1829
"released": "2025-04-24T19:17:16Z",
@@ -37,15 +48,14 @@
3748
}
3849
}
3950
],
40-
"tags": [
41-
"Jump Start"
42-
]
51+
"tags": []
4352
},
4453
{
4554
"name": "fastapitableau-example",
4655
"title": "Tableau Python Extension",
4756
"description": "fastapitableau is a Python package that enables Python developers to build FastAPI APIs that function as Tableau Analytics Extensions. These extensions can be leveraged from Tableau workbooks to allow real time requests from Tableau to Python. This extension builds on top of Tableau's example Superstore dataset.",
4857
"homepage": "https://github.com/posit-dev/connect-extensions/tree/main/extensions/fastapitableau-example",
58+
"category": "example",
4959
"latestVersion": {
5060
"version": "1.0.0",
5161
"released": "2025-04-24T19:38:18Z",
@@ -76,15 +86,14 @@
7686
}
7787
}
7888
],
79-
"tags": [
80-
"Jump Start"
81-
]
89+
"tags": []
8290
},
8391
{
8492
"name": "landing-page",
8593
"title": "Static HTML landing page",
8694
"description": "A simple static HTML web page that can be served from Connect",
8795
"homepage": "https://github.com/posit-dev/connect-extensions/tree/main/extensions/landing-page",
96+
"category": "example",
8897
"latestVersion": {
8998
"version": "1.0.0",
9099
"released": "2025-04-24T19:04:23Z",
@@ -99,15 +108,14 @@
99108
"minimumConnectVersion": "2025.04.0"
100109
}
101110
],
102-
"tags": [
103-
"Jump Start"
104-
]
111+
"tags": []
105112
},
106113
{
107114
"name": "plumbertableau-example",
108115
"title": "plumbertableau example",
109116
"description": "plumbertableau is an R package that enables R developers to build Plumber APIs that function as Tableau Analytics Extensions. These extensions can be leveraged from Tableau workbooks to allow real time requests from Tableau to R. This extension builds on top of Tableau's example Superstore dataset.",
110117
"homepage": "https://github.com/posit-dev/connect-extensions/tree/main/extensions/plumbertableau-example",
118+
"category": "example",
111119
"latestVersion": {
112120
"version": "1.0.0",
113121
"released": "2025-04-29T18:05:16Z",
@@ -138,15 +146,14 @@
138146
}
139147
}
140148
],
141-
"tags": [
142-
"Jump Start"
143-
]
149+
"tags": []
144150
},
145151
{
146152
"name": "portfolio-dashboard",
147153
"title": "Portfolio Dashboard",
148154
"description": "A shiny application makes it easy to transform your analysis into an interactive dashboard using R so users can ask and answer questions in real-time, without having to touch any code.",
149155
"homepage": "https://github.com/posit-dev/connect-extensions/tree/main/extensions/portfolio-dashboard",
156+
"category": "example",
150157
"latestVersion": {
151158
"version": "0.0.1",
152159
"released": "2025-04-11T21:32:23Z",
@@ -171,15 +178,14 @@
171178
}
172179
}
173180
],
174-
"tags": [
175-
"Jump Start"
176-
]
181+
"tags": []
177182
},
178183
{
179184
"name": "portfolio-report",
180185
"title": "Portfolio Report",
181186
"description": "This R Markdown document includes parameters, making it easier for stakeholders to customize the report's assumptions and create their own version. The main document serves as a standard base template, containing your core code and analysis, so you don't have to copy, paste, and republish.",
182187
"homepage": "https://github.com/posit-dev/connect-extensions/tree/main/extensions/portfolio-report",
188+
"category": "example",
183189
"latestVersion": {
184190
"version": "0.0.1",
185191
"released": "2025-05-01T18:23:36Z",
@@ -204,15 +210,14 @@
204210
}
205211
}
206212
],
207-
"tags": [
208-
"Jump Start"
209-
]
213+
"tags": []
210214
},
211215
{
212216
"name": "publisher-command-center",
213217
"title": "Publisher Command Center",
214218
"description": "An app that helps publishers view and manage details about apps and dashboards deployed to Connect: View app metadata and history for all of the apps you are collaborating on as well as see and managing running process for individual apps.",
215219
"homepage": "https://github.com/posit-dev/connect-extensions/tree/main/extensions/publisher-command-center",
220+
"category": "extension",
216221
"latestVersion": {
217222
"version": "0.0.4",
218223
"released": "2025-05-20T20:31:50Z",
@@ -297,6 +302,7 @@
297302
"title": "Quarto Document",
298303
"description": "This Quarto example shows how a basic document can present diagrams and interactivity.",
299304
"homepage": "https://github.com/posit-dev/connect-extensions/tree/main/extensions/quarto-document",
305+
"category": "example",
300306
"latestVersion": {
301307
"version": "1.0.1",
302308
"released": "2025-05-08T19:48:06Z",
@@ -332,15 +338,14 @@
332338
}
333339
}
334340
],
335-
"tags": [
336-
"Jump Start"
337-
]
341+
"tags": []
338342
},
339343
{
340344
"name": "quarto-script-r",
341345
"title": "Run an R Script using Quarto",
342346
"description": "This example demonstrates running a simple R script on Connect as a Quarto project. It is an example of how you might automate regular imports and transformations from a data source. JSON and CSV files are exported and made available for download. The script also generates a custom email, with the generated CSV files as attachments.",
343347
"homepage": "https://github.com/posit-dev/connect-extensions/tree/main/extensions/quarto-script-r",
348+
"category": "example",
344349
"latestVersion": {
345350
"version": "1.0.0",
346351
"released": "2025-05-14T13:17:52Z",
@@ -371,15 +376,14 @@
371376
}
372377
}
373378
],
374-
"tags": [
375-
"Jump Start"
376-
]
379+
"tags": []
377380
},
378381
{
379382
"name": "quarto-stock-report-python",
380383
"title": "Quarto Stock Report using Python",
381384
"description": "An example of how you might automate regular updates using a data source",
382385
"homepage": "https://github.com/posit-dev/connect-extensions/tree/main/extensions/quarto-stock-report-python",
386+
"category": "example",
383387
"latestVersion": {
384388
"version": "1.0.1",
385389
"released": "2025-05-08T19:48:11Z",
@@ -424,15 +428,14 @@
424428
}
425429
}
426430
],
427-
"tags": [
428-
"Jump Start"
429-
]
431+
"tags": []
430432
},
431433
{
432434
"name": "quarto-website",
433435
"title": "Quarto Website",
434436
"description": "This Quarto website uses the Posit Connect Server API together with Python to construct a dashboard that presents published content. Views showing featured and all content are included. Set the `FEATURED_TAGS` environment variable and feature content having a particular tag name.",
435437
"homepage": "https://github.com/posit-dev/connect-extensions/tree/main/extensions/quarto-website",
438+
"category": "example",
436439
"latestVersion": {
437440
"version": "1.0.0",
438441
"released": "2025-05-14T12:56:14Z",
@@ -463,15 +466,14 @@
463466
}
464467
}
465468
],
466-
"tags": [
467-
"Jump Start"
468-
]
469+
"tags": []
469470
},
470471
{
471472
"name": "stock-api-fastapi",
472473
"title": "FastAPI Stock Pricing Service",
473474
"description": "APIs are a great way for software engineering teams to use your models without translating them into different languages",
474475
"homepage": "https://github.com/posit-dev/connect-extensions/tree/main/extensions/stock-api-fastapi",
476+
"category": "example",
475477
"latestVersion": {
476478
"version": "1.0.0",
477479
"released": "2025-04-24T18:56:34Z",
@@ -502,15 +504,14 @@
502504
}
503505
}
504506
],
505-
"tags": [
506-
"Jump Start"
507-
]
507+
"tags": []
508508
},
509509
{
510510
"name": "stock-api-flask",
511511
"title": "Flask Stock Pricing Service",
512512
"description": "APIs are a great way for software engineering teams to use your models without translating them into different languages",
513513
"homepage": "https://github.com/posit-dev/connect-extensions/tree/main/extensions/stock-api-flask",
514+
"category": "example",
514515
"latestVersion": {
515516
"version": "1.0.0",
516517
"released": "2025-04-24T19:12:11Z",
@@ -541,15 +542,14 @@
541542
}
542543
}
543544
],
544-
"tags": [
545-
"Jump Start"
546-
]
545+
"tags": []
547546
},
548547
{
549548
"name": "stock-api-plumber",
550549
"title": "Stock Pricing Service with Plumber API",
551550
"description": "An API allows you to turn your models into production services that other tools and teams can use. APIs are a great way for software engineering teams to use your models without translating them into different languages.",
552551
"homepage": "https://github.com/posit-dev/connect-extensions/tree/main/extensions/stock-api-plumber",
552+
"category": "example",
553553
"latestVersion": {
554554
"version": "1.0.0",
555555
"released": "2025-04-25T18:11:56Z",
@@ -580,15 +580,14 @@
580580
}
581581
}
582582
],
583-
"tags": [
584-
"Jump Start"
585-
]
583+
"tags": []
586584
},
587585
{
588586
"name": "stock-dashboard-python",
589587
"title": "Stock Pricing Dashboard using Python Dash",
590588
"description": "A Dash application makes it easy to transform your analysis into an interactive dashboard using Python so users can ask and answer questions in real-time, without having to touch any code.",
591589
"homepage": "https://github.com/posit-dev/connect-extensions/tree/main/extensions/stock-dashboard-python",
590+
"category": "example",
592591
"latestVersion": {
593592
"version": "1.0.0",
594593
"released": "2025-05-14T12:53:16Z",
@@ -613,15 +612,14 @@
613612
}
614613
}
615614
],
616-
"tags": [
617-
"Jump Start"
618-
]
615+
"tags": []
619616
},
620617
{
621618
"name": "usage-metrics-dashboard",
622619
"title": "Usage Metrics Dashboard",
623620
"description": "Understand usage patterns across your work on Connect. Browse an overview of usage across everything you've published, and dive into detailed breakdowns of data for an individual deployment, down to the level of individual visits.",
624621
"homepage": "https://github.com/posit-dev/connect-extensions/tree/main/extensions/usage-metrics-dashboard",
622+
"category": "extension",
625623
"latestVersion": {
626624
"version": "1.0.0",
627625
"released": "2025-05-07T20:38:49Z",
@@ -655,4 +653,4 @@
655653
"tags": []
656654
}
657655
]
658-
}
656+
}

extensions/connectwidgets-example/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"homepage": "https://github.com/posit-dev/connect-extensions/tree/main/extensions/connectwidgets-example",
1717
"version": "0.0.1",
1818
"minimumConnectVersion": "2025.04.0",
19-
"tags": ["Jump Start"]
19+
"category": "example"
2020
},
2121
"environment": {
2222
"r": {

extensions/fastapitableau-example/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"API Publishing"
1616
],
1717
"version": "1.0.0",
18-
"tags": ["Jump Start"]
18+
"category": "example"
1919
},
2020
"environment": {
2121
"python": {

extensions/landing-page/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"title": "Static HTML landing page",
1515
"description": "A simple static HTML web page that can be served from Connect",
1616
"homepage": "https://github.com/posit-dev/connect-extensions/tree/main/extensions/landing-page",
17-
"tags": ["Jump Start"],
17+
"category": "example",
1818
"minimumConnectVersion": "2025.04.0",
1919
"version": "1.0.0"
2020
},

0 commit comments

Comments
 (0)