fix typos in chapters 15 to 17

This commit is contained in:
lubiana 2022-05-31 18:05:46 +02:00 committed by Andre Lubian
parent ebbcc6e7f6
commit f5c444d4c7
3 changed files with 31 additions and 31 deletions

View file

@ -2,7 +2,7 @@
### Adding Content ### Adding Content
By now we did not really display anything but some examples to in our application and it is now time to make our app By now we did not really display anything but some examples to in our application, and it is now time to make our app
display some content. For example we could our app be able to display the Markdown files used in this tutorial as display some content. For example we could our app be able to display the Markdown files used in this tutorial as
nicely rendered HTML Pages that can be viewed in the browser instead of the editor you are using. nicely rendered HTML Pages that can be viewed in the browser instead of the editor you are using.
@ -15,7 +15,7 @@ can use whatever you like.
After installing Parsedown lets write a Markdownparser interface and an implementation using parsedown. After installing Parsedown lets write a Markdownparser interface and an implementation using parsedown.
We only need one function that receives a string of Markdown and returns the HTML represantion (as a string as well). We only need one function that receives a string of Markdown and returns the HTML representation (as a string as well).
@ -30,8 +30,8 @@ interface MarkdownParser
} }
``` ```
By the namespace you will already have guessed that I called placed in interface in a file calles MarkdownParser.php in By the namespace you will already have guessed that I placed in interface in a file calles MarkdownParser.php in
the src/Template folder. Lets put our Parsedown implementation right next to it in a file called ParsedownParser.php the src/Template folder. Let's put our Parsedown implementation right next to it in a file called ParsedownParser.php
```php ```php
<?php declare(strict_types=1); <?php declare(strict_types=1);
@ -55,7 +55,7 @@ final class ParsedownRenderer implements MarkdownParser
We could now use the ParsedownRender class directly in our actions by typehinting the classname as an argument to the We could now use the ParsedownRender class directly in our actions by typehinting the classname as an argument to the
constructor or a method, but as we always want to rely on an interface instead of an implementation we need to define constructor or a method, but as we always want to rely on an interface instead of an implementation we need to define
the the ParsedownRenderer as the correct implementation for the MarkdownRenderer interface in the dependencies file: the ParsedownRenderer as the correct implementation for the MarkdownRenderer interface in the dependencies file:
```php ```php
... ...
@ -129,10 +129,10 @@ those are simply displayed using an unordered list.
The second templates displays a single rendered markdown page. As data it expects the title and the content as array. The second templates displays a single rendered markdown page. As data it expects the title and the content as array.
I used an extra bracket for the content ```{{{content}}}``` so that the Mustache-Renderer does not escape the provided I used an extra bracket for the content ```{{{content}}}``` so that the Mustache-Renderer does not escape the provided
html and thereby destroys the the parsed markdown. html and thereby destroys the parsed markdown.
You might have spotted that I added [Pico.css](https://picocss.com/) which is just a very small css framework to make the You might have spotted that I added [Pico.css](https://picocss.com/) which is just a very small css framework to make the
pages a little bit nicer to look at. It mostly provides some typography styles that work great with rendered Markdown, pages a little nicer to look at. It mostly provides some typography styles that work great with rendered Markdown,
but you can leave that out or use any other css framework you like. There is also some Javascript that adds syntax but you can leave that out or use any other css framework you like. There is also some Javascript that adds syntax
highlighting to the code. highlighting to the code.
@ -145,7 +145,7 @@ function show(string $name): \Psr\Http\Message\ResponseInterface;
function list(): \Psr\Http\Message\ResponseInterface; function list(): \Psr\Http\Message\ResponseInterface;
``` ```
Lets define two routes. `/page` should display the overview of all pages, and if the add the name of chapter to the Let's define two routes. `/page` should display the overview of all pages, and if the add the name of chapter to the
route, `/page/adding-content` for example, the show action should be called with the name as a variable: route, `/page/adding-content` for example, the show action should be called with the name as a variable:
`config/routes.php` `config/routes.php`
@ -154,7 +154,7 @@ $r->addRoute('GET', '/page', [Page::class, 'list']);
$r->addRoute('GET', '/page/{page}', [Page::class, 'show']); $r->addRoute('GET', '/page/{page}', [Page::class, 'show']);
``` ```
Here is my Implementation. If have added a little regex replacement in the show method that replaces the links to the Here is my Implementation. I have added a little regex replacement in the show method that replaces the links to the
next and previous chapter so that it works with our routing configuration. next and previous chapter so that it works with our routing configuration.
`src/Action/Page.php` `src/Action/Page.php`
@ -244,9 +244,9 @@ class Page
You can now navigate your Browser to [localhost:1235/page][http://localhost:1235/page] and try out if everything works. You can now navigate your Browser to [localhost:1235/page][http://localhost:1235/page] and try out if everything works.
Of course this code is far from looking good. We heavily rely on the pages being files in the filesystem, and the action Of course this code is far from looking good. We heavily rely on the pages being files in the filesystem, and the action
should never be aware of the filesystem in the first place, also we have a lot of string replacements and other repetetive should never be aware of the filesystem in the first place, also we have a lot of string replacements and other repetitive
code in the file. And phpstan is gonna scream at us a lot, but if we rewrite the code to satisfy all the checks we would code in the file. And phpstan is going to scream at us a lot, but if we rewrite the code to satisfy all the checks we would
add even more lines to that simple class, so lets move on to the next chapter where we move all the logic to seperate add even more lines to that simple class, so lets move on to the next chapter where we move all the logic to separate
classes following our holy SOLID principles :) classes following our holy SOLID principles :)

