Skip to content

Commit

Permalink
A collection of tutorial text fixes (dojo#297)
Browse files Browse the repository at this point in the history
* dojo#245 Feedback 1
dojo#244 Feedback 1
dojo#270 Feedback 1
dojo#258 Feedback 1
dojo#251 Feedback 3
dojo#251 Feedback 4
dojo#250 Feedback 2
dojo#295 Feedback 1
dojo#295 Feedback 5
dojo#294 Feedback 3
dojo#294 Feedback 9
dojo#294 Feedback 12
dojo#294 Feedback 13
dojo#293 Feedback 1
dojo#293 Feedback 2
dojo#293 Feedback 14
dojo#293 Feedback 15
dojo#291 Feedback 1
dojo#291 Feedback 2
dojo#291 Feedback 3
dojo#291 Feedback 5
dojo#291 Feedback 6
dojo#291 Feedback 8
dojo#291 Feedback 16
dojo#289 Feedback 6

Resolves dojo#273
Resolves dojo#274
Resolves dojo#282
Resolves dojo#283
Resolves dojo#284
Resolves dojo#286
Resolves dojo#287
Resolves dojo#242
Resolves dojo#241
Resolves dojo#239
Resolves dojo#238
Resolves dojo#234
Resolves dojo#232
Resolves dojo#231
Resolves dojo#227
Resolves dojo#271
Resolves dojo#268

* Fix instruction text in tutorial
  • Loading branch information
umaar authored and edhager committed Oct 26, 2017
1 parent eaf448d commit a987f3e
Show file tree
Hide file tree
Showing 11 changed files with 43 additions and 41 deletions.
2 changes: 1 addition & 1 deletion site/source/tutorials/003_creating_widgets/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ To allow our `Worker` widget to be styled, we need to modify the class. First, a

{% include_codefile 'demo/finished/biz-e-corp/src/widgets/Worker.ts' lines:15-32 %}

If you return to the browser, you'll see that the widget now has the classes applied and looks a little better. While you are there, open up the developer tools and look at the CSS classes that have been applied to the widget's components. Notice that we don't have class names such as `.worker` or `.image` like we used in the CSS file, rather we have something like `.worker__image__3aIJl`. The `dojo build` command uses CSS Modules to obfuscate class names when it compiles the project to ensure that CSS selectors are localized to a given widget. There are also ways to provide global styling rules (called "themes"). To learn more about those, take a look at the [Theming an Application](../comingsoon.html) tutorial in the Cookbook section.
If you return to the browser, you'll see that the widget now has the classes applied and looks a little better. While you are there, open up the developer tools and look at the CSS classes that have been applied to the widget's components. Notice that we don't have class names such as `.worker` or `.image` like we used in the CSS file, rather we have something like `.worker__image__3aIJl`. The `dojo build` command uses CSS Modules to obfuscate class names when it compiles the project to ensure that CSS selectors are localized to a given widget. There are also ways to provide global styling rules (called "themes"). To learn more about those, take a look at the [Theming an Application](../007_theming/) tutorial in the Cookbook section.

We've now updated our application to display a single Biz-E-Body, but our goal is to display a collection of Biz-E-Body items. We could certainly add additional `Worker` widgets to our application, but they would all be siblings of the `Banner` widget and could be difficult to style properly. In the next section, we'll create a simple container widget that will manage the layout of the `Worker` widgets.

Expand Down
2 changes: 1 addition & 1 deletion site/source/tutorials/005_form_widgets/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ The form is now ready to be integrated into the application. We will do that in

{% task 'Integrate the form into the application.' %}

Now that the `WorkerForm` widget is complete, we will update the `App` class to use it. First, we need to address how to store the user-completed form data. Recall that the `WorkerForm` will accept an `onFormInput` property that will allow the `App` class to be informed when a field value changes. However, the `App` class does not currently have a place to store those changes. We will add a private property to the `App` to store this state, and a method to update the state and re-render the parts of the application that have changed. As the application grows and needs to store more data, using private properties on a widget class can become difficult to maintain. Dojo 2 uses containers and injectors to help manage the complexities of dealing with state in a large application. For more information, refer to the [Containers and Injecting State](../comingsoon.html) article.
Now that the `WorkerForm` widget is complete, we will update the `App` class to use it. First, we need to address how to store the user-completed form data. Recall that the `WorkerForm` will accept an `onFormInput` property that will allow the `App` class to be informed when a field value changes. However, the `App` class does not currently have a place to store those changes. We will add a private property to the `App` to store this state, and a method to update the state and re-render the parts of the application that have changed. As the application grows and needs to store more data, using private properties on a widget class can become difficult to maintain. Dojo 2 uses containers and injectors to help manage the complexities of dealing with state in a large application. For more information, refer to the [Containers and Injecting State](../1010_containers_and_injecting_state/) article.

{% instruction 'Add `_newWorker` as a private property.' %}

Expand Down
4 changes: 2 additions & 2 deletions site/source/tutorials/006_deploying_to_production/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,15 +117,15 @@ The build tool is designed to cover the most common use cases for developing and

To eject a project, use the `dojo eject` command. You will be prompted to ensure that you understand that this is a non-reversible action. Entering **'y'** will begin to export process. The export process generates a new directory - `config` that contains all of the exported configuration information for each of the `dojo-cli` tools that the project had been using. The process will also install some additional dependencies that the project now requires.

The project is now configured to be managed as a webpack project. Changes can be made to the build configuration by altering `config/build-webpack/webpack.config.js`. A build can then be triggered by running `webpack`'s build command and providing the configuration. That command is: `./node_modules/.bin/webapack --config ./config/build-webpack/webpack.config.js`.
The project is now configured to be managed as a webpack project. Changes can be made to the build configuration by altering `config/build-webpack/webpack.config.js`. A build can then be triggered by running `webpack`'s build command and providing the configuration. That command is: `./node_modules/.bin/webpack --config ./config/build-webpack/webpack.config.js`.

{% section %}

## Summary

For many software projects, preparing an application for deployment to production often involves creating complicated settings and at least a little bit of experimentation. Dojo 2, on the other hand, provides a single command, `dojo build` that is used both during development as well as for production deployments.

While the `dojo build` command addresses many use cases, a few configuration options are necessary to support certain development and deployment scenarios. The `--locale`, `--supportedLocales`, and `--messageBundles` arguments are used to configuration the applications internationalization support. The `--debug` argument allows the results of the build to be examined in more depth. Finally, the `--disableLazyWidgetDetection` argument can be used to optimize how an application loads widgets.
While the `dojo build` command addresses many use cases, a few configuration options are necessary to support certain development and deployment scenarios. The `--locale`, `--supportedLocales`, and `--messageBundles` arguments are used to configurate the applications internationalization support. The `--debug` argument allows the results of the build to be examined in more depth. Finally, the `--disableLazyWidgetDetection` argument can be used to optimize how an application loads widgets.

To ensure repeatable builds, all of the configuration options for the `dojo` CLI commands can be stored in `.dojorc`, an ideal choice when it is necessary to ensure that consecutive builds are executed with the same parameters.

Expand Down
6 changes: 3 additions & 3 deletions site/source/tutorials/007_theming/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ paginate: true
# Theming

## Overview
This tutorial will extend on previous tutorials where we created the basic biz-e-corp application. In this tutorial, we will adapt the app to allow it to be themed, then write a theme and apply it to our application. This will be done using the powerful theming system that is included in Dojo 2 widget system.
This tutorial will extend on previous tutorials where we created the basic biz-e-corp application. In this tutorial, we will adapt the app to allow it to be themed, then write a theme and apply it to our application. This will be done using the powerful theming system that is included in the Dojo 2 widget system.

## Prerequisites
You can [download](../assets/007_themeing-initial.zip) the demo project and run `npm install` to get started.
You can [download](../assets/007_theming-initial.zip) the demo project and run `npm install` to get started.

The `@dojo/cli` command line tool should be installed globally. Refer to the [Dojo 2 local installation](../000_local_installation/) article for more information.

Expand Down Expand Up @@ -107,7 +107,7 @@ Let's start by creating a red `Worker` and observe our theme being applied corre
}
```

To apply a theme to a widget, simply pass the `theme` as a property to widgets have the `ThemeableMixin` applied. To ensure that the entire application applies the `theme` it needs to be passed to all the themeable widgets in our application. This can become problematic when an application using a mixture of themeable and non-themeable widgets or uses a widget from a third party, meaning that there is no guarantee that the `theme` will be propagated as required.
To apply a theme to a widget, simply pass the `theme` as a property to widgets to have the `ThemeableMixin` applied. To ensure that the entire application applies the `theme` it needs to be passed to all the themeable widgets in our application. This can become problematic when an application uses a mixture of themeable and non-themeable widgets, or uses a widget from a third party, meaning that there is no guarantee that the `theme` will be propagated as required.

{% aside 'What is a registry?' %}
A registry provides a mechanism to inject external payloads into widgets throughout the application tree. To learn more, take a look at the [container tutorial](../1010_containers_and_injecting_state/) and [registry tutorial](../1020_registries/).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ This tutorial assumes that you have gone through the [beginner tutorial](../001_

{% task 'Create a class to manage application state.' %}

To begin our discussion, let's review the initial version of `App`:
To begin our tutorial, let's review the initial version of `App`:

{% include_codefile 'demo/initial/biz-e-corp/src/widgets/App.ts' %}

Most of this widget is dedicated to holding and managing the `WorkerData` in the application. Notice, however, that it never actually uses that data itself. `App` is only containing the state and passing it to the children as required via properties. Lifting up state to the highest common widget in the tree is a valid pattern, but as an application's state grows in size and complexity, it is often desirable to decouple this from widgets. In larger applications, the `App` class would become complicated and more difficult to maintain due to the additional state information that it would be required to track. Since the state information is not a primary concern of the `App` class, let's refactor it out of `App` and into a new `ApplicationContext` class that extends the base `Injector`.

{% instruction 'Add the following to `ApplicationContext.ts`.' %}
{% instruction 'Add the following to the existing `ApplicationContext.ts` file in the `src` directory' %}

{% include_codefile 'demo/finished/biz-e-corp/src/ApplicationContext.ts' %}

Expand All @@ -45,9 +45,9 @@ The `ApplicationContext` contains the application state information. The base `I

