Skip to content

Commit 8d01d00

Browse files
Merge pull request #1889 from redis/DOC-5503-enable-tce-overrides
DOC-5503 enable TCE overrides
2 parents c66c989 + 71a7752 commit 8d01d00

File tree

5 files changed

+225
-37
lines changed

5 files changed

+225
-37
lines changed

build/local_examples.py

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Local Examples Processor
4+
5+
This script processes local examples from the local_examples/ directory
6+
and integrates them into the existing examples system.
7+
8+
Works like remote examples - each file contains an EXAMPLE: header
9+
and can be any supported language.
10+
"""
11+
12+
import os
13+
import glob
14+
import shutil
15+
import logging
16+
from typing import Dict, Any
17+
18+
from components.example import Example
19+
from components.util import mkdir_p
20+
from components.structured_data import load_dict, dump_dict
21+
22+
23+
# File extension to language mapping
24+
EXTENSION_TO_LANGUAGE = {
25+
'.py': 'python',
26+
'.js': 'node.js',
27+
'.go': 'go',
28+
'.cs': 'c#',
29+
'.java': 'java',
30+
'.php': 'php'
31+
}
32+
33+
# Language to client name mapping (from config.toml clientsExamples)
34+
LANGUAGE_TO_CLIENT = {
35+
'python': 'Python',
36+
'node.js': 'Node.js',
37+
'go': 'Go',
38+
'c#': 'C#',
39+
'java': 'Java-Sync', # Default to sync, could be overridden
40+
'php': 'PHP',
41+
'redisvl': 'RedisVL'
42+
}
43+
44+
45+
def get_language_from_extension(filename: str) -> str:
46+
"""Get language from file extension."""
47+
_, ext = os.path.splitext(filename)
48+
return EXTENSION_TO_LANGUAGE.get(ext.lower())
49+
50+
51+
def get_client_name_from_language(language: str) -> str:
52+
"""Get client name from language."""
53+
return LANGUAGE_TO_CLIENT.get(language, language.title())
54+
55+
56+
def get_example_id_from_file(path: str) -> str:
57+
"""Extract example ID from the first line of a file."""
58+
try:
59+
with open(path, 'r') as f:
60+
first_line = f.readline().strip()
61+
if 'EXAMPLE:' in first_line:
62+
return first_line.split(':')[1].strip()
63+
except Exception as e:
64+
logging.error(f"Error reading example ID from {path}: {e}")
65+
return None
66+
67+
68+
def process_local_examples(local_examples_dir: str = 'local_examples',
69+
examples_dir: str = 'examples',
70+
examples_json: str = 'data/examples.json') -> None:
71+
"""
72+
Process local examples and integrate them into the examples system.
73+
74+
Works like remote examples - each file contains an EXAMPLE: header
75+
and can be any supported language.
76+
77+
Args:
78+
local_examples_dir: Directory containing local example source files
79+
examples_dir: Target directory for processed examples
80+
examples_json: Path to examples.json file
81+
"""
82+
83+
if not os.path.exists(local_examples_dir):
84+
logging.info(f"Local examples directory {local_examples_dir} not found, skipping")
85+
return
86+
87+
# Load existing examples data
88+
examples_data = {}
89+
if os.path.exists(examples_json):
90+
examples_data = load_dict(examples_json)
91+
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}")
147+
148+
# Save updated examples data
149+
dump_dict(examples_json, examples_data)
150+
logging.info(f"Updated examples data saved to {examples_json}")
151+
152+
153+
if __name__ == '__main__':
154+
logging.basicConfig(level=logging.INFO,
155+
format='%(levelname)s: %(message)s')
156+
157+
process_local_examples()
158+
print("Local examples processing complete")

build/make.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import argparse
22
from datetime import datetime
33
import logging
4+
import sys
45
import tempfile
56

67
from components.component import All
78
from components.util import mkdir_p
9+
from local_examples import process_local_examples
810

911

1012
def parse_args() -> argparse.Namespace:
@@ -30,20 +32,19 @@ def parse_args() -> argparse.Namespace:
3032
ARGS = parse_args()
3133
mkdir_p(ARGS.tempdir)
3234

33-
# Configure logging BEFORE creating objects
34-
log_level = getattr(logging, ARGS.loglevel.upper())
35-
logging.basicConfig(
36-
level=log_level,
37-
format='%(message)s %(filename)s:%(lineno)d - %(funcName)s',
38-
force=True # Force reconfiguration in case logging was already configured
39-
)
40-
4135
# Load settings
4236
ALL = All(ARGS.stack, None, ARGS.__dict__)
4337

4438
# Make the stack
39+
logging.basicConfig(
40+
level=ARGS.loglevel, format=f'{sys.argv[0]}: %(levelname)s %(asctime)s %(message)s')
4541
print(f'Applying all configured components"{ALL._name}"')
4642
start = datetime.now()
4743
ALL.apply()
44+
45+
# Process local examples
46+
print('Processing local examples')
47+
process_local_examples()
48+
4849
total = datetime.now() - start
4950
print(f'+OK ({total.microseconds / 1000} ms)')

layouts/partials/tabbed-clients-example.html

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
{{ $lang := .Scratch.Get "lang" }}
44
{{ $redisCommands := .Scratch.Get "redisCommands" }}
55
{{ $redisCommandsLineLimit := (or (.Scratch.Get "maxLines") 100) }}
6+
{{ $cliTabName := (or (.Scratch.Get "cli_tab_name") ">_ Redis CLI") }}
7+
{{ $cliFooterLinkText := .Scratch.Get "cli_footer_link_text" }}
8+
{{ $cliFooterLinkUrl := .Scratch.Get "cli_footer_link_url" }}
69

710
{{ if not (isset $.Site.Data.examples $id) }}
811
{{ warnf "[tabbed-clients-example] Example not found %q for %q" $id $.Page }}
@@ -12,7 +15,7 @@
1215
{{/* Render redis-cli example from inner content if any */}}
1316
{{ if (ne (trim $redisCommands "\n") "") }}
1417
{{ $redisCliContent := highlight (trim $redisCommands "\n") "plaintext" (printf "linenos=false,hl_lines=1-%d" $redisCommandsLineLimit ) }}
15-
{{ $tabs = $tabs | append (dict "title" "redis-cli" "content" $redisCliContent "limit" $redisCommandsLineLimit) }}
18+
{{ $tabs = $tabs | append (dict "title" "redis-cli" "displayName" $cliTabName "content" $redisCliContent "limit" $redisCommandsLineLimit "customFooterLinkText" $cliFooterLinkText "customFooterLinkUrl" $cliFooterLinkUrl) }}
1619
{{ end }}
1720

1821
{{ $clientExamples := index $.Site.Data.examples $id }}
@@ -21,15 +24,15 @@
2124
{{ $clientConfig := index $.Site.Params.clientsconfig $client }}
2225
{{ $language := index $example "language" }}
2326
{{ $quickstartSlug := index $clientConfig "quickstartSlug" }}
24-
27+
2528
{{ if and ($example) (or (eq $lang "") (strings.Contains $lang $client)) }}
2629
{{ $examplePath := index $example "target" }}
2730
{{ $options := printf "linenos=false" }}
28-
31+
2932
{{ if and (ne $step "") (isset $example "named_steps") (isset $example.named_steps $step) }}
3033
{{ $options = printf "%s,hl_lines=%s" $options (index $example.named_steps $step) }}
3134
{{ else }}
32-
{{ if isset $example "highlight" }}
35+
{{ if and (isset $example "highlight") (index $example "highlight") }}
3336
{{ $options = printf "%s,hl_lines=%s" $options (delimit (index $example "highlight") " ") }}
3437
{{ end }}
3538
{{ end }}
@@ -40,5 +43,5 @@
4043
{{ end }}
4144
{{ end }}
4245

43-
{{ $params := dict "id" (printf "%s-step%s" $id $step) "tabs" $tabs "showFooter" (eq $lang "") }}
46+
{{ $params := dict "id" (printf "%s-step%s" $id $step) "tabs" $tabs "showFooter" true }}
4447
{{ partial "tabs/wrapper.html" $params }}

layouts/partials/tabs/wrapper.html

Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
hover:text-redis-red-600 rounded rounded-mx transition duration-150 ease-in-out"
2222
title="Open example" for="{{ $tid }}">
2323
{{ if eq (index $tab "title") "redis-cli" }}
24-
{{ $cliName }}
24+
{{ or (index $tab "displayName") $cliName }}
2525
{{ else }}
2626
{{ index $tab "title" }}
2727
{{ end }}
@@ -54,24 +54,44 @@
5454
<div class="cli-footer flex items-center justify-between rounded-b-md bg-slate-900 mt-0 px-4 pt-0 mb-0 transition-opacity ease-in-out duration-300 opacity-0 invisible
5555
group-hover:opacity-100 group-hover:visible">
5656
{{ if eq (index $tab "title") "redis-cli" }}
57-
<div class="flex-1 text-xs text-white overflow-ellipsis">{{ $footerText }}</div>
58-
<div class="text-right">
59-
<a href="{{ $btnRIUrl }}" tabindex="1" class="rounded rounded-mx px-2 py-1 flex items-center text-white text-xs
60-
hover:text-white hover:bg-slate-600 hover:border-transparent focus:outline-none
61-
focus:ring-2 focus:white focus:border-slate-500" title="{{$btnRIText}}">
62-
<svg class="w-4 h-4 mr-1" width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
63-
<path d="M2.26236 5.66895L1.21732 6.07172L7.00018 8.65693V7.79842L2.26236 5.66895Z" fill="#fca5a5"/>
64-
<path d="M2.26236 8.02271L1.21732 8.42548L7.00018 11.0119V10.1516L2.26236 8.02271Z" fill="#fca5a5"/>
65-
<path d="M1.21732 3.7175L7.00018 6.30392V2.87805L8.66273 2.13423L7.00018 1.49512L1.21732 3.7175Z" fill="#fca5a5"/>
66-
<path d="M7.00018 2.8781V6.30366L1.21732 3.71724V5.20004L7.00018 7.79705V8.65526L1.21732 6.07217V7.55496L7.00018 10.1553V11.0135L1.21732 8.42376V9.90656H1.18878L7.00018 12.5051L8.66273 11.7613V2.13428L7.00018 2.8781Z" fill="#f87171"/>
67-
<path d="M9.07336 11.5777L10.7359 10.8338V4.01538L9.07336 4.7592V11.5777Z" fill="#f87171"/>
68-
<path d="M9.07336 4.75867L10.7359 4.01485L9.07336 3.37573V4.75867Z" fill="#fca5a5"/>
69-
<path d="M11.1481 10.6497L12.8112 9.90591V5.896L11.1487 6.63982L11.1481 10.6497Z" fill="#f87171"/>
70-
<path d="M11.1481 6.63954L12.8112 5.89572L11.1481 5.25781V6.63954Z" fill="#fca5a5"/>
71-
</svg>
72-
<span>{{$btnRIText}}</span>
73-
</a>
74-
</div>
57+
{{ $displayName := index $tab "displayName" }}
58+
{{ $hasCustomTabName := and $displayName (ne $displayName $cliName) }}
59+
{{ $customLinkText := index $tab "customFooterLinkText" }}
60+
{{ $customLinkUrl := index $tab "customFooterLinkUrl" }}
61+
62+
{{ if and $customLinkText $customLinkUrl }}
63+
<div class="text-left">
64+
<a href="{{ $customLinkUrl }}" tabindex="1" class="rounded rounded-mx px-2 py-1 flex items-center text-white text-xs
65+
hover:text-white hover:bg-slate-600 hover:border-transparent focus:outline-none
66+
focus:ring-2 focus:white focus:border-slate-500" title="{{ $customLinkText }}">
67+
<span>{{ $customLinkText }}</span>
68+
</a>
69+
</div>
70+
<div class="flex-1"></div>
71+
{{ else }}
72+
{{ if $hasCustomTabName }}
73+
<div class="flex-1"></div>
74+
{{ else }}
75+
<div class="flex-1 text-xs text-white overflow-ellipsis">{{ $footerText }}</div>
76+
{{ end }}
77+
<div class="text-right">
78+
<a href="{{ $btnRIUrl }}" tabindex="1" class="rounded rounded-mx px-2 py-1 flex items-center text-white text-xs
79+
hover:text-white hover:bg-slate-600 hover:border-transparent focus:outline-none
80+
focus:ring-2 focus:white focus:border-slate-500" title="{{$btnRIText}}">
81+
<svg class="w-4 h-4 mr-1" width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
82+
<path d="M2.26236 5.66895L1.21732 6.07172L7.00018 8.65693V7.79842L2.26236 5.66895Z" fill="#fca5a5"/>
83+
<path d="M2.26236 8.02271L1.21732 8.42548L7.00018 11.0119V10.1516L2.26236 8.02271Z" fill="#fca5a5"/>
84+
<path d="M1.21732 3.7175L7.00018 6.30392V2.87805L8.66273 2.13423L7.00018 1.49512L1.21732 3.7175Z" fill="#fca5a5"/>
85+
<path d="M7.00018 2.8781V6.30366L1.21732 3.71724V5.20004L7.00018 7.79705V8.65526L1.21732 6.07217V7.55496L7.00018 10.1553V11.0135L1.21732 8.42376V9.90656H1.18878L7.00018 12.5051L8.66273 11.7613V2.13428L7.00018 2.8781Z" fill="#f87171"/>
86+
<path d="M9.07336 11.5777L10.7359 10.8338V4.01538L9.07336 4.7592V11.5777Z" fill="#f87171"/>
87+
<path d="M9.07336 4.75867L10.7359 4.01485L9.07336 3.37573V4.75867Z" fill="#fca5a5"/>
88+
<path d="M11.1481 10.6497L12.8112 9.90591V5.896L11.1487 6.63982L11.1481 10.6497Z" fill="#f87171"/>
89+
<path d="M11.1481 6.63954L12.8112 5.89572L11.1481 5.25781V6.63954Z" fill="#fca5a5"/>
90+
</svg>
91+
<span>{{$btnRIText}}</span>
92+
</a>
93+
</div>
94+
{{ end }}
7595
{{ else }}
7696
<!--<a href='/docs/latest/develop/clients/{{ index $tab "quickstartSlug" }}/' tabindex="1" class="rounded rounded-mx px-3 py-1 text-white text-xs-->
7797
<a href='{{ absURL (print "develop/clients/" (index $tab "quickstartSlug")) }}/' tabindex="1" class="rounded rounded-mx px-3 py-1 text-white text-xs
@@ -81,11 +101,14 @@
81101
</a>
82102
<div class="w-1/2"></div>
83103
<div class="flex-1 text-right">
84-
<a href='{{ index $tab "sourceUrl" }}' tabindex="1" class="button text-neutral-400 hover:text-slate-100 h-6 w-6 p-1" title="Improve this code example">
85-
<svg width="18" height="16" viewBox="0 0 18 16" fill="github" xmlns="http://www.w3.org/2000/svg">
86-
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.99953 1.43397e-06C7.09918 -0.000897921 5.26058 0.674713 3.81295 1.90585C2.36533 3.13699 1.40324 4.84324 1.09896 6.71907C0.794684 8.5949 1.1681 10.5178 2.15233 12.1434C3.13657 13.769 4.66734 14.9912 6.47053 15.591C6.87053 15.664 7.01653 15.417 7.01653 15.205C7.01653 15.015 7.00953 14.512 7.00553 13.845C4.78053 14.328 4.31053 12.772 4.31053 12.772C4.16325 12.2887 3.84837 11.8739 3.42253 11.602C2.69653 11.102 3.47753 11.116 3.47753 11.116C3.73043 11.1515 3.97191 11.2442 4.18365 11.3869C4.39539 11.5297 4.57182 11.7189 4.69953 11.94C4.80755 12.1377 4.95378 12.3119 5.12972 12.4526C5.30567 12.5933 5.50782 12.6976 5.72442 12.7595C5.94103 12.8214 6.16778 12.8396 6.39148 12.813C6.61519 12.7865 6.83139 12.7158 7.02753 12.605C7.06381 12.1992 7.24399 11.8197 7.53553 11.535C5.75953 11.335 3.89153 10.647 3.89153 7.581C3.88005 6.78603 4.17513 6.01716 4.71553 5.434C4.47318 4.74369 4.50322 3.98693 4.79953 3.318C4.79953 3.318 5.47053 3.103 6.99953 4.138C8.31074 3.77905 9.69432 3.77905 11.0055 4.138C12.5325 3.103 13.2055 3.318 13.2055 3.318C13.5012 3.9877 13.5294 4.74513 13.2845 5.435C13.8221 6.01928 14.114 6.78817 14.0995 7.582C14.0995 10.655 12.2285 11.332 10.4465 11.53C10.6375 11.724 10.7847 11.9566 10.8784 12.2123C10.972 12.4679 11.0099 12.7405 10.9895 13.012C10.9895 14.081 10.9795 14.944 10.9795 15.206C10.9795 15.42 11.1235 15.669 11.5295 15.591C13.3328 14.9911 14.8636 13.7689 15.8479 12.1432C16.8321 10.5175 17.2054 8.59447 16.901 6.71858C16.5966 4.84268 15.6343 3.13642 14.1865 1.90536C12.7387 0.674306 10.9 -0.0011359 8.99953 1.43397e-06Z" fill="white"/>
87-
</svg>
88-
</a>
104+
{{ $sourceUrl := index $tab "sourceUrl" }}
105+
{{ if $sourceUrl }}
106+
<a href='{{ $sourceUrl }}' tabindex="1" class="button text-neutral-400 hover:text-slate-100 h-6 w-6 p-1" title="Improve this code example">
107+
<svg width="18" height="16" viewBox="0 0 18 16" fill="github" xmlns="http://www.w3.org/2000/svg">
108+
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.99953 1.43397e-06C7.09918 -0.000897921 5.26058 0.674713 3.81295 1.90585C2.36533 3.13699 1.40324 4.84324 1.09896 6.71907C0.794684 8.5949 1.1681 10.5178 2.15233 12.1434C3.13657 13.769 4.66734 14.9912 6.47053 15.591C6.87053 15.664 7.01653 15.417 7.01653 15.205C7.01653 15.015 7.00953 14.512 7.00553 13.845C4.78053 14.328 4.31053 12.772 4.31053 12.772C4.16325 12.2887 3.84837 11.8739 3.42253 11.602C2.69653 11.102 3.47753 11.116 3.47753 11.116C3.73043 11.1515 3.97191 11.2442 4.18365 11.3869C4.39539 11.5297 4.57182 11.7189 4.69953 11.94C4.80755 12.1377 4.95378 12.3119 5.12972 12.4526C5.30567 12.5933 5.50782 12.6976 5.72442 12.7595C5.94103 12.8214 6.16778 12.8396 6.39148 12.813C6.61519 12.7865 6.83139 12.7158 7.02753 12.605C7.06381 12.1992 7.24399 11.8197 7.53553 11.535C5.75953 11.335 3.89153 10.647 3.89153 7.581C3.88005 6.78603 4.17513 6.01716 4.71553 5.434C4.47318 4.74369 4.50322 3.98693 4.79953 3.318C4.79953 3.318 5.47053 3.103 6.99953 4.138C8.31074 3.77905 9.69432 3.77905 11.0055 4.138C12.5325 3.103 13.2055 3.318 13.2055 3.318C13.5012 3.9877 13.5294 4.74513 13.2845 5.435C13.8221 6.01928 14.114 6.78817 14.0995 7.582C14.0995 10.655 12.2285 11.332 10.4465 11.53C10.6375 11.724 10.7847 11.9566 10.8784 12.2123C10.972 12.4679 11.0099 12.7405 10.9895 13.012C10.9895 14.081 10.9795 14.944 10.9795 15.206C10.9795 15.42 11.1235 15.669 11.5295 15.591C13.3328 14.9911 14.8636 13.7689 15.8479 12.1432C16.8321 10.5175 17.2054 8.59447 16.901 6.71858C16.5966 4.84268 15.6343 3.13642 14.1865 1.90536C12.7387 0.674306 10.9 -0.0011359 8.99953 1.43397e-06Z" fill="white"/>
109+
</svg>
110+
</a>
111+
{{ end }}
89112
</div>
90113
{{ end }}
91114
</div>

layouts/shortcodes/clients-example.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,8 @@
22
{{ .Scratch.Set "step" (.Get 1) }}
33
{{ .Scratch.Set "lang" (.Get 2) }}
44
{{ .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) }}
58
{{ .Scratch.Set "redisCommands" .Inner }}
69
{{ partial "tabbed-clients-example.html" . }}

0 commit comments

Comments
 (0)