Skip to content

Commit 9dcbd4d

Browse files
Merge pull request #1898 from redis/DOC-5517-more-tce-stuff
DOC-5517 TCE `local_examples` subfolders and named params for `clients-examples`
2 parents 445c679 + 7fb6d15 commit 9dcbd4d

13 files changed

+253
-68
lines changed

build/local_examples.py

Lines changed: 68 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,8 @@
1010
"""
1111

1212
import os
13-
import glob
1413
import shutil
1514
import logging
16-
from typing import Dict, Any
1715

1816
from components.example import Example
1917
from components.util import mkdir_p
@@ -89,70 +87,80 @@ def process_local_examples(local_examples_dir: str = 'local_examples',
8987
if os.path.exists(examples_json):
9088
examples_data = load_dict(examples_json)
9189

92-
# Process each file in local_examples directory
93-
for filename in os.listdir(local_examples_dir):
94-
source_file = os.path.join(local_examples_dir, filename)
95-
96-
if not os.path.isfile(source_file):
97-
continue
98-
99-
# Get language from file extension
100-
language = get_language_from_extension(filename)
101-
if not language:
102-
logging.warning(f"Unknown file extension for: {filename}")
103-
continue
104-
105-
# Get example ID from file content
106-
example_id = get_example_id_from_file(source_file)
107-
if not example_id:
108-
logging.warning(f"No EXAMPLE: header found in {filename}")
109-
continue
110-
111-
logging.info(f"Processing local example: {example_id} ({language})")
112-
113-
# Create target directory
114-
target_dir = os.path.join(examples_dir, example_id)
115-
mkdir_p(target_dir)
116-
117-
# Initialize example data
118-
if example_id not in examples_data:
119-
examples_data[example_id] = {}
120-
121-
# Copy file to target directory with local_ prefix
122-
base_name = os.path.splitext(filename)[0]
123-
ext = os.path.splitext(filename)[1]
124-
target_filename = f"local_{base_name}{ext}"
125-
target_file = os.path.join(target_dir, target_filename)
126-
shutil.copy2(source_file, target_file)
127-
128-
# Process with Example class
129-
example = Example(language, target_file)
130-
131-
# Get client name
132-
client_name = get_client_name_from_language(language)
133-
134-
# Create metadata
135-
example_metadata = {
136-
'source': source_file,
137-
'language': language,
138-
'target': target_file,
139-
'highlight': example.highlight,
140-
'hidden': example.hidden,
141-
'named_steps': example.named_steps,
142-
'sourceUrl': None # Local examples don't have source URLs
143-
}
144-
145-
examples_data[example_id][client_name] = example_metadata
146-
logging.info(f"Processed {client_name} example for {example_id}")
90+
# Process each file in local_examples directory and subdirectories
91+
for root, _, files in os.walk(local_examples_dir):
92+
for filename in files:
93+
source_file = os.path.join(root, filename)
94+
95+
# Get language from file extension
96+
language = get_language_from_extension(filename)
97+
if not language:
98+
logging.warning(f"Unknown file extension for: {filename}")
99+
continue
100+
101+
# Get example ID from file content
102+
example_id = get_example_id_from_file(source_file)
103+
if not example_id:
104+
logging.warning(f"No EXAMPLE: header found in {filename}")
105+
continue
106+
107+
logging.info(f"Processing local example: {example_id} ({language}) "
108+
f"from {source_file}")
109+
110+
# Create target directory
111+
target_dir = os.path.join(examples_dir, example_id)
112+
mkdir_p(target_dir)
113+
114+
# Initialize example data
115+
if example_id not in examples_data:
116+
examples_data[example_id] = {}
117+
118+
# Copy file to target directory with local_ prefix
119+
# Include subdirectory structure in the filename to avoid conflicts
120+
relative_path = os.path.relpath(source_file, local_examples_dir)
121+
relative_dir = os.path.dirname(relative_path)
122+
base_name = os.path.splitext(filename)[0]
123+
ext = os.path.splitext(filename)[1]
124+
125+
# Create a unique filename that includes subdirectory info
126+
if relative_dir and relative_dir != '.':
127+
# Replace path separators with underscores for flat filename
128+
subdir_prefix = relative_dir.replace(os.sep, '_')
129+
target_filename = f"local_{subdir_prefix}_{base_name}{ext}"
130+
else:
131+
target_filename = f"local_{base_name}{ext}"
132+
133+
target_file = os.path.join(target_dir, target_filename)
134+
shutil.copy2(source_file, target_file)
135+
136+
# Process with Example class
137+
example = Example(language, target_file)
138+
139+
# Get client name
140+
client_name = get_client_name_from_language(language)
141+
142+
# Create metadata
143+
example_metadata = {
144+
'source': source_file,
145+
'language': language,
146+
'target': target_file,
147+
'highlight': example.highlight,
148+
'hidden': example.hidden,
149+
'named_steps': example.named_steps,
150+
'sourceUrl': None # Local examples don't have source URLs
151+
}
152+
153+
examples_data[example_id][client_name] = example_metadata
154+
logging.info(f"Processed {client_name} example for {example_id}")
147155

148156
# Save updated examples data
149157
dump_dict(examples_json, examples_data)
150158
logging.info(f"Updated examples data saved to {examples_json}")
151159

152160

153161
if __name__ == '__main__':
154-
logging.basicConfig(level=logging.INFO,
155-
format='%(levelname)s: %(message)s')
156-
162+
logging.basicConfig(level=logging.INFO,
163+
format='%(levelname)s: %(message)s')
164+
157165
process_local_examples()
158166
print("Local examples processing complete")
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
---
2+
Title: TCE test
3+
alwaysopen: false
4+
categories:
5+
- docs
6+
- operate
7+
- rs
8+
description: Test for tabbed-clients-example.html
9+
weight: 1
10+
linkTitle: TCE test
11+
---
12+
13+
This page demonstrates the new named parameter syntax for the `clients-example` shortcode while maintaining backward compatibility with positional parameters.
14+
15+
## Basic Usage with Named Parameters
16+
17+
### Example 1: Basic named parameters
18+
Using the new named parameter syntax with just the required parameters:
19+
20+
{{< clients-example set="stream_tutorial" step="xadd" >}}
21+
> XADD race:france * rider Castilla speed 30.2 position 1 location_id 1
22+
"1692632086370-0"
23+
{{< /clients-example >}}
24+
25+
### Example 2: Named parameters with language filter
26+
Filtering to show only specific client languages:
27+
28+
{{< clients-example set="py_home_json" step="query1" lang_filter="Python" >}}
29+
{{< /clients-example >}}
30+
31+
### Example 3: Named parameters with custom max lines
32+
Limiting the number of lines displayed in the Redis CLI tab:
33+
34+
{{< clients-example set="hash_tutorial" step="set_get_all" max_lines="2" >}}
35+
> JSON.SET "bicycle:0" "." "{\"brand\": \"Velorim\", \"model\": \"Jigger\", \"price\": 270}"
36+
OK
37+
> JSON.SET "bicycle:1" "." "{\"brand\": \"Bicyk\", \"model\": \"Hillcraft\", \"price\": 1200}"
38+
OK
39+
{{< /clients-example >}}
40+
41+
### Example 4: Named parameters with custom tab name
42+
Using a custom name for the Redis CLI tab:
43+
44+
{{< clients-example set="cmds_list" step="llen" dft_tab_name="🔧 Redis Commands" >}}
45+
redis> LPUSH mylist "World"
46+
(integer) 1
47+
redis> LPUSH mylist "Hello"
48+
(integer) 2
49+
redis> LLEN mylist
50+
(integer) 2
51+
{{< /clients-example >}}
52+
53+
### Example 5: Named parameters with custom footer links
54+
Adding custom footer links to the Redis CLI tab:
55+
56+
{{< clients-example set="cmds_hash" step="hvals" dft_tab_name="Redis CLI Example" dft_tab_link_title="Learn More" dft_tab_url="https://redis.io/commands/hvals" >}}
57+
redis> HSET myhash field1 "Hello"
58+
(integer) 1
59+
redis> HSET myhash field2 "World"
60+
(integer) 1
61+
redis> HVALS myhash
62+
1) "Hello"
63+
2) "World"
64+
{{< /clients-example >}}
65+
66+
## Backward Compatibility Tests
67+
68+
### Example 6: Original positional parameters (2 params)
69+
This should work exactly as before:
70+
71+
{{< clients-example stream_tutorial xrange >}}
72+
> XRANGE race:france 1692632086370-0 + COUNT 2
73+
{{< /clients-example >}}
74+
75+
### Example 7: Original positional parameters (4 params)
76+
Testing with language filter and max lines:
77+
78+
{{< clients-example search_quickstart add_documents "" 3 >}}
79+
> JSON.SET "bicycle:0" "." "{\"brand\": \"Velorim\", \"model\": \"Jigger\", \"price\": 270}"
80+
OK
81+
> JSON.SET "bicycle:1" "." "{\"brand\": \"Bicyk\", \"model\": \"Hillcraft\", \"price\": 1200}"
82+
OK
83+
{{< /clients-example >}}
84+
85+
## Parameter Reference
86+
87+
### Named Parameters
88+
89+
| Parameter | Type | Description | Default |
90+
|-----------|------|-------------|---------|
91+
| `set` | string | Name of the example set (required) | - |
92+
| `step` | string | Example step name (required) | - |
93+
| `lang_filter` or `language` | string | Language filter to show only specific clients | `""` (all languages) |
94+
| `max_lines` | integer | Maximum number of lines shown in Redis CLI tab | `100` |
95+
| `dft_tab_name` | string | Custom name for the Redis CLI tab | `">_ Redis CLI"` |
96+
| `dft_tab_link_title` | string | Custom footer link title for Redis CLI tab | - |
97+
| `dft_tab_url` | string | Custom footer link URL for Redis CLI tab | - |
98+
99+
### Positional Parameters (Backward Compatibility)
100+
101+
| Position | Type | Description | Default |
102+
|----------|------|-------------|---------|
103+
| 0 | string | Name of the example set (required) | - |
104+
| 1 | string | Example step name (required) | - |
105+
| 2 | string | Language filter | `""` |
106+
| 3 | integer | Maximum number of lines | `100` |
107+
| 4 | string | Custom first tab name | `">_ Redis CLI"` |
108+
| 5 | string | Custom first tab footer link title | - |
109+
| 6 | string | Custom first tab footer link URL | - |
110+
111+
## Migration Guide
112+
113+
### Before (Positional Parameters)
114+
```hugo
115+
{{</* clients-example stream_tutorial xadd */>}}
116+
{{</* clients-example search_quickstart add_documents "" 2 */>}}
117+
{{</* clients-example cmds_list llen "" "" "Custom CLI" */>}}
118+
```
119+
120+
### After (Named Parameters)
121+
```hugo
122+
{{</* clients-example set="stream_tutorial" step="xadd" */>}}
123+
{{</* clients-example set="search_quickstart" step="add_documents" max_lines="2" */>}}
124+
{{</* clients-example set="cmds_list" step="llen" dft_tab_name="Custom CLI" */>}}
125+
```
126+
127+
The named parameter syntax is more readable and self-documenting, making it easier to understand what each parameter does without referring to documentation.

layouts/partials/tabbed-clients-example.html

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,15 @@
1414
{{ $tabs := slice }}
1515
{{/* Render redis-cli example from inner content if any */}}
1616
{{ if (ne (trim $redisCommands "\n") "") }}
17-
{{ $redisCliContent := highlight (trim $redisCommands "\n") "plaintext" (printf "linenos=false,hl_lines=1-%d" $redisCommandsLineLimit ) }}
17+
{{ $highlightOptions := "linenos=false" }}
18+
{{ $redisCommandsLineLimitInt := 0 }}
19+
{{ if $redisCommandsLineLimit }}
20+
{{ $redisCommandsLineLimitInt = int $redisCommandsLineLimit }}
21+
{{ end }}
22+
{{ if gt $redisCommandsLineLimitInt 0 }}
23+
{{ $highlightOptions = printf "linenos=false,hl_lines=1-%d" $redisCommandsLineLimitInt }}
24+
{{ end }}
25+
{{ $redisCliContent := highlight (trim $redisCommands "\n") "plaintext" $highlightOptions }}
1826
{{ $tabs = $tabs | append (dict "title" "redis-cli" "displayName" $cliTabName "content" $redisCliContent "limit" $redisCommandsLineLimit "customFooterLinkText" $cliFooterLinkText "customFooterLinkUrl" $cliFooterLinkUrl) }}
1927
{{ end }}
2028

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,51 @@
1-
{{ .Scratch.Set "example" (.Get 0) }}
2-
{{ .Scratch.Set "step" (.Get 1) }}
3-
{{ .Scratch.Set "lang" (.Get 2) }}
4-
{{ .Scratch.Set "maxLines" (.Get 3) }}
5-
{{ .Scratch.Set "cli_tab_name" (.Get 4) }}
6-
{{ .Scratch.Set "cli_footer_link_text" (.Get 5) }}
7-
{{ .Scratch.Set "cli_footer_link_url" (.Get 6) }}
1+
{{/*
2+
clients-example shortcode - supports both positional and named parameters
3+
4+
Named parameters:
5+
- set: Name of the example set (required)
6+
- step: Example step name (required)
7+
- lang_filter: Language filter (optional, default: "")
8+
- max_lines: Maximum number of lines shown by default (optional, default: 100)
9+
- dft_tab_name: Custom first tab name (optional, default: ">_ Redis CLI")
10+
- dft_tab_link_title: Custom first tab footer link title (optional)
11+
- dft_tab_url: Custom first tab footer link URL (optional)
12+
13+
Positional parameters (for backward compatibility):
14+
- 0: example set name
15+
- 1: step name
16+
- 2: language filter
17+
- 3: max lines
18+
- 4: custom first tab name
19+
- 5: custom first tab footer link title
20+
- 6: custom first tab footer link URL
21+
*/}}
22+
23+
{{/* Determine if we're using named or positional parameters */}}
24+
{{ $usingNamedParams := false }}
25+
{{ if .Get "set" }}
26+
{{ $usingNamedParams = true }}
27+
{{ end }}
28+
29+
{{/* Set parameters based on whether we're using named or positional */}}
30+
{{ if $usingNamedParams }}
31+
{{/* Named parameters */}}
32+
{{ .Scratch.Set "example" (.Get "set") }}
33+
{{ .Scratch.Set "step" (.Get "step") }}
34+
{{ .Scratch.Set "lang" (or (.Get "lang_filter") (.Get "language") "") }}
35+
{{ .Scratch.Set "maxLines" (.Get "max_lines") }}
36+
{{ .Scratch.Set "cli_tab_name" (.Get "dft_tab_name") }}
37+
{{ .Scratch.Set "cli_footer_link_text" (.Get "dft_tab_link_title") }}
38+
{{ .Scratch.Set "cli_footer_link_url" (.Get "dft_tab_url") }}
39+
{{ else }}
40+
{{/* Positional parameters (backward compatibility) */}}
41+
{{ .Scratch.Set "example" (.Get 0) }}
42+
{{ .Scratch.Set "step" (.Get 1) }}
43+
{{ .Scratch.Set "lang" (.Get 2) }}
44+
{{ .Scratch.Set "maxLines" (.Get 3) }}
45+
{{ .Scratch.Set "cli_tab_name" (.Get 4) }}
46+
{{ .Scratch.Set "cli_footer_link_text" (.Get 5) }}
47+
{{ .Scratch.Set "cli_footer_link_url" (.Get 6) }}
48+
{{ end }}
49+
850
{{ .Scratch.Set "redisCommands" .Inner }}
951
{{ partial "tabbed-clients-example.html" . }}
File renamed without changes.

0 commit comments

Comments
 (0)