Skip to content

Commit 687061f

Browse files
committed
remove requirement for unique name attribute in carousel
see #179 (comment)
1 parent 8417d6d commit 687061f

File tree

5 files changed

+43
-69
lines changed

5 files changed

+43
-69
lines changed

examples/official-site/custom_components.sql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,14 @@ and SQLPage adds a few more:
111111
- `each_row`: iterates over the rows of a query result
112112
- `typeof`: returns the type of a value (`string`, `number`, `boolean`, `object`, `array`, `null`)
113113
114+
### Attributes
115+
116+
In addition to the parameters you pass to your components in your SQL queries,
117+
SQLPage adds the following attributes to the context of your components:
118+
119+
- `@component_index` : the index of the current component in the page. Useful to generate unique ids or classes.
120+
- `@row_index` : the index of the current row in the current component. Useful to implement special behavior on the first row, for instance.
121+
114122
## Overwriting the default components
115123
116124
You can overwrite the default components, including the `shell` component,

examples/official-site/sqlpage/migrations/32_shared_id_class_attributes.sql

Lines changed: 0 additions & 52 deletions
This file was deleted.

examples/official-site/sqlpage/migrations/34_carousel.sql

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,7 @@ INSERT INTO parameter (
1313
top_level,
1414
optional
1515
)
16-
VALUES (
17-
'carousel',
18-
'name',
19-
'An unique string to identify the caroussel component in the HTML page.',
20-
'TEXT',
21-
TRUE,
22-
FALSE
23-
),
16+
VALUES
2417
(
2518
'carousel',
2619
'title',

sqlpage/templates/carousel.handlebars

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
<div class="card my-2 col-md-{{default width 12}}{{#if center}} mx-auto{{/if}}">
1+
<div class="card my-2 col-md-{{default width 12}}{{#if center}} mx-auto{{/if}} {{class}}" {{#if id}}id="{{id}}"{{/if}}>
22
<div class="card-body">
33
{{#if title}}
44
<div class="d-flex align-items-center">
55
<div class="subheader">{{title}}</div>
66
</div>
77
{{/if}}
8-
<div id="{{name}}" class="carousel slide{{#if fade}} carousel-fade{{/if}}" {{#if auto}}data-bs-ride="carousel"{{/if}}>
8+
<div id="_sqlpage_carousel_{{@component_index}}" class="carousel slide{{#if fade}} carousel-fade{{/if}}" {{#if auto}}data-bs-ride="carousel"{{/if}}>
99
<div class="carousel-indicators{{#if indicators}} carousel-indicators-{{indicators}}{{/if}}{{#if vertical}} carousel-indicators-vertical{{/if}}">
1010
{{#each_row}}
11-
<button type="button" data-bs-target="#{{../name}}" data-bs-slide-to="{{@row_index}}" {{#if (eq @row_index 0)}}class="active"{{/if}}></button>
11+
<button type="button" data-bs-target="#_sqlpage_carousel_{{@../component_index}}" data-bs-slide-to="{{@row_index}}" {{#if (eq @row_index 0)}}class="active"{{/if}}></button>
1212
{{#delay}}
1313
{{flush_delayed}}
1414
<div class="carousel-item {{#if (eq @row_index 0)}}active{{/if}}">

src/render.rs

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ impl<W: std::io::Write> RenderContext<W> {
295295
} else {
296296
PAGE_SHELL_COMPONENT
297297
};
298-
let mut shell_renderer = Self::create_renderer(shell_component, Arc::clone(&app_state))
298+
let mut shell_renderer = Self::create_renderer(shell_component, Arc::clone(&app_state), 0)
299299
.await
300300
.with_context(|| "The shell component should always exist")?;
301301

@@ -484,20 +484,35 @@ impl<W: std::io::Write> RenderContext<W> {
484484
async fn create_renderer(
485485
component: &str,
486486
app_state: Arc<AppState>,
487+
component_index: usize,
487488
) -> anyhow::Result<SplitTemplateRenderer> {
488489
let split_template = app_state
489490
.all_templates
490491
.get_template(&app_state, component)
491492
.await?;
492-
Ok(SplitTemplateRenderer::new(split_template, app_state))
493+
Ok(SplitTemplateRenderer::new(
494+
split_template,
495+
app_state,
496+
component_index,
497+
))
493498
}
494499

495500
/// Set a new current component and return the old one
496501
async fn set_current_component(
497502
&mut self,
498503
component: &str,
499504
) -> anyhow::Result<Option<SplitTemplateRenderer>> {
500-
let new_component = Self::create_renderer(component, Arc::clone(&self.app_state)).await?;
505+
let current_component_index = self
506+
.current_component
507+
.as_ref()
508+
.map(|c| c.component_index)
509+
.unwrap_or(1);
510+
let new_component = Self::create_renderer(
511+
component,
512+
Arc::clone(&self.app_state),
513+
current_component_index + 1,
514+
)
515+
.await?;
501516
Ok(self.current_component.replace(new_component))
502517
}
503518

@@ -552,16 +567,22 @@ pub struct SplitTemplateRenderer {
552567
ctx: Context,
553568
app_state: Arc<AppState>,
554569
row_index: usize,
570+
component_index: usize,
555571
}
556572

557573
impl SplitTemplateRenderer {
558-
fn new(split_template: Arc<SplitTemplate>, app_state: Arc<AppState>) -> Self {
574+
fn new(
575+
split_template: Arc<SplitTemplate>,
576+
app_state: Arc<AppState>,
577+
component_index: usize,
578+
) -> Self {
559579
Self {
560580
split_template,
561581
local_vars: None,
562582
app_state,
563583
row_index: 0,
564584
ctx: Context::null(),
585+
component_index,
565586
}
566587
}
567588
fn name(&self) -> &str {
@@ -585,6 +606,10 @@ impl SplitTemplateRenderer {
585606
.unwrap_or_default(),
586607
);
587608
let mut render_context = handlebars::RenderContext::new(None);
609+
render_context
610+
.block_mut()
611+
.expect("context created without block")
612+
.set_local_var("component_index", JsonValue::Number(self.component_index.into()));
588613
*self.ctx.data_mut() = data;
589614
let mut output = HandlebarWriterOutput(writer);
590615
self.split_template.before_list.render(
@@ -678,7 +703,7 @@ mod tests {
678703
let mut output = Vec::new();
679704
let config = app_config::tests::test_config();
680705
let app_state = Arc::new(AppState::init(&config).await.unwrap());
681-
let mut rdr = SplitTemplateRenderer::new(Arc::new(split), app_state);
706+
let mut rdr = SplitTemplateRenderer::new(Arc::new(split), app_state, 0);
682707
rdr.render_start(&mut output, json!({"name": "SQL"}))?;
683708
rdr.render_item(&mut output, json!({"x": 1}))?;
684709
rdr.render_item(&mut output, json!({"x": 2}))?;
@@ -699,7 +724,7 @@ mod tests {
699724
let mut output = Vec::new();
700725
let config = app_config::tests::test_config();
701726
let app_state = Arc::new(AppState::init(&config).await.unwrap());
702-
let mut rdr = SplitTemplateRenderer::new(Arc::new(split), app_state);
727+
let mut rdr = SplitTemplateRenderer::new(Arc::new(split), app_state, 0);
703728
rdr.render_start(&mut output, json!(null))?;
704729
rdr.render_item(&mut output, json!({"x": 1}))?;
705730
rdr.render_item(&mut output, json!({"x": 2}))?;

0 commit comments

Comments
 (0)