Skip to content

Commit 086fafc

Browse files
committed
chore(docs): update readme.md
chore(build): update build to use yarn fix(template): change search placeholder
1 parent 6bfa205 commit 086fafc

9 files changed

Lines changed: 202 additions & 86 deletions

File tree

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Coding Conventions
2+
3+
## AMD Modules
4+
5+
All JS files use RequireJS AMD format. Never use CommonJS `require()` or ES modules.
6+
7+
```javascript
8+
// Correct — AMD define with dependency array
9+
define(['jquery', 'ractive', 'rv!templates/template'], function ($, Ractive, mainTemplate) {
10+
'use strict';
11+
// ...
12+
});
13+
```
14+
15+
Module paths are mapped in `config.js`. When adding a dependency:
16+
1. `npm install --save <package>`
17+
2. Add path mapping to `config.js`
18+
3. Add to `define([...])` dependency array
19+
20+
## jQuery noConflict
21+
22+
jQuery runs in `$.noConflict()` mode. **IMPORTANT:** Always use the `$` variable from the AMD module parameter, never assume a global `$` or `jQuery`.
23+
24+
```javascript
25+
// Correct — $ comes from the AMD define callback
26+
define(['jquery'], function ($) {
27+
$.ajax({ ... });
28+
$('.ossw-search-bar', el).show();
29+
});
30+
```
31+
32+
## Ractive Templates
33+
34+
- Templates use Ractive mustache syntax (`{{variable}}`, `{{{unescaped}}}`, `{{#if}}`, `{{#each}}`)
35+
- Located in `templates/` directory
36+
- Loaded via RequireJS `rv!` plugin: `'rv!templates/template'`
37+
- Events bound with `on-click="eventName"` and `on-keyup="eventName"`
38+
39+
## CSS
40+
41+
- All widget classes use the `ossw-` prefix (OpenStack Search Widget) to avoid conflicts with host page styles
42+
- CSS is loaded as a text module and injected into `<head>` at runtime — no external stylesheet link needed
43+
- Widget uses `z-index` values in the 99999991–99999997 range for the popup overlay
44+
45+
## API Integration
46+
47+
- AJAX calls use `$.ajax()` with `dataType: "json"`
48+
- Suggestions use a debounce pattern: 500ms `setTimeout` + abort previous XHR
49+
- Search results prefer `meta_title`/`meta_description` over `title`/`content`
50+
- Result detail text is truncated to 100 characters (`MAX_DETAIL_LEN`)
51+
52+
## Build Output
53+
54+
`embed.min.js` is committed to the repo. After any JS or template change, rebuild with `make js` and commit the updated `embed.min.js`.
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Project: OpenStack Search Bar Widget
2+
3+
**Last Updated:** 2026-03-11
4+
5+
## Overview
6+
7+
Embedded search bar widget for OpenStack sites. Provides search with autocomplete suggestions and paginated results via a popup overlay. Designed to be embedded on any page via a single `<div>` + script tag.
8+
9+
## Technology Stack
10+
11+
- **Language:** JavaScript (ES5, no transpilation)
12+
- **Module System:** RequireJS (AMD) with `almond` for production builds
13+
- **UI Framework:** Ractive.js 0.10.x (reactive templates with mustache syntax)
14+
- **DOM / AJAX:** jQuery 3.x (`$.noConflict()` mode — always use `$` from the AMD module, never global)
15+
- **Build Tool:** RequireJS Optimizer (`r.js`) via Makefile
16+
- **Icons:** Font Awesome 4.7 (loaded externally by the embedding page)
17+
- **Tests:** None configured
18+
19+
## Directory Structure
20+
21+
```
22+
├── app/app.js # Main widget logic (search, suggestions, pagination)
23+
├── config.js # RequireJS path configuration
24+
├── embed.js # Entry point — loads jQuery + app, calls app.init()
25+
├── embed.build.js # r.js optimizer build config
26+
├── embed.min.js # Built/minified output (committed)
27+
├── css/widget-styles.css
28+
├── templates/template.html # Ractive template (mustache syntax)
29+
├── example/index.html # Test page for the widget
30+
└── Makefile
31+
```
32+
33+
## Key Files
34+
35+
- **Entry Point:** `embed.js` → requires `app/app.js` → calls `app.init()`
36+
- **Build Config:** `embed.build.js` (r.js optimizer settings)
37+
- **RequireJS Paths:** `config.js` (maps module names to `node_modules/` paths)
38+
- **Output:** `embed.min.js` (self-contained bundle with almond loader)
39+
40+
## Development Commands
41+
42+
| Task | Command |
43+
|------|---------|
44+
| Install deps | `make init` (or `npm install`) |
45+
| Build CSS | `make css` |
46+
| Build JS | `make js` |
47+
| Build all | `make` |
48+
| Test locally | Open `example/index.html` in a browser after building |
49+
50+
## Architecture
51+
52+
### Embedding
53+
54+
Host pages add a `<div class="openstack-search-bar">` with data attributes and load `embed.min.js`:
55+
56+
```html
57+
<div class="openstack-search-bar" data-baseUrl="search.openstack.org" data-context="www-openstack"></div>
58+
```
59+
60+
- `data-baseUrl` — API host (default: `search.openstack.org`)
61+
- `data-context` — search context/scope (default: `www-openstack`)
62+
63+
### API Endpoints
64+
65+
All requests go to `https://{baseUrl}/api/public/v1/`:
66+
67+
| Endpoint | Purpose |
68+
|----------|---------|
69+
| `search/{context}/{term}?page=N&page_size=N` | Full search with pagination |
70+
| `suggestions/{context}/{term}` | Autocomplete suggestions |
71+
72+
### Widget Lifecycle
73+
74+
1. `embed.min.js` loads → RequireJS resolves AMD modules
75+
2. `app.init()` finds all `.openstack-search-bar` elements
76+
3. Each element gets its own Ractive instance with search/suggestion/pagination state
77+
4. CSS is injected into `<head>` at runtime

.nvmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
20

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
all: css js
22

33
init:
4-
npm install --save almond requirejs requirejs-text jquery ractive rv
4+
yarn install
55

66
css:
77
node_modules/requirejs/bin/r.js -o cssIn=css/widget-styles.css out=css/widget-styles_embed.css

README.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,19 @@
22

33
Search Bar embedded widget using [RequireJS](http://requirejs.org) and [Ractive.js](http://ractivejs.org).
44

5-
## Building the widget
5+
## Prerequisites
6+
7+
- [nvm](https://github.com/nvm-sh/nvm) (recommended) or Node.js 20+
8+
- [Yarn](https://classic.yarnpkg.com/)
69

7-
Assuming RequireJS is already installed:
10+
## Building the widget
811

912
```console
13+
$ nvm use
1014
$ make init
1115
$ make
1216
```
1317

14-
Now you can test ``embed.min.js`` with ``examples/index.html``
18+
`make init` runs `yarn install` to fetch dependencies. `make` builds both the CSS and the minified JS bundle (`embed.min.js`).
19+
20+
You can test the result by opening `example/index.html` in a browser.

embed.min.js

Lines changed: 14 additions & 28 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package-lock.json

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

templates/template.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<div class="ossw-search-wrapper">
22
<div class="ossw-search-bar-wrapper">
3-
<input value="{{term}}" on-keyup="search" type="text" id="search-bar-input" placeholder="Search OpenStack" />
3+
<input value="{{term}}" on-keyup="search" type="text" id="search-bar-input" placeholder="Search this site" />
44
<i class="fa fa-times ossw-search-bar-close" on-click="clear"></i>
55
</div>
66
<div class="ossw-search-suggestions-wrapper">

yarn.lock

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2+
# yarn lockfile v1
3+
4+
5+
almond@^0.3.3:
6+
version "0.3.3"
7+
resolved "https://registry.npmjs.org/almond/-/almond-0.3.3.tgz#a0e7c95ac7624d6417b4494b1e68bff693168a20"
8+
integrity sha512-Eh5QhyxrKnTI0OuGpwTRvzRrnu1NF3F2kbQJRwpXj/uMy0uycwqw2/RhdDrD1cBTD1JFFHFrxGIU8HQztowR0g==
9+
10+
jquery@^3.3.1:
11+
version "3.7.1"
12+
resolved "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz#083ef98927c9a6a74d05a6af02806566d16274de"
13+
integrity sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==
14+
15+
ractive@^0.10.9:
16+
version "0.10.14"
17+
resolved "https://registry.npmjs.org/ractive/-/ractive-0.10.14.tgz#0d3c2d2c8e4c686970f94127f29c2fef6f9de37c"
18+
integrity sha512-56mYF41urs/v0SUBpLIa1GyZrnugRBB3rkZlKHnPxcbPDK7mFIPSaA2fKn+4DKsjmMkSbmmXqaHrzZdx9keZsA==
19+
20+
ractive@^0.9.11:
21+
version "0.9.14"
22+
resolved "https://registry.npmjs.org/ractive/-/ractive-0.9.14.tgz#aa0834185bfaa57bfeb12ab9f842c1904fe25a6d"
23+
integrity sha512-qqOkqPho+X84N2xZx0HcxaGCSBnBzpv3Y7NzQxqj5hsAfnq7HAaHq+6w1PQhyo8tCZj+BijbKP6t1uJWmgBnLQ==
24+
25+
requirejs-text@^2.0.15:
26+
version "2.0.16"
27+
resolved "https://registry.npmjs.org/requirejs-text/-/requirejs-text-2.0.16.tgz#b6f3e20689aa998e36641bc4f8bd11b7964ac872"
28+
integrity sha512-XrzjeTb1pwzIWmkz8qnUiM20gENgiwB+66IciNuziwlaPAJsYQsQPSYyQ1kD4tGKGZxTisIfDbOHk02DpI/76Q==
29+
30+
requirejs@^2.3.6:
31+
version "2.3.8"
32+
resolved "https://registry.npmjs.org/requirejs/-/requirejs-2.3.8.tgz#bca0614b618ab2122462597e44878db7558bbba3"
33+
integrity sha512-7/cTSLOdYkNBNJcDMWf+luFvMriVm7eYxp4BcFCsAX0wF421Vyce5SXP17c+Jd5otXKGNehIonFlyQXSowL6Mw==
34+
35+
rv@^0.1.8:
36+
version "0.1.8"
37+
resolved "https://registry.npmjs.org/rv/-/rv-0.1.8.tgz#1d5f0203a0d3a59158bd2de8bd8a59efc9cb7541"
38+
integrity sha512-zKF0bGUi1yHZuxtUzuFVOLTy19XeAH0g/4SQ/GkS5HRMOIJyRA69/LV45Tz6k0J48KaYQeElsQsVeotuav3Ouw==
39+
40+
rvc@^0.5.0:
41+
version "0.5.0"
42+
resolved "https://registry.npmjs.org/rvc/-/rvc-0.5.0.tgz#fc3546d4f909218b08c90043304e83cecf80072e"
43+
integrity sha512-6ipnueSkuW2KTGakQkpr1fO62PStz47R+gTLXq3ughAzhlqIiwyl/LJtyUcmLrcg2CPPuNrQkwKQP+TD9bDreg==
44+
dependencies:
45+
ractive "^0.9.11"

0 commit comments

Comments
 (0)