11 | ${title} 12 |
13 | 14 |15 | ${description} 16 |
17 |-
18 | <% tags.forEach(tag => { %>
19 |
- 20 | ${tag} 21 | 22 | <% }) %> 23 |
├── .env.example ├── .github ├── issue_template.md └── pull_request_template.md ├── .gitignore ├── NEWS.md ├── README.md ├── ROADMAP.md ├── TUTORIAL.md ├── TUTORIAL2.md ├── archived ├── TUTORIAL.md └── TUTORIAL2.md ├── assets └── images │ ├── require-auth-directive.excalidraw │ ├── require-auth-directive.png │ ├── welcome-directive.excalidraw │ └── welcome-directive.png ├── code ├── html │ ├── 404.html │ ├── _community_nav.html │ ├── _nav.html │ ├── _search.html │ ├── _top_level_nav.html │ ├── cookbook │ │ └── .keep │ ├── docs │ │ └── .keep │ ├── index.html │ ├── layouts │ │ └── application.html │ ├── logos.html │ ├── reference │ │ └── .keep │ ├── roadmap.html │ ├── security.html │ ├── stickers-thanks.html │ ├── stickers.html │ ├── tutorial │ │ └── .keep │ ├── tutorial2 │ │ └── .keep │ └── videos │ │ └── .keep ├── javascripts │ ├── application.js │ └── controllers │ │ ├── application_controller.js │ │ ├── aside_controller.js │ │ ├── nav_controller.js │ │ └── search_controller.js └── stylesheets │ ├── application.pcss │ ├── markdown.pcss │ └── tailwind.pcss ├── cookbook ├── Background_Worker.md ├── Custom_Function.md ├── File_Upload.md ├── GoTrue_Auth.md ├── Mocking_GraphQL_Storybook.md ├── No_API.md ├── Pagination.md ├── Role-based_Access_Control.md ├── Self-hosting_Redwood.md ├── Sending_Emails.md ├── Supabase_Auth.md ├── Third_Party_API.md └── windows_setup.md ├── docs ├── a11y.md ├── appConfiguration.md ├── assetsAndFiles.md ├── authentication.md ├── builds.md ├── cells.md ├── cliCommands.md ├── connectionPooling.md ├── contributing-walkthrough.md ├── contributing.md ├── cors.md ├── customIndex.md ├── dataMigrations.md ├── deploy.md ├── directives.md ├── environmentVariables.md ├── form.md ├── graphql.md ├── localPostgresSetup.md ├── logger.md ├── mockGraphQLRequests.md ├── prerender.md ├── projectConfiguration.md ├── quick-start.md ├── redwoodRecord.md ├── router.md ├── schemaRelations.md ├── security.md ├── seo.md ├── serverlessFunctions.md ├── services.md ├── storybook.md ├── testing.md ├── toastNotifications.md ├── typescript.md ├── webhooks.md └── webpackConfiguration.md ├── functions ├── .keep └── stickers.js ├── lib ├── build.js ├── docutron.js ├── middleware │ ├── use-extension.js │ ├── use-headers.js │ └── use-redirects.js ├── news.js ├── roadmap.js ├── search.js └── templates │ ├── nav_item.html.template │ ├── news.html.template │ ├── news_article.html.template │ └── page.html.template ├── netlify.toml ├── package.json ├── postcss.config.js ├── prettier.config.js ├── publish ├── downloads │ ├── redwoodjs-diecut_mark.zip │ ├── redwoodjs-logo.zip │ └── redwoodjs-mark.zip ├── favicon.png └── images │ ├── .keep │ ├── diecut.svg │ ├── logo.svg │ ├── mark-logo-cover.png │ ├── mark-logo-transparent.png │ ├── opengraph-256.png │ ├── stickers.png │ ├── structure.png │ └── type.svg ├── tailwind.config.js ├── videos ├── authentication.md ├── router.md └── tutorial.md ├── webpack.config.js └── yarn.lock /.env.example: -------------------------------------------------------------------------------- 1 | # Copy this file to .env and replace with real API keys 2 | 3 | ALGOLIA_API_KEY= 4 | ALGOLIA_SEARCH_KEY= 5 | ALGOLIA_APP_ID= 6 | ALGOLIA_INDEX_NAME=docs-dev 7 | GITHUB_AUTH= 8 | -------------------------------------------------------------------------------- /.github/issue_template.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Issue template 3 | about: Docs Migration 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 🚨 HEADS UP 10 | 11 | In preparation for the 1.0.0 release, the Redwood Docs have been integrated with the main Redwood Framework redwoodjs/redwood repo. We are in the final stages of the migration. Once complete, this repo will be archived. 12 | 13 | > Please do not open new Issues here. Instead, open them at https://github.com/redwoodjs/redwood/issues 14 | 15 | The new doc site uses Docusaurus. The Docs are located here: 16 | - https://github.com/redwoodjs/redwood/tree/main/docs 17 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | 🚨 HEADS UP 2 | 3 | In preparation for the 1.0.0 release, the Redwood Docs have been integrated with the main Redwood Framework redwoodjs/redwood repo. We are in the final stages of the migration. Once complete, this repo will be archived. 4 | 5 | > Please do not open new PRs here. Instead, open them at https://github.com/redwoodjs/redwood/pulls 6 | 7 | The new doc site uses Docusaurus. The Docs are located here: 8 | - https://github.com/redwoodjs/redwood/tree/main/docs 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .env 3 | node_modules 4 | publish/* 5 | !publish/downloads 6 | !publish/images 7 | !publish/favicon.* 8 | !publish/security.txt 9 | yarn-error.log 10 | code/html/cookbook/*.html 11 | !code/html/cookbook/index.html 12 | code/html/docs/*.html 13 | !code/html/docs/index.html 14 | code/html/tutorial/*.html 15 | !code/html/tutorial/index.html 16 | code/html/tutorial2/*.html 17 | !code/html/tutorial2/index.html 18 | code/html/videos/*.html 19 | !code/html/videos/index.html 20 | code/html/_*nav.html 21 | !code/html/_nav.html 22 | !code/html/_community_nav.html 23 | !code/html/_top_level_nav.html 24 | code/html/news.html -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # redwoodjs.com 2 | 3 | This is the repo for https://redwoodjs.com 4 | 5 | The content for the tutorials are managed along with localization over at [learn.redwoodjs.com](https://github.com/redwoodjs/learn.redwoodjs.com). 6 | 7 | Other documentation is pulled from various READMEs in the main [redwoodjs/redwood](https://github.com/redwoodjs/redwood) repo (see `lib/build.js`, the `SECTIONS` constant). 8 | 9 | ## Local Development 10 | 11 | This codebase is built with https://cameronjs.com and relies on plain HTML pages and Javascript with a couple helpers built in to abstract things like partials and layouts. We use https://stimulusjs.org for the few sprinkles of interactivity throughout the site. 12 | 13 | First, make sure that you are running Node 14+. If you're not sure of how to manage your node versions, see [nvm](https://github.com/nvm-sh/nvm) or [nvm-windows](https://github.com/coreybutler/nvm-windows). 14 | 15 | Then build the tutorial and doc pages (after you've installed all dependencies with `yarn install`): 16 | 17 | yarn build 18 | 19 | And to develop locally (you'll need to run `yarn build` once first in order to generate some of the navigation menus): 20 | 21 | yarn dev 22 | 23 | If you are already running a `yarn dev` process, when you `yarn build`, you may need to stop and start `yarn dev` to pick up the new pages properly. 24 | 25 | ## Contributing 26 | 27 | Open a PR against the repo on GitHub. That will build and launch a copy of the site that you can get from the `netlify/redwoodjs/deploy-preview` check (click "Details" to open it): 28 | 29 |  30 | 31 | Double check that your changes look good! 32 | 33 | ## Contributors 34 | 35 | Redwood is amazing thanks to a wonderful [community of contributors](https://github.com/redwoodjs/redwood/blob/main/README.md#contributors). 36 | -------------------------------------------------------------------------------- /TUTORIAL.md: -------------------------------------------------------------------------------- 1 | ## Tutorial Contributions (and Translators) are Welcome! 2 | To support translations, the Redwood Tutorials have been moved to the `learn.redwoodjs.com` Repo: 3 | - **Tutorial Part 1:** [learn.redwoodjs.com/docs/tutorial/](https://github.com/redwoodjs/learn.redwoodjs.com/tree/main/docs/tutorial) 4 | - **Tutorial Part 2:** [learn.redwoodjs.com/docs/tutorial2/](https://github.com/redwoodjs/learn.redwoodjs.com/tree/main/docs/tutorial2) 5 | 6 | Instructions for the translation workflow and contributing are here: 7 | - [learn.redwoodjs.com/README.md](https://github.com/redwoodjs/learn.redwoodjs.com/blob/main/README.md) 8 | 9 | 10 | ## Translation Project Lead 11 | For more information and to learn how you can help contribute and translate, please contact Core Team member [@clairefro](https://github.com/clairefro) 12 | -------------------------------------------------------------------------------- /TUTORIAL2.md: -------------------------------------------------------------------------------- 1 | ## Tutorial Contributions (and Translators) are Welcome! 2 | To support translations, the Redwood Tutorials have been moved to the `learn.redwoodjs.com` Repo: 3 | - **Tutorial Part 1:** [learn.redwoodjs.com/docs/tutorial/](https://github.com/redwoodjs/learn.redwoodjs.com/tree/main/docs/tutorial) 4 | - **Tutorial Part 2:** [learn.redwoodjs.com/docs/tutorial2/](https://github.com/redwoodjs/learn.redwoodjs.com/tree/main/docs/tutorial2) 5 | 6 | Instructions for the translation workflow and contributing are here: 7 | - [learn.redwoodjs.com/README.md](https://github.com/redwoodjs/learn.redwoodjs.com/blob/main/README.md) 8 | 9 | 10 | ## Translation Project Lead 11 | For more information and to learn how you can help contribute and translate, please contact Core Team member [@clairefro](https://github.com/clairefro) 12 | -------------------------------------------------------------------------------- /assets/images/require-auth-directive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redwoodjs/redwoodjs-com-archive/f6681f5c5d65d04b7bb85a9c0d679b71685ed3bc/assets/images/require-auth-directive.png -------------------------------------------------------------------------------- /assets/images/welcome-directive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redwoodjs/redwoodjs-com-archive/f6681f5c5d65d04b7bb85a9c0d679b71685ed3bc/assets/images/welcome-directive.png -------------------------------------------------------------------------------- /code/html/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 |Are you lost in the woods?
16 | 17 |Are you looking for the tutorials? They've moved here:
18 | 19 |Here are some official assets for linking to the project.
7 | 8 |65 | Please do not claim endorsement of your product or service by RedwoodJS without permission. 66 | 67 |
Last updated 21 June 2021
9 |To view the RedwoodJS Security policy, click here
10 |If you discover a potential security issue, do let us know as soon as possible. We'll quickly work toward a resolution, so please provide us with a reasonable amount of time before disclosure to the public or a third-party.
14 |Contact us at security@redwoodjs.com
16 |Thank you for helping improve Redwood security!
18 |The day may come when we ask you for a favor...
33 |And that day is today: star us on GitHub!
34 | Star on GitHub 35 |...
97 | if (parent.tagName === 'PRE') {
98 | parent.classList.add('relative')
99 | var button = document.createElement('button')
100 | button.classList.add(...COPY_BUTTON_CSS)
101 | button.textContent = 'Copy'
102 | block.parentElement.appendChild(button)
103 |
104 | new ClipboardJS('.copy-button', {
105 | text: (trigger) => {
106 | this._copiedMessage(trigger)
107 | return this._stripComments(trigger.previousElementSibling.innerText)
108 | },
109 | })
110 | }
111 | }
112 | }
113 |
114 | _copiedMessage(trigger) {
115 | trigger.focus()
116 | trigger.textContent = 'Copied'
117 | setTimeout(() => {
118 | trigger.textContent = 'Copy'
119 | }, 750)
120 | }
121 |
122 | // strips any leading comments out of a chunk of text
123 | _stripComments(content) {
124 | let lines = content.split('\n')
125 |
126 | if (lines[0].match(/^\/\/|\*/)) {
127 | lines.shift()
128 | // remove empty lines after comments
129 | while (lines[0].trim() === '') {
130 | lines.shift()
131 | }
132 | }
133 |
134 | return lines.join('\n')
135 | }
136 |
137 | _openCollapsedSectionForHash() {
138 | let hash = location.hash
139 |
140 | if (hash) {
141 | hash = hash.substring(1)
142 |
143 | const element = document.getElementById(hash)
144 | const parent = element.parentNode
145 |
146 | if (parent.tagName === 'DETAILS') {
147 | parent.open = true
148 | window.scrollTo(0, element.offsetTop)
149 | }
150 | }
151 | }
152 |
153 | _spawnCones() {
154 | let count = 0
155 |
156 | while (count < 20) {
157 | const fallTime = Math.random() * 2 + 1.5
158 | const rotateStart = Math.random() * 360 - 180
159 | const rotateEnd = Math.random() * 360 - 180
160 | const wait = Math.random() * 1
161 | const size = Math.random() * 64 + 24
162 | const cone = this.coneTarget.cloneNode(true)
163 |
164 | this.element.appendChild(cone)
165 | cone.style.left = `${Math.random() * this.element.offsetWidth}px`
166 | cone.style.width = `${size}px`
167 | cone.style.setProperty('--rotateStart',`${rotateStart}deg`)
168 | cone.style.setProperty('--rotateEnd',`${rotateEnd}deg`)
169 |
170 | setTimeout(() => {
171 | cone.classList.remove('hidden')
172 | cone.style.animation = `falling ${fallTime}s ease-in forwards`
173 | }, wait * 1000)
174 |
175 | count++
176 | }
177 | }
178 |
179 | async _showStarCount() {
180 | const stars = await this._getStarCount()
181 | this.starsTarget.textContent = stars
182 | }
183 |
184 | async _getStarCount() {
185 | const response = await fetch('https://api.github.com/repos/redwoodjs/redwood')
186 | const body = await response.json()
187 | return body.stargazers_count
188 | }
189 |
190 | get isHomePage() {
191 | return location.pathname === '/'
192 | }
193 |
194 | get someInputHasFocus() {
195 | return ['INPUT', 'TEXTAREA'].indexOf(document.activeElement.tagName) !== -1
196 | }
197 | }
198 |
--------------------------------------------------------------------------------
/code/javascripts/controllers/aside_controller.js:
--------------------------------------------------------------------------------
1 | import { Controller } from 'stimulus'
2 |
3 | let scroll
4 |
5 | export default class extends Controller {
6 | connect() {
7 | this.element.scrollTop = scroll
8 | }
9 |
10 | saveScroll() {
11 | scroll = this.element.scrollTop
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/code/javascripts/controllers/nav_controller.js:
--------------------------------------------------------------------------------
1 | import { Controller } from 'stimulus'
2 |
3 | export default class extends Controller {
4 | static get targets() {
5 | return ['link']
6 | }
7 |
8 | connect() {
9 | this._highlightNav()
10 | document.dispatchEvent(new Event('navigated'))
11 | }
12 |
13 | // opens/closes a nav section
14 | toggle(event) {
15 | event.preventDefault()
16 | event.currentTarget.nextSibling.nextSibling.classList.toggle('hidden')
17 | }
18 |
19 | // Highlight nav items if the URL matches the `href` on the link.
20 | //
21 | // If no links matched, look at the data-match attribute on the first link in
22 | // a list and if one of those matches, highlight it
23 | _highlightNav() {
24 | let linkFound = false
25 |
26 | this.linkTargets.forEach((link) => {
27 | if (this._linkDoesMatch(link)) {
28 | this._activateLink(link)
29 | linkFound = true
30 | } else {
31 | this._deactivateLink(link)
32 | }
33 | return !linkFound
34 | })
35 |
36 | if (!linkFound) {
37 | this._fallbackLink()
38 | }
39 | }
40 |
41 | _linkDoesMatch(link) {
42 | return location.href.indexOf(link.href) !== -1
43 | }
44 |
45 | _fallbackLink() {
46 | this.linkTargets.every((link) => {
47 | if (link.dataset.match && location.href.indexOf(link.dataset.match) !== -1) {
48 | this._activateLink(link)
49 | return false
50 | } else {
51 | return true
52 | }
53 | })
54 | }
55 |
56 | _activateLink(link) {
57 | link.classList.add(...this.activeClasses)
58 | if (this.removeClasses.length) {
59 | link.classList.remove(...this.removeClassesClasses)
60 | }
61 | // make sure whole parent list is visible
62 | link.closest('ul').classList.remove('hidden')
63 | }
64 |
65 | _deactivateLink(link) {
66 | link.classList.remove(...this.activeClasses)
67 | }
68 |
69 | get removeClasses() {
70 | return this.data.get('remove') ? this.data.get('remove').split(' ') : []
71 | }
72 |
73 | get activeClasses() {
74 | return this.data.get('active').split(' ')
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/code/javascripts/controllers/search_controller.js:
--------------------------------------------------------------------------------
1 | import { Controller } from 'stimulus'
2 | import template from 'lodash.template'
3 | import escape from 'lodash.escape'
4 | import clone from 'lodash.clone'
5 | import algoliasearch from 'algoliasearch'
6 |
7 | export default class extends Controller {
8 | static get targets() {
9 | return ['input', 'results']
10 | }
11 |
12 | initialize() {
13 | // create a handler bound to `this` that we can add and remove
14 | this.documentClickHandler = () => {
15 | this.close()
16 | }
17 |
18 | this.client = algoliasearch(process.env.ALGOLIA_APP_ID, process.env.ALGOLIA_SEARCH_KEY)
19 | this.index = this.client.initIndex(process.env.ALGOLIA_INDEX_NAME)
20 | this.searchOptions = {
21 | hitsPerPage: 10,
22 | attributesToRetrieve: '*',
23 | attributesToSnippet: 'text:20,section:20',
24 | attributesToHighlight: null,
25 | snippetEllipsisText: '…',
26 | analytics: true,
27 | }
28 |
29 | this.searchResultTemplate = template(`
30 |
31 | \${text}
38 |No docs found for ${data.query}
` 93 | ) 94 | } 95 | 96 | const sections = [] 97 | data.hits.map((hit) => { 98 | if (sections.indexOf(hit.book) === -1) { 99 | sections.push(hit.book) 100 | } 101 | }) 102 | 103 | const items = {} 104 | data.hits.forEach((hit) => { 105 | let attributes = Object.assign(clone(hit), { 106 | text: this._formatText(hit.text), 107 | section: this._formatSection(hit.section), 108 | }) 109 | let html = this.searchResultTemplate(attributes) 110 | 111 | if (items[hit.book]) { 112 | items[hit.book].push(html) 113 | } else { 114 | items[hit.book] = [html] 115 | } 116 | }) 117 | 118 | let output = '' 119 | for (let item in items) { 120 | output += `This is the about page!
98 |All the news that's fit to print about RedwoodJS. If you've got news we should feature open a PR. 7 |
15 | ${description} 16 |
17 |9 |18 | 19 |10 | Out of the box, @RedwoodJS provides automatic 11 | code-splitting and a super easy to use loading state you can show when page loads take longer than a 12 | configurable amount of time (great for slow connections) without any white page flash or annoying shenanigans. 13 | Check the vid for how! pic.twitter.com/c4T0P213dM 14 |
15 | — Tom Preston-Werner (@mojombo) 16 | April 15, 2020 17 |