{% include_codefile 'demo/finished/biz-e-corp/src/ApplicationContext.ts' lines:26-35 %}

The `formInput` method provides the same functionality as the `_onFormInput` method in the `App` class and the `submitForm` method is analogous to `_addWorker` from the `App` class. The implementations vary slightly as the `ApplicationContext` has dedicated fields to store the state information. Also, since the `ApplicationContext` is not a widget, it cannot call `invalidate();` to schedule a re-render. Instead the instance needs to emit an `invalidate` event that instructs associated widgets to `invalidate` themselves.
The `formInput` method provides the same functionality as the `_onFormInput` method in the `App` class and the `submitForm` method is analogous to the `_addWorker` method from the `App` class. The implementations vary slightly as the `ApplicationContext` has dedicated fields to store the state information. Also, since the `ApplicationContext` is not a widget, it cannot call `invalidate();` to schedule a re-render. Instead the instance needs to emit an `invalidate` event that instructs associated widgets to `invalidate` themselves.

Notice that the `ApplicationContext` does not contain any code to load state information. Currently its only role is only to manage the application's state provided on initialization via its `constructor`. However as the requirements for the application become more advanced the `ApplicationContext` could make requests to fetch and modify data from a remote service or local storage mechanism.
Notice that the `ApplicationContext` does not contain any code to load state information. Currently its only role is only to manage the application's state provided on initialization via its `constructor`. However as the requirements for the application become more advanced, the `ApplicationContext` could make requests to fetch and modify data from a remote service or local storage mechanism.

