WooCommerce Docs: Improve Manifest Structure, Extend Frontmatter Support (#39214)
This commit is contained in:
parent
66cee083d4
commit
69e9acaba9
|
@ -14,7 +14,8 @@
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"woocommerce/woocommerce-sniffs": "^0.1.3",
|
"woocommerce/woocommerce-sniffs": "^0.1.3",
|
||||||
"phpunit/phpunit": "^9.6",
|
"phpunit/phpunit": "^9.6",
|
||||||
"yoast/phpunit-polyfills": "^2.0"
|
"yoast/phpunit-polyfills": "^2.0",
|
||||||
|
"php-stubs/wordpress-tests-stubs": "^6.2"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"allow-plugins": {
|
"allow-plugins": {
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "c3e8ed8878c0f36e0b6be7c78d35663f",
|
"content-hash": "061f99e607a2e8a793f0231a294cc761",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "dflydev/dot-access-data",
|
"name": "dflydev/dot-access-data",
|
||||||
|
@ -1030,6 +1030,46 @@
|
||||||
},
|
},
|
||||||
"time": "2022-02-21T01:04:05+00:00"
|
"time": "2022-02-21T01:04:05+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "php-stubs/wordpress-tests-stubs",
|
||||||
|
"version": "v6.2.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/php-stubs/wordpress-tests-stubs.git",
|
||||||
|
"reference": "175f395c814d9f52ebd2c1c64069a3b01ef764e8"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/php-stubs/wordpress-tests-stubs/zipball/175f395c814d9f52ebd2c1c64069a3b01ef764e8",
|
||||||
|
"reference": "175f395c814d9f52ebd2c1c64069a3b01ef764e8",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"php": "~7.3 || ~8.0",
|
||||||
|
"php-stubs/generator": "^0.8.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"symfony/polyfill-php73": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
|
||||||
|
"szepeviktor/phpstan-wordpress": "WordPress extensions for PHPStan"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"description": "WordPress Tests function and class declaration stubs for static analysis.",
|
||||||
|
"homepage": "https://github.com/php-stubs/wordpress-tests-stubs",
|
||||||
|
"keywords": [
|
||||||
|
"PHPStan",
|
||||||
|
"static analysis",
|
||||||
|
"wordpress"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/php-stubs/wordpress-tests-stubs/issues",
|
||||||
|
"source": "https://github.com/php-stubs/wordpress-tests-stubs/tree/v6.2.0"
|
||||||
|
},
|
||||||
|
"time": "2023-05-15T07:50:52+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "phpcompatibility/php-compatibility",
|
"name": "phpcompatibility/php-compatibility",
|
||||||
"version": "9.3.5",
|
"version": "9.3.5",
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
---
|
---
|
||||||
title: Getting Started with WooCommerce
|
category_title: Getting Started with WooCommerce
|
||||||
---
|
---
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
---
|
||||||
|
post_title: Install the Plugin
|
||||||
|
---
|
||||||
|
|
||||||
|
## Install the plugin
|
||||||
|
|
||||||
|
1. Download the plugin from the [GitHub repository](https://example.com).
|
||||||
|
2. Upload the plugin to your WordPress site.
|
||||||
|
3. Activate the plugin.
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
title: Local Development
|
post_title: Local Development
|
||||||
---
|
---
|
||||||
|
|
||||||
## Local Development
|
## Local Development
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
---
|
---
|
||||||
title: Troubleshooting Problems
|
category_title: Troubleshooting Problems
|
||||||
---
|
---
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
title: What Went Wrong?
|
post_title: What Went Wrong?
|
||||||
---
|
---
|
||||||
|
|
||||||
## Try some troubleshooting
|
## Try some troubleshooting
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
---
|
---
|
||||||
title: Testing WooCommerce
|
category_title: Testing WooCommerce
|
||||||
---
|
---
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
title: Unit Testing
|
post_title: Unit Testing
|
||||||
---
|
---
|
||||||
|
|
||||||
## Unit Test
|
## Unit Test
|
||||||
|
|
|
@ -1,20 +1,33 @@
|
||||||
{
|
{
|
||||||
"categories": [
|
"categories": [
|
||||||
{
|
{
|
||||||
"title": "Getting Started with WooCommerce",
|
"category_title": "Getting Started with WooCommerce",
|
||||||
"posts": [
|
"posts": [
|
||||||
{
|
{
|
||||||
"title": "Local Development",
|
"post_title": "Local Development",
|
||||||
|
"edit_url": "https://github.com/woocommerce/woocommerce/edit/trunk/plugins/woocommerce-docs/example-docs/get-started/local-development.md",
|
||||||
"url": "https://raw.githubusercontent.com/woocommerce/woocommerce/trunk/plugins/woocommerce-docs/example-docs/get-started/local-development.md",
|
"url": "https://raw.githubusercontent.com/woocommerce/woocommerce/trunk/plugins/woocommerce-docs/example-docs/get-started/local-development.md",
|
||||||
"id": "c068ce54044fa44c760a69bd71ef21274f2a5a37"
|
"id": "c068ce54044fa44c760a69bd71ef21274f2a5a37"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"categories": [
|
"categories": [
|
||||||
{
|
{
|
||||||
"title": "Troubleshooting Problems",
|
"category_title": "Installation",
|
||||||
"posts": [
|
"posts": [
|
||||||
{
|
{
|
||||||
"title": "What Went Wrong?",
|
"edit_url": "https://github.com/woocommerce/woocommerce/edit/trunk/plugins/woocommerce-docs/example-docs/get-started/installation/install-plugin.md",
|
||||||
|
"url": "https://raw.githubusercontent.com/woocommerce/woocommerce/trunk/plugins/woocommerce-docs/example-docs/get-started/installation/install-plugin.md",
|
||||||
|
"id": "fb59bd01dda7b090e5b0a557948e155a6b679d6a"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"categories": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category_title": "Troubleshooting Problems",
|
||||||
|
"posts": [
|
||||||
|
{
|
||||||
|
"post_title": "What Went Wrong?",
|
||||||
|
"edit_url": "https://github.com/woocommerce/woocommerce/edit/trunk/plugins/woocommerce-docs/example-docs/get-started/troubleshooting/what-went-wrong.md",
|
||||||
"url": "https://raw.githubusercontent.com/woocommerce/woocommerce/trunk/plugins/woocommerce-docs/example-docs/get-started/troubleshooting/what-went-wrong.md",
|
"url": "https://raw.githubusercontent.com/woocommerce/woocommerce/trunk/plugins/woocommerce-docs/example-docs/get-started/troubleshooting/what-went-wrong.md",
|
||||||
"id": "1f88c4d039e72c059c928ab475ad1ea0a02c8abb"
|
"id": "1f88c4d039e72c059c928ab475ad1ea0a02c8abb"
|
||||||
}
|
}
|
||||||
|
@ -24,10 +37,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Testing WooCommerce",
|
"category_title": "Testing WooCommerce",
|
||||||
"posts": [
|
"posts": [
|
||||||
{
|
{
|
||||||
"title": "Unit Testing",
|
"post_title": "Unit Testing",
|
||||||
|
"edit_url": "https://github.com/woocommerce/woocommerce/edit/trunk/plugins/woocommerce-docs/example-docs/testing/unit-tests.md",
|
||||||
"url": "https://raw.githubusercontent.com/woocommerce/woocommerce/trunk/plugins/woocommerce-docs/example-docs/testing/unit-tests.md",
|
"url": "https://raw.githubusercontent.com/woocommerce/woocommerce/trunk/plugins/woocommerce-docs/example-docs/testing/unit-tests.md",
|
||||||
"id": "120770c899215a889246b47ac883e4dda1f97b8b"
|
"id": "120770c899215a889246b47ac883e4dda1f97b8b"
|
||||||
}
|
}
|
||||||
|
@ -35,5 +49,5 @@
|
||||||
"categories": []
|
"categories": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"hash": "180a6ce0bebb8e84072fda451758ef6326490a99e7b3a349b9e45baa8c7c54ac"
|
"hash": "db0047299d7dd99bd9a657d59be9e6e4f113710a253c27417427965f7a5ebc8c"
|
||||||
}
|
}
|
|
@ -31,6 +31,39 @@ class ManifestProcessor {
|
||||||
return $converter;
|
return $converter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate post args
|
||||||
|
*
|
||||||
|
* @param mixed $post The post to generate args for.
|
||||||
|
* @param mixed $post_content The post content.
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private static function generate_post_args( $post, $post_content ) {
|
||||||
|
$possible_attributes = array(
|
||||||
|
'post_title',
|
||||||
|
'post_author',
|
||||||
|
'post_date',
|
||||||
|
'comment_status',
|
||||||
|
'post_status',
|
||||||
|
);
|
||||||
|
|
||||||
|
$args = array();
|
||||||
|
|
||||||
|
foreach ( $possible_attributes as $attribute ) {
|
||||||
|
if ( isset( $post[ $attribute ] ) ) {
|
||||||
|
$args[ $attribute ] = $post[ $attribute ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$args['post_content'] = $post_content;
|
||||||
|
|
||||||
|
if ( ! isset( $args['post_status'] ) ) {
|
||||||
|
$args['post_status'] = 'publish';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $args;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process categories
|
* Process categories
|
||||||
*
|
*
|
||||||
|
@ -40,25 +73,27 @@ class ManifestProcessor {
|
||||||
*/
|
*/
|
||||||
private static function process_categories( $categories, $logger_action_id, $parent_id = 0 ) {
|
private static function process_categories( $categories, $logger_action_id, $parent_id = 0 ) {
|
||||||
foreach ( $categories as $category ) {
|
foreach ( $categories as $category ) {
|
||||||
$term = term_exists( $category['title'], 'category' );
|
$term = term_exists( $category['category_title'], 'category' );
|
||||||
|
|
||||||
|
$category_args = array( 'parent' => $parent_id );
|
||||||
|
|
||||||
|
if ( isset( $category['category_slug'] ) ) {
|
||||||
|
$category_args['slug'] = $category['category_slug'];
|
||||||
|
}
|
||||||
|
|
||||||
// If the category doesn't exist, create it.
|
// If the category doesn't exist, create it.
|
||||||
if ( 0 === $term || null === $term ) {
|
if ( 0 === $term || null === $term ) {
|
||||||
$term = wp_insert_term(
|
$term = wp_insert_term(
|
||||||
$category['title'],
|
$category['category_title'],
|
||||||
'category',
|
'category',
|
||||||
array(
|
$category_args
|
||||||
'parent' => $parent_id,
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// If the category exists, update it.
|
// If the category exists, update it.
|
||||||
$term = wp_update_term(
|
$term = wp_update_term(
|
||||||
$term['term_id'],
|
$term['term_id'],
|
||||||
'category',
|
'category',
|
||||||
array(
|
$category_args
|
||||||
'parent' => $parent_id,
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,31 +120,27 @@ class ManifestProcessor {
|
||||||
// If the post doesn't exist, create it.
|
// If the post doesn't exist, create it.
|
||||||
if ( ! $existing_post ) {
|
if ( ! $existing_post ) {
|
||||||
$post_id = \WooCommerceDocs\Data\DocsStore::insert_docs_post(
|
$post_id = \WooCommerceDocs\Data\DocsStore::insert_docs_post(
|
||||||
array(
|
self::generate_post_args( $post, $blocks ),
|
||||||
'post_title' => $post['title'],
|
|
||||||
'post_content' => $blocks,
|
|
||||||
'post_status' => 'publish',
|
|
||||||
),
|
|
||||||
$post['id']
|
$post['id']
|
||||||
);
|
);
|
||||||
|
|
||||||
\ActionScheduler_Logger::instance()->log( $logger_action_id, 'Created post with id: ' . $post_id );
|
\ActionScheduler_Logger::instance()->log( $logger_action_id, 'Created post with id: ' . $post_id );
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
$post_update = self::generate_post_args( $post, $blocks );
|
||||||
|
$post_update = array_merge( $post_update, array( 'ID' => $existing_post->ID ) );
|
||||||
|
|
||||||
// if the post exists, update it .
|
// if the post exists, update it .
|
||||||
$post_id = \WoocommerceDocs\Data\DocsStore::update_docs_post(
|
$post_id = \WoocommerceDocs\Data\DocsStore::update_docs_post(
|
||||||
array(
|
$post_update,
|
||||||
'ID' => $existing_post->ID,
|
|
||||||
'post_title' => $post['title'],
|
|
||||||
'post_content' => $blocks,
|
|
||||||
),
|
|
||||||
$post['id']
|
$post['id']
|
||||||
);
|
);
|
||||||
|
|
||||||
\ActionScheduler_Logger::instance()->log( $logger_action_id, 'Updated post with id: ' . $post_id );
|
\ActionScheduler_Logger::instance()->log( $logger_action_id, 'Updated post with id: ' . $post_id );
|
||||||
}
|
}
|
||||||
|
|
||||||
wp_set_post_categories( $post_id, array( $term['term_id'] ), $parent_id );
|
wp_set_post_categories( $post_id, array( $term['term_id'] ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process any sub-categories.
|
// Process any sub-categories.
|
||||||
|
|
|
@ -11,3 +11,6 @@ $tests_dir = getenv( 'WP_TESTS_DIR' );
|
||||||
|
|
||||||
require_once $tests_dir . '/includes/functions.php';
|
require_once $tests_dir . '/includes/functions.php';
|
||||||
require_once $tests_dir . '/includes/bootstrap.php';
|
require_once $tests_dir . '/includes/bootstrap.php';
|
||||||
|
|
||||||
|
// Require action-scheduler manually.
|
||||||
|
require_once __DIR__ . '/../vendor/woocommerce/action-scheduler/action-scheduler.php';
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace WooCommerceDocs\Tests\Manifest;
|
||||||
|
|
||||||
|
use WooCommerceDocs\Manifest\ManifestProcessor;
|
||||||
|
use WP_UnitTestCase;
|
||||||
|
use WooCommerceDocs\Data\DocsStore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ManifestProcessorTest
|
||||||
|
*
|
||||||
|
* @package WooCommerceDocs\Tests\Manifest
|
||||||
|
*/
|
||||||
|
class ManifestProcessorTest extends WP_UnitTestCase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test processing a manifest into WordPress posts and categories.
|
||||||
|
*/
|
||||||
|
public function test_process_manifest() {
|
||||||
|
|
||||||
|
$manifest = json_decode( file_get_contents( __DIR__ . '/fixtures/manifest.json' ), true );
|
||||||
|
$md_file = file_get_contents( __DIR__ . '/fixtures/test.md' );
|
||||||
|
|
||||||
|
// Mock the wp_remote_get function with a filter.
|
||||||
|
add_filter(
|
||||||
|
'pre_http_request',
|
||||||
|
function ( $preempt, $args, $url ) use ( $md_file ) {
|
||||||
|
return array(
|
||||||
|
'response' => array(
|
||||||
|
'code' => 200,
|
||||||
|
'message' => 'OK',
|
||||||
|
),
|
||||||
|
'body' => $md_file,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
10,
|
||||||
|
3
|
||||||
|
);
|
||||||
|
|
||||||
|
ManifestProcessor::process_manifest( $manifest, 123 );
|
||||||
|
|
||||||
|
$get_started_category = get_term_by( 'name', 'Getting Started with WooCommerce', 'category' );
|
||||||
|
$this->assertNotFalse( $get_started_category );
|
||||||
|
|
||||||
|
$install_category = get_term_by( 'name', 'Installation', 'category' );
|
||||||
|
$this->assertNotFalse( $install_category );
|
||||||
|
// Check parent is correct.
|
||||||
|
$this->assertEquals( $get_started_category->term_id, $install_category->parent );
|
||||||
|
|
||||||
|
$troubleshoot_category = get_term_by( 'name', 'Troubleshooting Problems', 'category' );
|
||||||
|
$this->assertNotFalse( $troubleshoot_category );
|
||||||
|
// Check parent is correct.
|
||||||
|
$this->assertEquals( $get_started_category->term_id, $troubleshoot_category->parent );
|
||||||
|
|
||||||
|
$testing_category = get_term_by( 'name', 'Testing WooCommerce', 'category' );
|
||||||
|
$this->assertNotFalse( $testing_category );
|
||||||
|
|
||||||
|
// check posts exist using the DocStore.
|
||||||
|
$posts = DocsStore::get_posts();
|
||||||
|
$this->assertEquals( 4, count( $posts ) );
|
||||||
|
|
||||||
|
$install_plugin_post = $posts[0];
|
||||||
|
$local_dev_post = $posts[1];
|
||||||
|
$unit_testing_post = $posts[2];
|
||||||
|
$what_went_wrong_post = $posts[3];
|
||||||
|
|
||||||
|
// check doc titles (note that they are returned in alpha order).
|
||||||
|
$this->assertEquals( 'Install the Plugin', $install_plugin_post->post_title );
|
||||||
|
$this->assertEquals( 'Local Development', $local_dev_post->post_title );
|
||||||
|
$this->assertEquals( 'Unit Testing', $unit_testing_post->post_title );
|
||||||
|
$this->assertEquals( 'What Went Wrong?', $what_went_wrong_post->post_title );
|
||||||
|
|
||||||
|
// Assert that post was assigned to categories.
|
||||||
|
$this->assertTrue( has_category( $install_category->term_id, $install_plugin_post->ID ) );
|
||||||
|
$this->assertTrue( has_category( $troubleshoot_category->term_id, $what_went_wrong_post->ID ) );
|
||||||
|
$this->assertTrue( has_category( $testing_category->term_id, $unit_testing_post->ID ) );
|
||||||
|
$this->assertTrue( has_category( $troubleshoot_category->term_id, $what_went_wrong_post->ID ) );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
{
|
||||||
|
"categories": [
|
||||||
|
{
|
||||||
|
"category_title": "Getting Started with WooCommerce",
|
||||||
|
"posts": [
|
||||||
|
{
|
||||||
|
"post_title": "Local Development",
|
||||||
|
"edit_url": "https://example.com/edit/local-development.md",
|
||||||
|
"url": "https://example.com/local-development.md",
|
||||||
|
"id": "c068ce54044fa44c760a69bd71ef21274f2a5a37"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"categories": [
|
||||||
|
{
|
||||||
|
"category_title": "Installation",
|
||||||
|
"posts": [
|
||||||
|
{
|
||||||
|
"post_title": "Install the Plugin",
|
||||||
|
"edit_url": "https://example.com/edit/install-plugin.md",
|
||||||
|
"url": "https://example.com/install-plugin.md",
|
||||||
|
"id": "fb59bd01dda7b090e5b0a557948e155a6b679d6a"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"categories": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category_title": "Troubleshooting Problems",
|
||||||
|
"posts": [
|
||||||
|
{
|
||||||
|
"post_title": "What Went Wrong?",
|
||||||
|
"edit_url": "https://example.com/edit/what-went-wrong.md",
|
||||||
|
"url": "https://example.com/what-went-wrong.md",
|
||||||
|
"id": "1f88c4d039e72c059c928ab475ad1ea0a02c8abb"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"categories": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category_title": "Testing WooCommerce",
|
||||||
|
"posts": [
|
||||||
|
{
|
||||||
|
"post_title": "Unit Testing",
|
||||||
|
"edit_url": "https://example.com/edit/unit-tests.md",
|
||||||
|
"url": "https://example.com/unit-tests.md",
|
||||||
|
"id": "120770c899215a889246b47ac883e4dda1f97b8b"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"categories": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"hash": "db0047299d7dd99bd9a657d59be9e6e4f113710a253c27417427965f7a5ebc8c"
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
post_title: Testing Post
|
||||||
|
---
|
||||||
|
|
||||||
|
### Testing Post
|
||||||
|
|
||||||
|
This is a test post.
|
|
@ -3474,6 +3474,9 @@ importers:
|
||||||
gray-matter:
|
gray-matter:
|
||||||
specifier: ^4.0.3
|
specifier: ^4.0.3
|
||||||
version: 4.0.3
|
version: 4.0.3
|
||||||
|
js-yaml:
|
||||||
|
specifier: ^4.1.0
|
||||||
|
version: 4.1.0
|
||||||
octokit:
|
octokit:
|
||||||
specifier: ^2.0.14
|
specifier: ^2.0.14
|
||||||
version: 2.0.14
|
version: 2.0.14
|
||||||
|
@ -9184,8 +9187,8 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.21.3
|
'@babel/core': 7.21.3
|
||||||
'@babel/helper-module-imports': 7.16.0
|
'@babel/helper-module-imports': 7.16.0
|
||||||
'@babel/helper-plugin-utils': 7.14.5
|
'@babel/helper-plugin-utils': 7.21.5
|
||||||
babel-plugin-polyfill-corejs2: 0.3.0(@babel/core@7.21.3)
|
babel-plugin-polyfill-corejs2: 0.3.3(@babel/core@7.21.3)
|
||||||
babel-plugin-polyfill-corejs3: 0.4.0(@babel/core@7.21.3)
|
babel-plugin-polyfill-corejs3: 0.4.0(@babel/core@7.21.3)
|
||||||
babel-plugin-polyfill-regenerator: 0.3.0(@babel/core@7.21.3)
|
babel-plugin-polyfill-regenerator: 0.3.0(@babel/core@7.21.3)
|
||||||
semver: 6.3.0
|
semver: 6.3.0
|
||||||
|
@ -18453,7 +18456,7 @@ packages:
|
||||||
'@wordpress/style-engine': 0.15.0
|
'@wordpress/style-engine': 0.15.0
|
||||||
'@wordpress/token-list': 2.19.0
|
'@wordpress/token-list': 2.19.0
|
||||||
'@wordpress/url': 3.29.0
|
'@wordpress/url': 3.29.0
|
||||||
'@wordpress/warning': 2.34.0
|
'@wordpress/warning': 2.19.0
|
||||||
'@wordpress/wordcount': 3.19.0
|
'@wordpress/wordcount': 3.19.0
|
||||||
change-case: 4.1.2
|
change-case: 4.1.2
|
||||||
classnames: 2.3.1
|
classnames: 2.3.1
|
||||||
|
@ -19813,7 +19816,7 @@ packages:
|
||||||
cosmiconfig: 7.0.1
|
cosmiconfig: 7.0.1
|
||||||
eslint: 8.32.0
|
eslint: 8.32.0
|
||||||
eslint-config-prettier: 8.5.0(eslint@8.32.0)
|
eslint-config-prettier: 8.5.0(eslint@8.32.0)
|
||||||
eslint-plugin-import: 2.25.4(@typescript-eslint/parser@5.54.0)(eslint-import-resolver-typescript@2.5.0)(eslint-import-resolver-webpack@0.13.2)(eslint@8.32.0)
|
eslint-plugin-import: 2.25.4(@typescript-eslint/parser@5.54.0)(eslint@8.32.0)
|
||||||
eslint-plugin-jest: 27.2.1(@typescript-eslint/eslint-plugin@5.54.0)(eslint@8.32.0)(jest@27.5.1)(typescript@4.9.5)
|
eslint-plugin-jest: 27.2.1(@typescript-eslint/eslint-plugin@5.54.0)(eslint@8.32.0)(jest@27.5.1)(typescript@4.9.5)
|
||||||
eslint-plugin-jsdoc: 39.9.1(eslint@8.32.0)
|
eslint-plugin-jsdoc: 39.9.1(eslint@8.32.0)
|
||||||
eslint-plugin-jsx-a11y: 6.5.1(eslint@8.32.0)
|
eslint-plugin-jsx-a11y: 6.5.1(eslint@8.32.0)
|
||||||
|
@ -19854,7 +19857,7 @@ packages:
|
||||||
cosmiconfig: 7.0.1
|
cosmiconfig: 7.0.1
|
||||||
eslint: 8.32.0
|
eslint: 8.32.0
|
||||||
eslint-config-prettier: 8.5.0(eslint@8.32.0)
|
eslint-config-prettier: 8.5.0(eslint@8.32.0)
|
||||||
eslint-plugin-import: 2.25.4(@typescript-eslint/parser@5.54.0)(eslint-import-resolver-typescript@2.5.0)(eslint-import-resolver-webpack@0.13.2)(eslint@8.32.0)
|
eslint-plugin-import: 2.25.4(@typescript-eslint/parser@5.54.0)(eslint@8.32.0)
|
||||||
eslint-plugin-jest: 27.2.1(@typescript-eslint/eslint-plugin@5.54.0)(eslint@8.32.0)(jest@27.5.1)(typescript@4.9.5)
|
eslint-plugin-jest: 27.2.1(@typescript-eslint/eslint-plugin@5.54.0)(eslint@8.32.0)(jest@27.5.1)(typescript@4.9.5)
|
||||||
eslint-plugin-jsdoc: 39.9.1(eslint@8.32.0)
|
eslint-plugin-jsdoc: 39.9.1(eslint@8.32.0)
|
||||||
eslint-plugin-jsx-a11y: 6.5.1(eslint@8.32.0)
|
eslint-plugin-jsx-a11y: 6.5.1(eslint@8.32.0)
|
||||||
|
@ -19895,7 +19898,7 @@ packages:
|
||||||
cosmiconfig: 7.0.1
|
cosmiconfig: 7.0.1
|
||||||
eslint: 8.32.0
|
eslint: 8.32.0
|
||||||
eslint-config-prettier: 8.5.0(eslint@8.32.0)
|
eslint-config-prettier: 8.5.0(eslint@8.32.0)
|
||||||
eslint-plugin-import: 2.25.4(@typescript-eslint/parser@5.54.0)(eslint-import-resolver-typescript@2.5.0)(eslint-import-resolver-webpack@0.13.2)(eslint@8.32.0)
|
eslint-plugin-import: 2.25.4(@typescript-eslint/parser@5.54.0)(eslint@8.32.0)
|
||||||
eslint-plugin-jest: 27.2.1(@typescript-eslint/eslint-plugin@5.54.0)(eslint@8.32.0)(jest@29.5.0)(typescript@4.9.5)
|
eslint-plugin-jest: 27.2.1(@typescript-eslint/eslint-plugin@5.54.0)(eslint@8.32.0)(jest@29.5.0)(typescript@4.9.5)
|
||||||
eslint-plugin-jsdoc: 39.9.1(eslint@8.32.0)
|
eslint-plugin-jsdoc: 39.9.1(eslint@8.32.0)
|
||||||
eslint-plugin-jsx-a11y: 6.5.1(eslint@8.32.0)
|
eslint-plugin-jsx-a11y: 6.5.1(eslint@8.32.0)
|
||||||
|
@ -27112,7 +27115,7 @@ packages:
|
||||||
has: 1.0.3
|
has: 1.0.3
|
||||||
is-core-module: 2.8.0
|
is-core-module: 2.8.0
|
||||||
is-glob: 4.0.3
|
is-glob: 4.0.3
|
||||||
minimatch: 3.0.4
|
minimatch: 3.1.2
|
||||||
object.values: 1.1.5
|
object.values: 1.1.5
|
||||||
resolve: 1.20.0
|
resolve: 1.20.0
|
||||||
tsconfig-paths: 3.14.0
|
tsconfig-paths: 3.14.0
|
||||||
|
@ -27152,6 +27155,36 @@ packages:
|
||||||
- eslint-import-resolver-webpack
|
- eslint-import-resolver-webpack
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
|
/eslint-plugin-import@2.25.4(@typescript-eslint/parser@5.54.0)(eslint@8.32.0):
|
||||||
|
resolution: {integrity: sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
peerDependencies:
|
||||||
|
'@typescript-eslint/parser': '*'
|
||||||
|
eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@typescript-eslint/parser':
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@typescript-eslint/parser': 5.54.0(eslint@8.32.0)(typescript@4.9.5)
|
||||||
|
array-includes: 3.1.4
|
||||||
|
array.prototype.flat: 1.2.5
|
||||||
|
debug: 2.6.9(supports-color@6.1.0)
|
||||||
|
doctrine: 2.1.0
|
||||||
|
eslint: 8.32.0
|
||||||
|
eslint-import-resolver-node: 0.3.6
|
||||||
|
eslint-module-utils: 2.7.3(@typescript-eslint/parser@5.54.0)(eslint-import-resolver-node@0.3.6)(eslint-import-resolver-typescript@2.5.0)(eslint-import-resolver-webpack@0.13.2)
|
||||||
|
has: 1.0.3
|
||||||
|
is-core-module: 2.8.0
|
||||||
|
is-glob: 4.0.3
|
||||||
|
minimatch: 3.1.2
|
||||||
|
object.values: 1.1.5
|
||||||
|
resolve: 1.20.0
|
||||||
|
tsconfig-paths: 3.14.0
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- eslint-import-resolver-typescript
|
||||||
|
- eslint-import-resolver-webpack
|
||||||
|
- supports-color
|
||||||
|
|
||||||
/eslint-plugin-jest@23.20.0(eslint@7.32.0)(typescript@4.9.5):
|
/eslint-plugin-jest@23.20.0(eslint@7.32.0)(typescript@4.9.5):
|
||||||
resolution: {integrity: sha512-+6BGQt85OREevBDWCvhqj1yYA4+BFK4XnRZSGJionuEYmcglMZYLNNBBemwzbqUAckURaHdJSBcjHPyrtypZOw==}
|
resolution: {integrity: sha512-+6BGQt85OREevBDWCvhqj1yYA4+BFK4XnRZSGJionuEYmcglMZYLNNBBemwzbqUAckURaHdJSBcjHPyrtypZOw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
@ -34072,7 +34105,7 @@ packages:
|
||||||
esprima: 4.0.1
|
esprima: 4.0.1
|
||||||
|
|
||||||
/js-yaml@3.5.3:
|
/js-yaml@3.5.3:
|
||||||
resolution: {integrity: sha1-6e5ggrBld3DkNG368qWMWZIlH3Y=}
|
resolution: {integrity: sha512-rkxjJUwevxyYOdr45k3IOyZjyhRbEMqUvcMyXXeBXTf8kdFaFKUIvMkdHgIcFIjNIoctM6l/emA7OjXYVabYSw==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dependencies:
|
dependencies:
|
||||||
argparse: 1.0.10
|
argparse: 1.0.10
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
"glob": "^10.2.4",
|
"glob": "^10.2.4",
|
||||||
"graphql": "^16.6.0",
|
"graphql": "^16.6.0",
|
||||||
"gray-matter": "^4.0.3",
|
"gray-matter": "^4.0.3",
|
||||||
|
"js-yaml": "^4.1.0",
|
||||||
"octokit": "^2.0.14",
|
"octokit": "^2.0.14",
|
||||||
"ora": "^5.4.1",
|
"ora": "^5.4.1",
|
||||||
"promptly": "^3.2.0",
|
"promptly": "^3.2.0",
|
||||||
|
|
|
@ -38,8 +38,13 @@ export const generateManifestCommand = new Command( 'create' )
|
||||||
'Root directory of the markdown files, used to generate URLs.',
|
'Root directory of the markdown files, used to generate URLs.',
|
||||||
process.cwd()
|
process.cwd()
|
||||||
)
|
)
|
||||||
|
.option(
|
||||||
|
'-be --baseEditUrl <baseEditUrl>',
|
||||||
|
'Base url to provide edit links to. This option will be ignored if your baseUrl is not a GitHub URL.',
|
||||||
|
'https://github.com/woocommerce/woocommerce/edit/trunk'
|
||||||
|
)
|
||||||
.action( async ( dir, projectName, options ) => {
|
.action( async ( dir, projectName, options ) => {
|
||||||
const { outputFilePath, baseUrl, rootDir } = options;
|
const { outputFilePath, baseUrl, rootDir, baseEditUrl } = options;
|
||||||
|
|
||||||
// determine if the rootDir is absolute or relative
|
// determine if the rootDir is absolute or relative
|
||||||
const absoluteRootDir = path.isAbsolute( rootDir )
|
const absoluteRootDir = path.isAbsolute( rootDir )
|
||||||
|
@ -60,7 +65,8 @@ export const generateManifestCommand = new Command( 'create' )
|
||||||
absoluteRootDir,
|
absoluteRootDir,
|
||||||
absoluteSubDir,
|
absoluteSubDir,
|
||||||
projectName,
|
projectName,
|
||||||
baseUrl
|
baseUrl,
|
||||||
|
baseEditUrl
|
||||||
);
|
);
|
||||||
|
|
||||||
Logger.endTask();
|
Logger.endTask();
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
---
|
---
|
||||||
title: Getting Started with WooCommerce
|
category_title: Getting Started with WooCommerce
|
||||||
|
category_slug: get-started
|
||||||
---
|
---
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
### Install the plugin
|
||||||
|
|
||||||
|
1. Download the plugin from the [GitHub repository](https://example.com).
|
||||||
|
2. Upload the plugin to your WordPress site.
|
||||||
|
3. Activate the plugin.
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
title: Local Development
|
post_title: Local Development
|
||||||
---
|
---
|
||||||
|
|
||||||
## Local Development
|
## Local Development
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
---
|
---
|
||||||
title: Troubleshooting Problems
|
category_title: Troubleshooting Problems
|
||||||
---
|
---
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
title: What Went Wrong?
|
post_title: What Went Wrong?
|
||||||
---
|
---
|
||||||
|
|
||||||
## Try some troubleshooting
|
## Try some troubleshooting
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
---
|
---
|
||||||
title: Testing WooCommerce
|
category_title: Testing WooCommerce
|
||||||
---
|
---
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
title: Unit Testing
|
category_title: Unit Testing
|
||||||
---
|
---
|
||||||
|
|
||||||
## Unit Test
|
## Unit Test
|
||||||
|
|
|
@ -6,7 +6,7 @@ import path from 'path';
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import { generateFileUrl } from '../generate-manifest';
|
import { generateFileUrl } from '../generate-urls';
|
||||||
|
|
||||||
describe( 'generateFileUrl', () => {
|
describe( 'generateFileUrl', () => {
|
||||||
it( 'should generate a file url relative to the root directory provided', () => {
|
it( 'should generate a file url relative to the root directory provided', () => {
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { generatePostFrontMatter } from '../generate-frontmatter';
|
||||||
|
|
||||||
|
describe( 'generateFrontmatter', () => {
|
||||||
|
it( 'should not allow disallowed attributes', () => {
|
||||||
|
const frontMatter = generatePostFrontMatter( `---
|
||||||
|
title: Hello World
|
||||||
|
description: This is a description
|
||||||
|
post_content: This is some content
|
||||||
|
post_title: This is a title
|
||||||
|
---
|
||||||
|
` );
|
||||||
|
|
||||||
|
expect( frontMatter ).toEqual( {
|
||||||
|
post_title: 'This is a title',
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'should not do additional date parsing', () => {
|
||||||
|
const frontMatter = generatePostFrontMatter( `---
|
||||||
|
post_date: 2023-07-12 15:30:00
|
||||||
|
---
|
||||||
|
` );
|
||||||
|
|
||||||
|
expect( frontMatter ).toEqual( {
|
||||||
|
post_date: '2023-07-12 15:30:00',
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
} );
|
|
@ -18,31 +18,47 @@ describe( 'generateManifest', () => {
|
||||||
rootDir,
|
rootDir,
|
||||||
dir,
|
dir,
|
||||||
'example-docs',
|
'example-docs',
|
||||||
'https://example.com'
|
'https://example.com',
|
||||||
|
'https://example.com/edit'
|
||||||
);
|
);
|
||||||
|
|
||||||
const topLevelCategories = manifest.categories;
|
const topLevelCategories = manifest.categories;
|
||||||
|
|
||||||
expect( topLevelCategories[ 0 ].title ).toEqual(
|
expect( topLevelCategories[ 0 ].category_title ).toEqual(
|
||||||
'Getting Started with WooCommerce'
|
'Getting Started with WooCommerce'
|
||||||
);
|
);
|
||||||
expect( topLevelCategories[ 1 ].title ).toEqual(
|
expect( topLevelCategories[ 1 ].category_title ).toEqual(
|
||||||
'Testing WooCommerce'
|
'Testing WooCommerce'
|
||||||
);
|
);
|
||||||
|
|
||||||
const subCategories = topLevelCategories[ 0 ].categories;
|
const subCategories = topLevelCategories[ 0 ].categories;
|
||||||
|
|
||||||
expect( subCategories[ 0 ].title ).toEqual(
|
expect( subCategories[ 1 ].category_title ).toEqual(
|
||||||
'Troubleshooting Problems'
|
'Troubleshooting Problems'
|
||||||
);
|
);
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
it( 'should create categories with titles where there is no index README', async () => {
|
||||||
|
const manifest = await generateManifestFromDirectory(
|
||||||
|
rootDir,
|
||||||
|
dir,
|
||||||
|
'example-docs',
|
||||||
|
'https://example.com',
|
||||||
|
'https://example.com/edit'
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
manifest.categories[ 0 ].categories[ 0 ].category_title
|
||||||
|
).toEqual( 'Installation' );
|
||||||
|
} );
|
||||||
|
|
||||||
it( 'should create post urls with the correct url', async () => {
|
it( 'should create post urls with the correct url', async () => {
|
||||||
const manifest = await generateManifestFromDirectory(
|
const manifest = await generateManifestFromDirectory(
|
||||||
rootDir,
|
rootDir,
|
||||||
dir,
|
dir,
|
||||||
'example-docs',
|
'example-docs',
|
||||||
'https://example.com'
|
'https://example.com',
|
||||||
|
'https://example.com/edit'
|
||||||
);
|
);
|
||||||
|
|
||||||
expect( manifest.categories[ 0 ].posts[ 0 ].url ).toEqual(
|
expect( manifest.categories[ 0 ].posts[ 0 ].url ).toEqual(
|
||||||
|
@ -52,7 +68,7 @@ describe( 'generateManifest', () => {
|
||||||
expect(
|
expect(
|
||||||
manifest.categories[ 0 ].categories[ 0 ].posts[ 0 ].url
|
manifest.categories[ 0 ].categories[ 0 ].posts[ 0 ].url
|
||||||
).toEqual(
|
).toEqual(
|
||||||
'https://example.com/example-docs/get-started/troubleshooting/what-went-wrong.md'
|
'https://example.com/example-docs/get-started/installation/install-plugin.md'
|
||||||
);
|
);
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
@ -61,9 +77,24 @@ describe( 'generateManifest', () => {
|
||||||
rootDir,
|
rootDir,
|
||||||
dir,
|
dir,
|
||||||
'example-docs',
|
'example-docs',
|
||||||
'https://example.com'
|
'https://example.com',
|
||||||
|
'https://example.com/edit'
|
||||||
);
|
);
|
||||||
|
|
||||||
expect( manifest.hash ).not.toBeUndefined();
|
expect( manifest.hash ).not.toBeUndefined();
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
it( 'should generate edit_url when github is in the base url', async () => {
|
||||||
|
const manifest = await generateManifestFromDirectory(
|
||||||
|
rootDir,
|
||||||
|
dir,
|
||||||
|
'example-docs',
|
||||||
|
'https://github.com',
|
||||||
|
'https://github.com/edit'
|
||||||
|
);
|
||||||
|
|
||||||
|
expect( manifest.categories[ 0 ].posts[ 0 ].edit_url ).toEqual(
|
||||||
|
'https://github.com/edit/example-docs/get-started/local-development.md'
|
||||||
|
);
|
||||||
|
} );
|
||||||
} );
|
} );
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import matter from 'gray-matter';
|
||||||
|
import yaml from 'js-yaml';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate front-matter for supported post attributes.
|
||||||
|
*
|
||||||
|
* @param fileContents
|
||||||
|
*/
|
||||||
|
export const generatePostFrontMatter = (
|
||||||
|
fileContents: string
|
||||||
|
): {
|
||||||
|
[ key: string ]: unknown;
|
||||||
|
} => {
|
||||||
|
const allowList = [
|
||||||
|
'post_date',
|
||||||
|
'post_title',
|
||||||
|
'page_template',
|
||||||
|
'post_author',
|
||||||
|
'post_name',
|
||||||
|
'category_title',
|
||||||
|
'category_slug',
|
||||||
|
];
|
||||||
|
|
||||||
|
const frontMatter = matter( fileContents, {
|
||||||
|
engines: {
|
||||||
|
// By passing yaml.JSON_SCHEMA we disable date parsing that changes date format.
|
||||||
|
// See https://github.com/jonschlinkert/gray-matter/issues/62#issuecomment-577628177 for more details.
|
||||||
|
yaml: ( s ) => yaml.load( s, { schema: yaml.JSON_SCHEMA } ),
|
||||||
|
},
|
||||||
|
} ).data;
|
||||||
|
|
||||||
|
return Object.keys( frontMatter )
|
||||||
|
.filter( ( key ) => allowList.includes( key ) )
|
||||||
|
.reduce( ( obj, key ) => {
|
||||||
|
obj[ key ] = frontMatter[ key ];
|
||||||
|
return obj;
|
||||||
|
}, {} );
|
||||||
|
};
|
|
@ -3,10 +3,15 @@
|
||||||
*/
|
*/
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import matter from 'gray-matter';
|
|
||||||
import { glob } from 'glob';
|
import { glob } from 'glob';
|
||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { generatePostFrontMatter } from './generate-frontmatter';
|
||||||
|
import { generateFileUrl } from './generate-urls';
|
||||||
|
|
||||||
interface Category {
|
interface Category {
|
||||||
[ key: string ]: unknown;
|
[ key: string ]: unknown;
|
||||||
posts?: Post[];
|
posts?: Post[];
|
||||||
|
@ -23,59 +28,28 @@ function generatePageId( filePath: string, prefix = '' ) {
|
||||||
return hash.digest( 'hex' );
|
return hash.digest( 'hex' );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a file url relative to the root directory provided.
|
|
||||||
*
|
|
||||||
* @param baseUrl The base url to use for the file url.
|
|
||||||
* @param rootDirectory The root directory where the file resides.
|
|
||||||
* @param subDirectory The sub-directory where the file resides.
|
|
||||||
* @param absoluteFilePath The absolute path to the file.
|
|
||||||
* @return The file url.
|
|
||||||
*/
|
|
||||||
export const generateFileUrl = (
|
|
||||||
baseUrl: string,
|
|
||||||
rootDirectory: string,
|
|
||||||
subDirectory: string,
|
|
||||||
absoluteFilePath: string
|
|
||||||
) => {
|
|
||||||
// check paths are absolute
|
|
||||||
for ( const filePath of [
|
|
||||||
rootDirectory,
|
|
||||||
subDirectory,
|
|
||||||
absoluteFilePath,
|
|
||||||
] ) {
|
|
||||||
if ( ! path.isAbsolute( filePath ) ) {
|
|
||||||
throw new Error(
|
|
||||||
`File URLs cannot be generated without absolute paths. ${ filePath } is not absolute.`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Generate a path from the subdirectory to the file path.
|
|
||||||
const relativeFilePath = path.resolve( subDirectory, absoluteFilePath );
|
|
||||||
|
|
||||||
// Determine the relative path from the rootDirectory to the filePath.
|
|
||||||
const relativePath = path.relative( rootDirectory, relativeFilePath );
|
|
||||||
|
|
||||||
return `${ baseUrl }/${ relativePath }`;
|
|
||||||
};
|
|
||||||
|
|
||||||
async function processDirectory(
|
async function processDirectory(
|
||||||
rootDirectory: string,
|
rootDirectory: string,
|
||||||
subDirectory: string,
|
subDirectory: string,
|
||||||
projectName: string,
|
projectName: string,
|
||||||
baseUrl: string,
|
baseUrl: string,
|
||||||
|
baseEditUrl: string,
|
||||||
checkReadme = true
|
checkReadme = true
|
||||||
): Promise< Category > {
|
): Promise< Category > {
|
||||||
let category: Category = {};
|
const category: Category = {};
|
||||||
|
|
||||||
// Process README.md (if exists) for the category definition.
|
// Process README.md (if exists) for the category definition.
|
||||||
const readmePath = path.join( subDirectory, 'README.md' );
|
const readmePath = path.join( subDirectory, 'README.md' );
|
||||||
|
|
||||||
if ( checkReadme && fs.existsSync( readmePath ) ) {
|
if ( checkReadme && fs.existsSync( readmePath ) ) {
|
||||||
const readmeContent = fs.readFileSync( readmePath, 'utf-8' );
|
const readmeContent = fs.readFileSync( readmePath, 'utf-8' );
|
||||||
const readmeFrontmatter = matter( readmeContent ).data;
|
const frontMatter = generatePostFrontMatter( readmeContent );
|
||||||
category = { ...readmeFrontmatter };
|
Object.assign( category, frontMatter );
|
||||||
category.posts = [];
|
} else if ( checkReadme ) {
|
||||||
|
// derive the category title from the directory name, capitalize first letter
|
||||||
|
const categoryTitle = path.basename( subDirectory );
|
||||||
|
category.category_title =
|
||||||
|
categoryTitle.charAt( 0 ).toUpperCase() + categoryTitle.slice( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
const markdownFiles = glob.sync( path.join( subDirectory, '*.md' ) );
|
const markdownFiles = glob.sync( path.join( subDirectory, '*.md' ) );
|
||||||
|
@ -84,7 +58,18 @@ async function processDirectory(
|
||||||
if ( filePath !== readmePath || ! checkReadme ) {
|
if ( filePath !== readmePath || ! checkReadme ) {
|
||||||
// Skip README.md which we have already processed.
|
// Skip README.md which we have already processed.
|
||||||
const fileContent = fs.readFileSync( filePath, 'utf-8' );
|
const fileContent = fs.readFileSync( filePath, 'utf-8' );
|
||||||
const fileFrontmatter = matter( fileContent ).data;
|
const fileFrontmatter = generatePostFrontMatter( fileContent );
|
||||||
|
category.posts = [];
|
||||||
|
|
||||||
|
if ( baseUrl.includes( 'github' ) ) {
|
||||||
|
fileFrontmatter.edit_url = generateFileUrl(
|
||||||
|
baseEditUrl,
|
||||||
|
rootDirectory,
|
||||||
|
subDirectory,
|
||||||
|
filePath
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const post: Post = { ...fileFrontmatter };
|
const post: Post = { ...fileFrontmatter };
|
||||||
|
|
||||||
category.posts.push( {
|
category.posts.push( {
|
||||||
|
@ -111,7 +96,8 @@ async function processDirectory(
|
||||||
rootDirectory,
|
rootDirectory,
|
||||||
subdirectory,
|
subdirectory,
|
||||||
projectName,
|
projectName,
|
||||||
baseUrl
|
baseUrl,
|
||||||
|
baseEditUrl
|
||||||
);
|
);
|
||||||
|
|
||||||
category.categories.push( subcategory );
|
category.categories.push( subcategory );
|
||||||
|
@ -124,13 +110,15 @@ export async function generateManifestFromDirectory(
|
||||||
rootDirectory: string,
|
rootDirectory: string,
|
||||||
subDirectory: string,
|
subDirectory: string,
|
||||||
projectName: string,
|
projectName: string,
|
||||||
baseUrl: string
|
baseUrl: string,
|
||||||
|
baseEditUrl: string
|
||||||
) {
|
) {
|
||||||
const manifest = await processDirectory(
|
const manifest = await processDirectory(
|
||||||
rootDirectory,
|
rootDirectory,
|
||||||
subDirectory,
|
subDirectory,
|
||||||
projectName,
|
projectName,
|
||||||
baseUrl,
|
baseUrl,
|
||||||
|
baseEditUrl,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a file url relative to the root directory provided.
|
||||||
|
*
|
||||||
|
* @param baseUrl The base url to use for the file url.
|
||||||
|
* @param rootDirectory The root directory where the file resides.
|
||||||
|
* @param subDirectory The sub-directory where the file resides.
|
||||||
|
* @param absoluteFilePath The absolute path to the file.
|
||||||
|
* @return The file url.
|
||||||
|
*/
|
||||||
|
export const generateFileUrl = (
|
||||||
|
baseUrl: string,
|
||||||
|
rootDirectory: string,
|
||||||
|
subDirectory: string,
|
||||||
|
absoluteFilePath: string
|
||||||
|
) => {
|
||||||
|
// check paths are absolute
|
||||||
|
for ( const filePath of [
|
||||||
|
rootDirectory,
|
||||||
|
subDirectory,
|
||||||
|
absoluteFilePath,
|
||||||
|
] ) {
|
||||||
|
if ( ! path.isAbsolute( filePath ) ) {
|
||||||
|
throw new Error(
|
||||||
|
`File URLs cannot be generated without absolute paths. ${ filePath } is not absolute.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Generate a path from the subdirectory to the file path.
|
||||||
|
const relativeFilePath = path.resolve( subDirectory, absoluteFilePath );
|
||||||
|
|
||||||
|
// Determine the relative path from the rootDirectory to the filePath.
|
||||||
|
const relativePath = path.relative( rootDirectory, relativeFilePath );
|
||||||
|
|
||||||
|
return `${ baseUrl }/${ relativePath }`;
|
||||||
|
};
|
Loading…
Reference in New Issue