Skip to content

Commit

Permalink
Merge pull request #39 from ryangjchandler/feature/markdown-json
Browse files Browse the repository at this point in the history
feature: MarkdownJson driver
  • Loading branch information
ryangjchandler authored Mar 25, 2021
2 parents 9ce4273 + 37424dc commit 63a53e1
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 3 deletions.
37 changes: 35 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,31 @@ Out of the box, Orbit provides the following drivers:
* `md` -> `Orbit\Drivers\Markdown`
* `json` => `Orbit\Drivers\Json`
* `yaml` => `Orbit\Drivers\Yaml`
* `md_json` => `Orbit\Drivers\MarkdownJson`

### `md`

This is a Markdown that is capable of parsing Markdown files, as well as YAML front-matter.

When Orbit loads files using this driver, it will map each front-matter key into a column in your models `schema`.

By default, the Markdown driver will also add a `TEXT content` column to your schema. This is used to store the Markdown body from the file.

> 💡 If you wish to customise the name of the `content` column, you can use the `Markdown::contentColumn()` method and provide a new column name. This is applied to all models that use the `Markdown` driver.
### `json`

This is a JSON driver that is capable of parsing `.json` files. Each key in the file is mapped to a column in your schema.

### `yaml`

This is a YAML driver that is capable of parsing `.yml` drivers. Each key in the file is mapped to a column in your schema.

### `md_json`

This driver is very similar to the `Markdown` / `md` driver, but it supports JSON-based front-matter as opposed to the default YAML format.

> 💡 If you wish to customise the name of the `content` column, you can use the `MarkdownJson::contentColumn()` method and provide a new column name. This is applied to all models that use the `MarkdownJson` driver.
### Registering drivers

Expand All @@ -144,7 +169,7 @@ You can register custom Orbit drivers by using the `Orbit::extend` method. You s
})
```

All drivers must implement the `Orbit\Contracts\Driver` contract. This enforces drivers to have at least 4 methods:
All drivers must implement the `Orbit\Contracts\Driver` contract, or extend the `Orbit\Drivers\FileDriver` class. This enforces drivers to have at least 4 methods:

```php
interface Driver
Expand All @@ -159,13 +184,21 @@ interface Driver
}
```

Here is what each of the methods are for:
Here is what each method is used for:

* `shouldRestoreCache` - used to determine if the file cache should be updated.
* `save` - used to persist model changes to a file on disk, or create a new file.
* `delete` - used to delete an existing file on disk
* `all` - used to retrieve all records from disk and cache.

### Extending `FileDriver`

Extending the `Orbit\Drivers\FileDriver` class is useful when you want some of the heavy lifting done for you. To work with this base class, you should do the following:

1. Implement an `extension(): string` method that returns the file extension as a string, i.e. `return 'md'` for `Markdown`.
2. Implement a `dumpContent(Model $model): string` method. This method should return the updated content for the file.
3. Implement a `parseContent(SplFileInfo $file): array` method. This method should return an array of `key => value` pairs, where each `key` is a column in the `schema`.

### Changing drivers

If you wish to use a different driver for one of your models, you can add a `public static $driver` property to your model and set the value to the name of a driver.
Expand Down
1 change: 1 addition & 0 deletions config/orbit.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
'md' => \Orbit\Drivers\Markdown::class,
'json' => \Orbit\Drivers\Json::class,
'yaml' => \Orbit\Drivers\Yaml::class,
'md_json' => \Orbit\Drivers\MarkdownJson::class,
],

'paths' => [
Expand Down
44 changes: 44 additions & 0 deletions src/Drivers/MarkdownJson.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace Orbit\Drivers;

use SplFileInfo;
use Illuminate\Database\Eloquent\Model;
use Spatie\YamlFrontMatter\YamlFrontMatter;

class MarkdownJson extends Markdown
{
protected function dumpContent(Model $model): string
{
$matter = array_filter($model->attributesToArray(), function ($value, $key) {
return $key !== 'content' && $value !== null;
}, ARRAY_FILTER_USE_BOTH);

$json = json_encode($matter, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);

return implode(PHP_EOL, [
'---',
rtrim($json, PHP_EOL),
'---',
$model->getAttribute('content'),
]);
}

protected function parseContent(SplFileInfo $file): array
{
$content = file_get_contents($file->getPathname());

$pattern = '/^[\s\r\n]?---[\s\r\n]?$/sm';

$parts = preg_split($pattern, PHP_EOL . ltrim($content));

$matter = count($parts) < 3 ? [] : json_decode(trim($parts[1]), true);

$body = implode(PHP_EOL.'---'.PHP_EOL, array_slice($parts, 2));

return array_merge(
$matter,
['content' => trim($body)]
);
}
}
10 changes: 10 additions & 0 deletions tests/AdvancedOrbitalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Orbit\Tests\Fixtures\CustomKey;
use Orbit\Tests\Fixtures\JsonModel;
use Orbit\Tests\Fixtures\MarkdownJsonModel;
use Orbit\Tests\Fixtures\YamlModel;

class AdvancedOrbitalTest extends TestCase
Expand Down Expand Up @@ -57,4 +58,13 @@ public function test_it_can_use_yaml_driver()

$this->assertFileExists(__DIR__.'/content/yaml_models/'.$yaml->getKey().'.yml');
}

public function test_it_can_use_markdown_json_driver()
{
$md = MarkdownJsonModel::create([
'name' => 'Ryan',
]);

$this->assertFileExists(__DIR__.'/content/markdown_json_models/'.$md->getKey().'.md');
}
}
2 changes: 1 addition & 1 deletion tests/BasicOrbitalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use Orbit\Tests\Fixtures\Post;
use Orbit\Tests\Fixtures\Emptiness;

class OrbitalTest extends TestCase
class BasicOrbitalTest extends TestCase
{
public function tearDown(): void
{
Expand Down
31 changes: 31 additions & 0 deletions tests/Fixtures/MarkdownJsonModel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Orbit\Tests\Fixtures;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Schema\Blueprint;
use Orbit\Concerns\Orbital;

class MarkdownJsonModel extends Model
{
use Orbital;

protected $guarded = [];

protected static $driver = 'md_json';

public static function schema(Blueprint $table)
{
$table->string('name');
}

public function getKeyName()
{
return 'name';
}

public function getIncrementing()
{
return false;
}
}

0 comments on commit 63a53e1

Please sign in to comment.