View file

@ -2,32 +2,32 @@
## Data Repository ## Data Repository
At the end of the last chapter I mentioned being unhappy with our Pages action, because there is to much stuff happening At the end of the last chapter I mentioned being unhappy with our Pages action, because there is too much stuff happening
there. We are firstly receiving some Arguments, then we are using those to query the filesytem for the given page, there. We are firstly receiving some Arguments, then we are using those to query the filesystem for the given page,
loading the specific file from the filesystem, rendering the markdown, passing the markdown to the template renderer, loading the specific file from the filesystem, rendering the markdown, passing the markdown to the template renderer,
adding the resulting html to the response and then returning the response. adding the resulting html to the response and then returning the response.
In order to make our pageaction independent from the filesystem and move the code that is responsible for reading the In order to make our page-action independent of the filesystem and move the code that is responsible for reading the
files files
to a better place I want to introduce to a better place I want to introduce
the [Repository Pattern](https://designpatternsphp.readthedocs.io/en/latest/More/Repository/README.html). the [Repository Pattern](https://designpatternsphp.readthedocs.io/en/latest/More/Repository/README.html).
I want to start by creating a class that represents the Data that is included in a page so that. For now I can spot I want to start by creating a class that represents the Data that is included in a page so that. For now, I can spot
three three
distrinct attributes. distinct attributes.
* the ID (or chapternumber) * the ID (or chapter-number)
* the title (or name) * the title (or name)
* the content * the content
Currently all those properties are always available, but we might later be able to create new pages and store them, but Currently, all those properties are always available, but we might later be able to create new pages and store them, but
at that point in time we are not yet aware of the new available ID, so we should leave that property nullable. This at that point in time we are not yet aware of the new available ID, so we should leave that property nullable. This
allows allows
us to create an object without an id and let the code that actually saves the object to a persistant store define a us to create an object without an id and let the code that actually saves the object to a persistent store define a
valid valid
id on saving. id on saving.
Lets create an new Namespace called `Model` and put a `MarkdownPage.php` class in there: Let's create an new Namespace called `Model` and put a `MarkdownPage.php` class in there:
```php ```php
<?php declare(strict_types=1); <?php declare(strict_types=1);
@ -48,12 +48,12 @@ class MarkdownPage
These small Model classes are one of my most favorite features in newer PHP-Versions, because they are almost as easy These small Model classes are one of my most favorite features in newer PHP-Versions, because they are almost as easy
to create as an on-the-fly array but give us the great benefit of type safety as well as full code completion in our to create as an on-the-fly array but give us the great benefit of type safety as well as full code completion in our
IDEs. IDEs.
There is a [great blogpost](https://stitcher.io/blog/evolution-of-a-php-object) that highlights how these kind of There is a [great blogpost](https://stitcher.io/blog/evolution-of-a-php-object) that highlights how this kind of
objects objects
have evolved in PHP from version 5.6 to 8.1, as I personally first started writing proper php with 5.4 it really baffles have evolved in PHP from version 5.6 to 8.1, as I personally first started writing proper php with 5.4 it really baffles
me how far the language has evolved in these last years. me how far the language has evolved in these last years.
Next we can define our interface for the repository, for our current usecase I see only two needed methods: Next we can define our interface for the repository, for our current use case I see only two needed methods:
* get all pages * get all pages
* get one page by name * get one page by name
@ -183,7 +183,7 @@ return new Settings(
); );
``` ```
Of course we need to define the correct implementation for the container to choose when we are requesting the Repository Of course, we need to define the correct implementation for the container to choose when we are requesting the Repository
interface: interface:
`conf/dependencies.php` `conf/dependencies.php`

View file

@ -2,14 +2,14 @@
## Autoloading performance ## Autoloading performance
Although our application is still very small and you should not really experience any performance issues right now, Although our application is still very small, and you should not really experience any performance issues right now,
there are still some things we can already consider and take a look at. If I check the network tab in my browser it takes there are still some things we can already consider and take a look at. If I check the network tab in my browser it takes
about 90-400ms to show a simple rendered markdownpage, with is sort of ok but in my opinion way to long as we are not about 90-400ms to show a simple rendered markdown, with is sort of ok but in my opinion way to long as we are not
really doing anything and do not connect to any external services. Mostly we are just reading around 16 markdown files, really doing anything and do not connect to any external services. Mostly we are just reading around 16 markdown files,
a template, some config files here and there and parse some markdown. So that should not really take that long. a template, some config files here and there and parse some markdown. So that should not really take that long.
The problem is, that we heavily rely on autoloading for all our class files, in the `src` folder. And there are also The problem is, that we heavily rely on autoload for all our class files, in the `src` folder. And there are also
quite a lot of other files in composers `vendor` directory. To understand while this is becomming we should make quite a lot of other files in composers `vendor` directory. To understand while this is becoming we should make
ourselves familiar with how [autoloading in php](https://www.php.net/manual/en/language.oop5.autoload.php) works. ourselves familiar with how [autoloading in php](https://www.php.net/manual/en/language.oop5.autoload.php) works.
The basic idea is, that every class that php encounters has to be loaded from somewhere in the filesystem, we could The basic idea is, that every class that php encounters has to be loaded from somewhere in the filesystem, we could
@ -19,8 +19,8 @@ The problem we are now facing is that the composer autoloader has some rules to
a class definition might be placed, then the autoloader tries to locate a file by the namespace and classname and if it a class definition might be placed, then the autoloader tries to locate a file by the namespace and classname and if it
exists includes that file. exists includes that file.
If we only have a handfull of classes that does not take a lot of time, but as we are growing with our application this If we only have a handful of classes that does not take a lot of time, but as we are growing with our application this
easily takes longer than necesery, but fortunately composer has some options to speed up the class loading. easily takes longer than necessary, but fortunately composer has some options to speed up the class loading.
Take a few minutes to read the documentation about [composer autoloader optimization](https://getcomposer.org/doc/articles/autoloader-optimization.md) Take a few minutes to read the documentation about [composer autoloader optimization](https://getcomposer.org/doc/articles/autoloader-optimization.md)
@ -35,7 +35,7 @@ in your browsers devtools.
In my case the response time falls down to under an average of 30ms with some spikes in between, but all in all it looks really good. In my case the response time falls down to under an average of 30ms with some spikes in between, but all in all it looks really good.
You can also try out the different optimization levels and see if you can spot any differences. You can also try out the different optimization levels and see if you can spot any differences.
Although the composer manual states not to use the optimtization in a dev environment I personally have not encountered Although the composer manual states not to use the optimization in a dev environment I personally have not encountered
any errors with the first level of optimizations, so we can use that level here. If you add the line from the documentation any errors with the first level of optimizations, so we can use that level here. If you add the line from the documentation
to your `composer.json` so that the autoloader gets optimized everytime we install new packages. to your `composer.json` so that the autoloader gets optimized everytime we install new packages.