Now that we have moved state management to a dedicated module, we need a way to register the state and connect it to sections of our application. We will do this by creating a registry and registering the `ApplicationContext` injector.

Expand All @@ -61,9 +61,9 @@ Currently, the application's `main` module is only responsible for creating the

{% include_codefile 'demo/initial/biz-e-corp/src/main.ts' %}

Now, we need to update `main` to construct and populate an instance of `ApplicationContext`, create a `registry` and then define the `ApplicationContext` as an injector in the registry. Lastly, in order to make the `registry` available within the widget tree, we need to pass the `registry` as a property to the `projector`.
Now, we need to update the `main` module to construct and populate an instance of `ApplicationContext`, create a `registry` and then define the `ApplicationContext` as an injector in the registry. Lastly, in order to make the `registry` available within the widget tree, we need to pass the `registry` as a property to the `projector`.

{% instruction 'Import the `ApplicationContext` module and add this code to `main`:' %}
{% instruction 'Import the `ApplicationContext` module and add this code to the `main` module:' %}

{% include_codefile 'demo/finished/biz-e-corp/src/main.ts' lines:4,9-28 %}

Expand Down Expand Up @@ -105,7 +105,7 @@ Normally, a separate `Container` is created for each widget that needs to have `

{% include_codefile 'demo/finished/biz-e-corp/src/containers/WorkerContainerContainer.ts' lines:1-4 %}

The first `import` gives the module access to the `Container` factory function which will be used to construct the container. The other `import` allow the module to use the `ApplicationContext` to extract state, use the `WorkerContainerProperties` to receive properties from its parent, and wrap the `WorkerContainer` class with the `container`.
The first `import` gives the module access to the `Container` factory function which will be used to construct the container. The other `import` allows the module to use the `ApplicationContext` to extract state, use the `WorkerContainerProperties` to receive properties from its parent, and wrap the `WorkerContainer` class with the `container`.

Next, we need to address the fact that the container has two places to get properties from - its parent widget and the `ApplicationContext`. To tell the container how to manage this, we will create a function called `getProperties`.

Expand Down
6 changes: 3 additions & 3 deletions site/source/tutorials/1015_form_validation/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Right now the error object should mirror `WorkerFormData` in both `WorkerForm.ts

