From 3db9f4c1c5a5b65ae97671383dd34b4b8af5923e Mon Sep 17 00:00:00 2001 From: Philippe Lonchampt Date: Fri, 22 Sep 2017 10:46:51 +0200 Subject: [PATCH] Fix markdown --- README.md | 6 +++--- docs/authentication.md | 8 ++++---- docs/auto_updater.md | 18 +++++++++-------- docs/commands.md | 12 ++++++------ docs/concepts.md | 14 +++++++------- docs/config.md | 2 +- docs/entities_list.md | 18 ++++++++--------- docs/entity_form.md | 44 +++++++++++++++++++++--------------------- docs/repository.md | 5 +++-- 9 files changed, 65 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index 32aeb30..bbb3e9e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -#Sharp +# Sharp *A Laravel CMS for developers who hate CMS* @@ -12,7 +12,7 @@ Well, I think I can try to be clearer: in many of my web projects there's a lot --- -##Installation +## Installation - Through composer, add `"dvlpp/sharp": "~1.0"` in your require section, and run `composer update`. - Next add `'Dvlpp\Sharp\SharpServiceProvider'` in your app.php providers section. @@ -24,7 +24,7 @@ OK, you're good to go. One final note: after an composer update, always re-run t --- -##Full documentation +## Full documentation [Here's the doc index](docs/index.md). diff --git a/docs/authentication.md b/docs/authentication.md index acf6efa..80afe98 100644 --- a/docs/authentication.md +++ b/docs/authentication.md @@ -1,4 +1,4 @@ -#Authentication and rights management +# Authentication and rights management Sharp shall not be responsible of the auth or access rights management of a particular application: implementation is your choice. @@ -7,7 +7,7 @@ Sharp shall not be responsible of the auth or access rights management of a part 3. [Rights management](#rights) -## 1. Config +## 1. Config To enable authentication, we simply indicate a Auth service class in the application config (`site.php`): @@ -21,7 +21,7 @@ return [ ``` -## 2. Auth service +## 2. Auth service Then, we have to write this `Quincy\Sharp\SharpAuthentication` class, making it implements `Dvlpp\Sharp\Auth\SharpAuth`: @@ -75,7 +75,7 @@ Once the class is written, we can test it by hitting any Sharp page, and we get Notice also that a logout link appears in Sharp's header. -## 3. Rights management +## 3. Rights management Question is now: how to authorize specific users for specific actions? Suppose we want to set our rights this way: diff --git a/docs/auto_updater.md b/docs/auto_updater.md index 5f5a99c..e6660e4 100644 --- a/docs/auto_updater.md +++ b/docs/auto_updater.md @@ -1,4 +1,4 @@ -#Sharp Eloquent auto-updater +# Sharp Eloquent auto-updater If you read the [Entity forms](docs/entity_form.md) chapter, you probably noticed that the update or create code to write in the entity repository can be tricky, or at least a bit long, especially when posting big entities with lists and tags and stuff. @@ -12,7 +12,7 @@ The good news is that if you are using Eloquent for your models, you can probabl -## 1. The auto-updater Trait magic +## 1. The auto-updater Trait magic Here's how the giraffe repository is managing `update()` and `create()` methods: @@ -46,7 +46,7 @@ First two arguments are useful to review the configuration and find out the type And... that's mostly it: this function does all the boring job. But it will sometimes need some help, as explained below. -## 2. The file upload case +## 2. The file upload case File uploads needs a little extra work: if you use the SharpEloquentRepositoryUpdaterTrait on a repository that manage an entity which contains file uploads, you need to implement a special interface: `SharpEloquentRepositoryUpdaterWithUploads`. This interface will require 3 methods: @@ -81,7 +81,7 @@ Finally, the last method, `deleteFileUpload()`, is called when a file is deleted Of course, it's easy to manage this in a project Trait, and code it only once, based on your file upload storage implementation choices. -## 3. List special config +## 3. List special config Lists offers two optional config parameters: @@ -105,7 +105,7 @@ So, as an example: ``` -## 4. Pivot tags special config +## 4. Pivot tags special config Very similarly to lists, pivot tags have also optional config parameters dedicated to the auto-updater: @@ -113,7 +113,7 @@ Very similarly to lists, pivot tags have also optional config parameters dedicat - `create_attribute` is more specific: for pivot tags fields which authorize on-the-fly creation (with `addable` parameter), this must be filled with the model attribute name which will be updated with the string tag. -## 5. Wait, this particular attribute is specific +## 5. Wait, this particular attribute is specific Of course, you will sometimes need extra code for some attributes, or you will maybe want to override the default behavior. Well, you want hooks, and there's one per attribute. @@ -123,7 +123,8 @@ The rule is simple: if you have in your repo a method called `update[AttributeNa function updateNameAttribute($instance, $value) { // Do anything with the value - return false; } + return false; +} ``` If the method returns false, the auto updater will skip to the next posted value. If true, the auto update process will continue just as planned. @@ -140,7 +141,8 @@ function createPhotosListItem($instance) return new Photo([ "animal_id" => $instance->id, "animal_type" => 'Quincy\Sharp\Giraffe\Giraffe' - ]); } + ]); +} ``` In fact, if we let Sharp doing this alone, in this case, only `animal_id` would be valued, because there's no way it could guess the `animal_type` specific thing (for [polymorphic relation](http://laravel.com/docs/eloquent#polymorphic-relations)). diff --git a/docs/commands.md b/docs/commands.md index 89b08a1..fd77a73 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -1,4 +1,4 @@ -#Commands +# Commands Let's say that our zoo administrator wants to execute some specific actions like export a CSV file of a giraffe list, or quickly update an attribute right from the list view, or even have a online page preview before publishing content. Well, that why there's commands in Sharp. @@ -8,7 +8,7 @@ Let's say that our zoo administrator wants to execute some specific actions like 3. [Download command](#download) 4. [Auth](#auth) -## 1. Command config +## 1. Command config It always start with some config: @@ -60,7 +60,7 @@ Next, there's 3 possible types: "download", "reload" and "view". They are explai A new caret appeared at the end of each row, with a submenu containing all commands. The same is true on the list itself, thanks to the "Export" list command, for which the caret is in the blue list bar, on the right. -## 2. Reload command +## 2. Reload command Our first entity command is called "birthday", and refers to a `Quincy\Sharp\Giraffe\BirthdayCommand` command handler. Well, let's create this class and let it implement `Dvlpp\Sharp\Commands\SharpEntityCommand`. @@ -92,7 +92,7 @@ class BirthdayCommand implements SharpEntityCommand { The `execute()` method is required, and accept the `$instanceId` (a giraffe id for us) as a parameter. All we have to do is the increment the age, and return nothing, in the command "reload" case. -## 3. View command +## 3. View command The "preview" entity command we described above is a little bit different: in a "view" type, meaning that Sharp must load a view (specified in the config) with the command data in a new window. Here's the command handler `execute()` method possible code: @@ -107,7 +107,7 @@ function execute($instanceId) Sharp will load the `sharp_previews/giraffe` view with a `$giraffe` parameter, and open it in a new browser window / tab. -## 4. Download command +## 4. Download command To demonstrate the download command, let's take a list command this time, named "export". The goal is to create a CSV file of the displayed giraffe list and send it to the user. @@ -163,7 +163,7 @@ As you can see, the execute method accept a SharpEntitiesListParams parameter, v As expected, when the command is called, the generated csv file is downloaded. -## 4. Auth +## 4. Auth Commands require by default an "update" auth on the entity. To change that, simply add a `auth` attribute on the command config: diff --git a/docs/concepts.md b/docs/concepts.md index c4c39b6..449193b 100644 --- a/docs/concepts.md +++ b/docs/concepts.md @@ -1,24 +1,24 @@ -#Sharp's concepts +# Sharp's concepts Don't worry, there's not much. ## Entities An *entity* is a business object that Sharp has to manipulate. Let's say, for example, a Client, or a Giraffe (in a zoo case). -##Categories +## Categories A *category* is just a place to store entities. So giraffes could be stored in a *Ruminant* category, or maybe in some *Africa* zoo department. -##Sublist +## Sublist A *sublist* is used to group entities. This isn't required, be could be useful in some transversal cases. Take a theatre, for example: we have to manage some *event* or *show* entities, but we would likely group them in *seasons*. Well, in this case, season is a sublist, which can apply to several entities (events, but also tickets prices, and maybe blog posts, ...). -##Repository +## Repository This one is probably more obvious. Sharp needs *repositories* to work with, which are the abstraction layer between Sharp and the data. Those repos must implements specific interfaces. -##Validator +## Validator *Validators* are simple descriptive classes used while... validating data. -##Field +## Field A *field* is obviously a web composant used to let a user enter data. There are many field types in Sharp, but we'll get to this later. -##Command +## Command A *command* is a project specific action executed on an entity or on an entities list. \ No newline at end of file diff --git a/docs/config.md b/docs/config.md index e43f70f..092a2b0 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1,4 +1,4 @@ -#Sharp's config file(s) +# Sharp's config file(s) Sharp development is divided in two parts: the coding (by extending / implementing Sharp's classes or interfaces), and the data description, done in config files. Sharp has two of them: diff --git a/docs/entities_list.md b/docs/entities_list.md index 02c0ff7..4bb7ce4 100644 --- a/docs/entities_list.md +++ b/docs/entities_list.md @@ -1,4 +1,4 @@ -#Entities list +# Entities list 1. [The entities list config](#config) 1. [Sorting](#sorting) @@ -9,7 +9,7 @@ 2. [Reordering](#reordering) 2. [Sublists](#sublists) -## 1. The entities list config +## 1. The entities list config All that we need here is store under the `list_template` attribute in the config: @@ -55,7 +55,7 @@ All that stuff will be covered in this chapter. Let's just be global here: OK, let's see: -## 2. Sorting +## 2. Sorting OK, let's work on the giraffe list; but first, we need some data to work with. After a [faker](https://github.com/fzaninotto/Faker)-based seed, we not have 50 animals: @@ -80,7 +80,7 @@ function listAll(SharpEntitiesListParams $params) Line by line, I first chose to eager load zookeeper (because I want to add its name on a column of the list, later). Then I make use of the SharpEntitiesListParams parameter, which contains (among other things) the sorted column and sorted direction. And I can now use he column sorting! -## 3. Columns renderers +## 3. Columns renderers I'm not happy with the height column: data is expressed in cm, and I could like to have it in ft / inch. We can use a column renderer for that, which allows to format the displayed data. @@ -149,7 +149,7 @@ They can be used like this: ``` -## 4. Activation / Deactivation +## 4. Activation / Deactivation Notice the blue or outlined star at the end of each row? This is the active state indicator (we talk about it in the [Config](config.md) page). The idea is to provide a basic way to declare an instance online or offline. We defined it this way in the config: @@ -178,7 +178,7 @@ function deactivate($id) We can now clic on the activate / deactivate star buttons. -## 5. Pagination +## 5. Pagination In many cases we'll need pagination in entities lists. It's very easy to tackle with Sharp. First, as usual, the config: @@ -222,7 +222,7 @@ The fact is giraffe are now paginated: ![](img/listview-giraffe-pagination.png) -## 6. Search +## 6. Search The idea is to add a quick search functionality. So, in the config, we activate the search: @@ -271,7 +271,7 @@ One again, the philosophy is that we can implement this search in many ways, dep Notice we iterate over a `$params->getSearchTerms()` collection first, to search for all words. Notice also that we don't add the necessary '%' characters around `$term`: it's a default. To override this, simply provide prefix and suffix to the method: `$params->getSearchTerms($prefix, $suffix)`. -## 7. Reordering +## 7. Reordering OK, I think we are going to need another entity to work with. We have Giraffe and Zookeeper (this one will be used in the next paragraph). To keep it simple, let's say our zoo areas are divided in *zones*, like savanna, mountains, and so on. We just have to create an entity config for those zones, a model, and a repo. Then insert some data, and: @@ -314,7 +314,7 @@ And now, we can clic on the reorder button, drag and drop zones and validate to Notice that I choose for this tutorial to manage order with an integer attribute, which is a brutal way to do it. But Sharp doesn't need you to do it this way: depending on the project or the entity, you can use integer, or some previous / next pointer, or anything else. -## 8. Sublists +## 8. Sublists Like I said before, sublists are a transversal way to group entities. I gave a good season and theatre example in the [concepts](concepts.md) page, but in our case let's say we want to group giraffes (and other animals) by zookeepers. diff --git a/docs/entity_form.md b/docs/entity_form.md index 9776ef8..5a6b614 100644 --- a/docs/entity_form.md +++ b/docs/entity_form.md @@ -1,4 +1,4 @@ -#Entity form +# Entity form 1. [Fields](#fields) 2. [Shared config](#f-shared) @@ -24,11 +24,11 @@ OK, here we are: we created some [entities config file(s)](config.md), and wrote [the base classes](entities_list.md) to handle lists display, reordering, searching and stuff. Now, let's tackle the big part, the actual data entry. This is in fact the final purpose of Sharp: provide a simple way to enter complex data without having to develop big javascript objects each time. -## 1. Fields +## 1. Fields There's a bunch of them. -### 1.1 Shared config +### 1.1 Shared config Here is the basic config shared by all fields: @@ -53,7 +53,7 @@ Here is the basic config shared by all fields: And finally, about the **key**: this must be an instance attribute of the object, because Sharp will get values for form population ou repopulation from there. Using Eloquent, this must correspond to a database field. -### 1.2 Text field +### 1.2 Text field Just a simple regular text field. Base config: @@ -65,7 +65,7 @@ Just a simple regular text field. Base config: ``` -### 1.3 Textarea +### 1.3 Textarea Just a textarea field. @@ -80,7 +80,7 @@ Just a textarea field. - **height**: textarea height expressed in pixels  -### 1.4 Markdown textarea +### 1.4 Markdown textarea This will generate a markdown-specific textarea field, based on the [lepture/Editor](https://github.com/lepture/editor) javascript editor. @@ -106,7 +106,7 @@ This will generate a markdown-specific textarea field, based on the [lepture/Edi - F: toggle fullscreen -### 1.5 Date +### 1.5 Date Useful to enter date and time: @@ -141,7 +141,7 @@ The date component is based on the [datetimepicker Jquery plugin](http://xdsoft. ![](img/formfield-date.png) -### 1.6 Check +### 1.6 Check A simple checkbox. @@ -161,7 +161,7 @@ Note: Usually, you wouldn't put a label attribute for a checkbox. Sharp always send the value of a checkbox attribute, even if unchecked. -### 1.7 Choose +### 1.7 Choose A select element (also called dropdown). @@ -182,7 +182,7 @@ A select element (also called dropdown). This component is rendered by the [selectize.js](http://brianreavis.github.io/selectize.js/) plugin. -### 1.8 Hidden +### 1.8 Hidden Well, you know. Yes, an hidden field. @@ -195,7 +195,7 @@ Well, you know. Yes, an hidden field. Note that there isn't any *value* attribute: like for all other fields, the field is populated with instance->age (in this example). -### 1.9 Label +### 1.9 Label Label is for displaying read-only data. @@ -211,7 +211,7 @@ Label is for displaying read-only data. Nothing will be posted here, and the key for the field could be anything unique. -### 1.10 Password +### 1.10 Password A password field. @@ -222,7 +222,7 @@ A password field. ``` -### 1.11 Reference field +### 1.11 Reference field This one is used to reference a related instance, in a one-to-* relationship. @@ -254,7 +254,7 @@ This component is rendered by the [selectize.js](http://brianreavis.github.io/se ![](img/formfield-ref.png) -### 1.12 File upload +### 1.12 File upload OK, file upload are basically the main reason I developed Sharp, at the beginning. You know, asynchronous upload, files types, tmp directory, storage, repopulation in case of validation problem, ... @@ -304,7 +304,7 @@ The rest is magic, provided on the client side by the well-known [blueimp/jQuery ![](img/formfield-file-2.png) -### 1.13 List +### 1.13 List I wrote that file upload was the reason why I developed Sharp: in fact, it's file upload *and lists*. In many projects, I have to handle lists with dynamic items, for all kind of purpose: @@ -368,7 +368,7 @@ In case of an item creation, X would be a generated unique string, starting with ![](img/formfield-list.png) -### 1.14 List item reference field +### 1.14 List item reference field This one is for a quite rare case: to reference an specific item in a list of another entity instance. Suppose we develop a new Comment entity, and we want to attach it to a specific photo of our giraffe photos list described earlier: this is a list item reference (reference is toward a specific photo of a giraffe). @@ -409,7 +409,7 @@ function formListForSublist($sublistId, $askingInstance) This method is responsible for creating a multidimensional array of giraffe x photos with a text value to display in a dropdown list. The user can now pick a giraffe, and then pick a specific photo. -### 1.15 Pivot tags field +### 1.15 Pivot tags field It's pretty common to manage tags. There's different ways to do it, and Sharp proposal is to handle it with a tags table and a pivot table. @@ -443,7 +443,7 @@ function formList($askingInstance) The tag field is now complete. The rendering is done with the [selectize.js plugin](http://brianreavis.github.io/selectize.js/). -## 2. The form layout +## 2. The form layout Maybe you noticed that the config file contains a second form-related attribute. That's `form_layout`: @@ -489,7 +489,7 @@ With the config above, here's the result: ![](img/formview-giraffe-singlerelation.png) -## 3. Conditional display (hide and show fields) +## 3. Conditional display (hide and show fields) Sharp offers a simple way to hide or show fields depending on a Check or a Choose value. This is all done in the config file: @@ -549,7 +549,7 @@ You can even indicate multiple matches, separated by a comma (Choose only): ``` -## 4. Update and create +## 4. Update and create This is the part where you have to do something in your repository with the posted data. Like, you know, save it in a database. And here, you have two big choices: @@ -663,7 +663,7 @@ Very simple. But the "addable" option in the tag config file authorize to create The update code can differentiate new tags from existing one by checking numeric vs string values. Now why is there a # at the beginning of the name? To indicate that it's a new tag (we can't just rely on a "is_numeric" test, because a tag name could be numeric)... The # must be removed on the update stage. -## 5. Form validation +## 5. Form validation Naturally, Sharp can help when it comes to form validation. We can reference a *Validator* in the config: @@ -725,7 +725,7 @@ public function getMessages() A final note: you can choose to override the class attributes instead of methods, if you prefer. Simply take a look to the `Dvlpp\Sharp\Validation\Validator` class. -## 6. Single relation case +## 6. Single relation case A final chapter on this long page, to talk about a quite specific case. Suppose that zoo animal could have an "ID card", with some info on it: a number and an origin. We decide to add a animal_card table, and a one-to-one relationship with the giraffe table (which contains now a animal_card_id). diff --git a/docs/repository.md b/docs/repository.md index f5c77d4..0202caf 100644 --- a/docs/repository.md +++ b/docs/repository.md @@ -1,4 +1,4 @@ -#Repository and data management +# Repository and data management So, here we are: we just finished to [write our giraffe config file](config.md), and we want to see all giraffes in a pretty list. Well, there's some classes to create, and the first one, the main one is the *repository*. Let's get started. @@ -84,7 +84,8 @@ class Repository implements SharpCmsRepository { } } ``` - A quite simple repository, with methods to: + +A quite simple repository, with methods to: - grab lists (`listAll()`, `paginate()`), - get instances (`find()` and `newInstance()`),