Age | Commit message (Collapse) | Author |
|
|
|
|
|
This provides the infrastructure to create views and HTTP handlers to
provide recipe steps.
|
|
This error used to be silent. Since it is just about test recipes and
thus a debugging environment it is best to directly give up and log the
error.
|
|
It should be inside the body tag but used to be before it.
|
|
Design changes should be avoided for now since simple.css cares about
the CSS part of Ceres.
|
|
The model package should never modify the data. Thus the functionality
to update timestamps is moved to the controller package which is
intended to modify data.
|
|
There is the need to add buttons to the recipe server which act like a
anchor tag (link). This can be achieved by nesting anchor and button
tag.
The problem is that if the user cycles through the elements of the page
with the 'tab' key such a button is handled as two overlapping elements
instead of one.
This commit solves the issue by using buttons with the attribute
`onclick="window.location.href='<url>';`.
|
|
|
|
|
|
They are intended to use multiple lines. This is easier to edit in a
textarea element rather than in an input element.
|
|
|
|
An empty string for one of these attributes will lead to a recipe view
page which does not render the paragraph for this item.
|
|
The model package should handle the object relational mapping (ORM).
This requires implementing the four CRUD methods:
- create
- read
- update
- delete
On create and update the model package used to modify the timestamps
like `last_changed`. This was detected by the unit tests which tested
that the data is not changed in a create / read cycle or is updated
correctly in an update / read cycle.
This raised the question if it is a good idea that the model package is
"smart" and updates timestamps. To keep the model package and the
included unit tests simple the new design enforces that the complete
data - including metadata - is always exactly the same after using any
CRUD methods.
The functionality of updating the timestamp is moved to the HTTP handler
inside the controller package. This also matches the definition of the
controller package as the part of the code which is alone responsible to
actually change the data.
This commit finally fixes the unit test suite.
|
|
This allows to print a recipe with a fmt.Printf() call more easily:
fmt.Printf("%s\n", recipe)
This is also used for better error output in unit tests with t.Fatalf().
The Stringer interface is implemented with the JSON package because an
indented version of a recipe is a useful string representation.
|
|
This allows to formulate the test data with an object-based model which
is easier than writing it down in a relational model.
|
|
In the long term the <nav> section at the top should reference the list
views of all managed objects (recipes, users, products and so on).
With this structure it makes more sense to have the button to add a
recipe on the list view on recipes located at /recipes.
|
|
|
|
This allows to cache the involved JavaScript code.
|
|
The <nav> section is the same on every page. This new template reduces
code duplication.
|
|
|
|
This makes the update URL more consistent with the other ones. A check
ensures consistency of the URL and JSON ID values.
|
|
|
|
This reflects that these HTTP handler functions implement one of the
four CRUD methods create, read update and delete.
|
|
The old edit URL parameter allowed to select one different HTML
template. A more generic approach is to provide a view parameter which
allows to use multiple alternative HTML templates for the same data
defined by the Go struct.
This makes implementing additional pages like a confirm page for recipe
deletion easier.
|
|
|
|
|
|
While forms can be send without JavaScript this new approach has the
benefit that the whole data is send as one JSON.
This JSON format can also be used for an API or testing.
|
|
|
|
A missing or wrong .Id field for example otherwise results in a silent
error because nothing is actually updated.
|
|
When a HTML form is converted to JSON by JavaScript using `FormData()`,
`Object.fromEntries()` and `JSON.stringify` the data type is always
`string`. This does not match the Go struct definitions using multiple
types including e.g. `int`.
There are several options to solve this conflict:
1. use only strings in Go struct definitions
2. write custom functions to parse string-based JSONs to Go structs
3. implement custom functions in JS to use `number` type if possible
Option 3 seems to be a very clean solution. Nevertheless it is limited
by the fact that JSON anyway has a way more limited type system than Go.
So the types used in Go cannot be used and this would reduce this option
to a variant of option 2.
Option 2 requires significant effort per struct inside the model
package. Every object which is transferred via JSON and serialized into
Go structs would require a second struct definition with string types
and a conversion function. This does not scale.
Thus option 1 seems to be the best fit. The reasons for using types like
`int` or `bool` are:
- less memory consumption than `string` in most cases
- implicit data validation (e.g. enforcing positive numbers with `uint`)
- better compatibility with certain APIs which rely on e.g. `int`
The first argument is not so relevant in this use case. The amount of
required memory is still quite small for servers. Implicit data
validation is a good thing but not enough. There should anyway be
validation method which has to be called on CRUD methods and JSON
deserialization.
|
|
|
|
Otherwise e.g. the Firefox browser throws an error on the console.
|
|
|
|
The index page / provides a redirect to /recipes but this is inefficient
since two HTTP requests are required.
|
|
|
|
|
|
|
|
|
|
This type is provided to render overview pages easily with a list of all
recipes.
|
|
The new Go type 'Recipe' should contain every information directly
related to a recipe. It should be sufficient to pass it to a template to
directly render a HTML view or edit page for the recipe or to a template
to generate a PDF.
The CRUD methods are:
- func (r *Recipe) Create() error
- func (r *Recipe) Update() error
- func (r *Recipe) Read() error
- func (r *Recipe) Delete() error
Together with the type itself they are the interface the model package
provides for recipes.
|
|
This simple model is used to test if it is helpful to implement the four
CRUD methods create, read, update and delete all inside the model
package.
The model package should also provide the datastructures for these
operations (well suited for the required views) aswell as tests for
them.
With this approach it should be possible to easily implement the view
and controller package because most of the logic is already inside the
model package and is tested.
|
|
This is a simple first HTTP handler and is required to display the
website with the intended design.
|
|
This CSS framework uses nearly only the standard HTML tags and is thus
easy to adopt / replace.
|
|
This adds the infrastructure to add HTTP handlers. It already sets up
the HTTP server and makes sure it is started and stopped.
|
|
This dependency provides a more extended HTTP routing than the Go
standard library.
|
|
This is the intended behaviour for production and also for debugging to
at least inspect the data directory of Ceres.
|
|
This is useful for debugging and testing.
|
|
This provides the basic table structure to the database.
|
|
The already implemented storage folder should contain a sqlite database
to store most parts of the Ceres user data.
|