Search code examples
wordpresswordpress-rest-api

Creating page with custom url / meta tags using Wordpress REST API


I'm trying to create a custom page on my domain that has the url 'http://example.com/test/slug', however the slug does not seem to support slashes (the slug '/test/slug' turns into '/testslug'). Is it possible using the rest api to create a page on a custom url? Also, I populate the 'meta' dictionary, however the page created does not contain a meta 'description' tag in the header. How can I correctly create custom meta tags?

import requests

url = 'http://example.com/wp-json/wp/v2/pages'
data = {'content': '<h2>test content</h2>',
 'meta': {'description': 'this is a test meta field'},
 'slug': 'test/slug',
 'status': 'publish',
 'title': 'test title'}

resp = requests.post(url, json=data, auth=('user','pass'), headers={'Content-Type':'application/json'})

Solution

  • the slug does not seem to support slashes (the slug '/test/slug' turns into '/testslug').

    Yes, because whether you use the REST API or the admin UI for creating Pages, the slug is limited to alphanumeric characters, plus dashes (-) and underscores (_). See https://developer.wordpress.org/rest-api/reference/pages/#schema-slug.

    You can remove the limitation by adding remove_filter( 'sanitize_title', 'sanitize_title_with_dashes', 10, 3 ); to the theme's functions.php file (or a custom plugin); however, visiting the page (URL) would by default throw a 404 (not found) error. There are ways to fix that, but in short, you should not remove the filter.

    Is it possible using the rest api to create a page on a custom url?

    No it's not, not by default.

    However, if you want http://example.com/test/slug to serve/show a Page/Post/etc. be it created via the REST API or not, then you can use custom URL rewrite rules, e.g. via add_rewrite_rule().

    the page created does not contain a meta 'description' tag in the header. How can I correctly create custom meta tags?

    You need to register the meta key, which in your case is description.

    See

    And you can register it using the register_meta() function in wp-includes/meta.php.

    Example for your description meta:

    <?php
    // The object type. For custom post types, this is 'post';
    // for custom comment types, this is 'comment'. For user meta,
    // this is 'user'.
    $object_type = 'post'; // 'post' even for Pages
    $args1 = array( // Validate and sanitize the meta value.
        // Note: currently (4.7) one of 'string', 'boolean', 'integer',
        // 'number' must be used as 'type'. The default is 'string'.
        'type'         => 'string',
        // Shown in the schema for the meta key.
        'description'  => 'A meta key associated with a string meta value.',
        // Return a single value of the type.
        'single'       => true,
        // Show in the WP REST API response. Default: false.
        'show_in_rest' => true,
    );
    register_meta( $object_type, 'description', $args1 );
    

    To quickly test if the meta description was successfully registered and that it's being available from the REST API, perform a GET request to http://example.com/wp-json/wp/v2/pages/<id> where <id> is the Page ID.