{% include_codefile 'demo/finished/biz-e-corp/src/widgets/WorkerForm.ts' lines:15-19 %}

Defining the properties in `WorkerFormErrors` as optional allows us to effectively create three possible states for form fields: unvalidated, valid, and invalid.
Defining the properties in the `WorkerFormErrors` interface as optional allows us to effectively create three possible states for form fields: unvalidated, valid, and invalid.

{% instruction 'Next add `formErrors` to `ApplicationContext`' %}

Expand Down Expand Up @@ -95,9 +95,9 @@ For now, we will test our validation by calling it directly in every `onInput` e
this._formErrors = deepAssign({}, this._formErrors, this._validateInput(input));
```

{% instruction 'Update the `WorkerForm` render to display validation state' %}
{% instruction 'Update the render method of the `WorkerForm` class to display validation state' %}

At this point in our progress, the `WorkerForm` widget holds the validation state of each form field in its `formErrors` property, updated every time an `onInput` handler is called. All that remains is to pass the valid/invalid property to the inputs themselves. Luckily the Dojo 2 `TextInput` widget contains an `invalid` property that sets `aria-invalid` and toggles classes used for visual styling.
At this point in our progress, the `WorkerForm` widget holds the validation state of each form field in its `formErrors` property, updated every time an `onInput` handler is called. All that remains is to pass the valid/invalid property to the inputs themselves. Luckily the Dojo 2 `TextInput` widget contains an `invalid` property that sets the `aria-invalid` attribute on a DOM node, and toggles classes used for visual styling.

The updated render function in `WorkerForm.ts` should set the `invalid` property on all form field widgets to reflect `formErrors`. We also add a `novalidate` attribute to the form element to prevent native browser validation.

Expand Down
4 changes: 2 additions & 2 deletions site/source/tutorials/1020_registries/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ The first step is to create a `registry` that will be made available to the appl
{% include_codefile 'demo/finished/biz-e-corp/src/main.ts' line:32 %}

{% aside 'Registries Everywhere!' %}
A `registry` can also be used to define an injector that can be used to provide context for responsibilities such as state injection and routing. To learn more, take a look at the [container tutorial](../1010_containers_and_injecting_state/) and [routing tutorial](../comingsoon.html) .
A `registry` can also be used to define an injector that can be used to provide context for responsibilities such as state injection and routing. To learn more, take a look at the [container tutorial](../1010_containers_and_injecting_state/) and [routing tutorial](../1030_routing/) .
{% endaside %}

At the moment we haven't affected the application, however we now have a handle to a `registry` where we can start to define widgets. Once the widgets are defined in the `registry`, they will be available through the application and can be used by switching the concrete class in `w()` with the `registry` label.
Expand Down Expand Up @@ -103,7 +103,7 @@ First we need to extract the `_renderBack` function from `Worker.ts` into a new
{% include_codefile 'demo/finished/biz-e-corp/src/widgets/Worker.ts' lines:51-65 %}

{% aside 'Use Before You Define' %}
The `registry` is designed to mirror the behavior and API of custom elements wherever possible. One neat feature is that a registry item can be used before it is defined, and, once defined, an used before it is defined and, once defined, widgets that use the `registry` will automatically re-render!
The `registry` is designed to mirror the behavior and API of custom elements wherever possible. One neat feature is that a registry item can be used before it is defined, and, once defined, and used before it is defined and, once defined, widgets that use the `registry` will automatically re-render!
{% endaside %}

Now we need to add the `registry` definition for `WorkerBack.ts` to lazily load when the worker is clicked. Instead of adding a concrete widget class, we add a function that, when called, requires and returns the concrete widget. This function will not be called until the first time the application tries to use the widget label as part of the usual `render` cycle. Initially, before the widget has loaded, nothing will be rendered. Once it has loaded, any widgets that use the lazy widget will automatically re-render.
Expand Down
Loading

0 comments on commit a987f3e

Please sign in to comment.