5

I'm a software engineer with a WordPress site with hundreds of pages, and it's working very well.

There are certain cases, however, where I'd love to be able to code my own page with no interaction with / interference from the WordPress system (no themes, no styles, no javascript, etc) yet still have it located on that same subdomain.

How can I set https://example.com/special-page to display an HTML file uploaded somewhere within /wp-content/?

And as a bonus, I'd love if it would also work with a PHP file (which would generate the HTML).

I'd like to do this without manually editing the .htaccess file.

Here is an example that comes close:

The LeadPages WordPress plugin seems to do a variation of what I'm hoping for. It allows a user to specify a "slug" (relative path, such as special-page) and what content to display there. But the content needs to be hosted on LeadPages.net to use this plugin, obviously.

LeadPages plugin

What I'm hoping to do is host my own HTML file somewhere on my server (e.g. in a publicly-accessible folder such as /wp-content/) and then have a certain relative path point to it.

Look at this .htaccess file that I manually edited (and which works how I want):

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
Options +FollowSymLinks
DirectoryIndex /wp-content/raw/book-sale.html [L]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteRule ^thanks$ /wp-content/raw/book-opt-in-thank-you.html [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

I would have loved to have been able to specify from within the WordPress admin that the site root (/) should show the contents of /wp-content/raw/book-sale.html, and /thanks should show /wp-content/raw/book-opt-in-thank-you.html (so that I wouldn't need to go in an edit the .htaccess file directly.

5
  • It's not too tricky to do. Are you using your own theme? I'm trying to sleep at the moment but if no-one jumps in I'll try for an answer tomorrow. Jun 8, 2016 at 23:36
  • I could use a child theme to sort of "make" a theme into "mine" if that will allow me to do what you recommend. Thanks!
    – Ryan
    Jun 9, 2016 at 0:08
  • It would allow an approach where you create a Page with the URL you want, add your HTML file to the Page as an attachment and set a special page template that uses get_template_part() to pull in the attached file. Jun 9, 2016 at 0:13
  • Thanks. Perhaps you're talking about this? wordpress.stackexchange.com/a/128869/51462
    – Ryan
    Jun 9, 2016 at 0:35
  • 1
    That would need a template for each page. Where the HTML is in that answer, put in code to get the URL of the attached HTML file and then include it. However note the possible security risk of including files that an editor level user can upload. You needn't use a special template, just put a check for an HTML attachment in the theme's page.php. I do similar in front-page.php on some development sites to show a holding page to visitors who aren't logged in. Jun 9, 2016 at 0:40

3 Answers 3

1

If you're willing to create a child theme and put your PHP files in there, this approach is relatively clean. For each file, create a rewrite rule where you specify the path you want to use and the filename that should load. In the example below, /custom-path/ loads custom-file.php from the root of your child theme directory and /custom-path-2/ loads custom-file-2.php. Don't forget to flush permalinks after adding rewrites.

/*
 * Set up a rewrite for each path which should load a file.
 */
function my_standalone_rewrites() {
    add_rewrite_rule( '^custom-path/?', 'index.php?standalone=custom-file', 'top' );
    add_rewrite_rule( '^custom-path-2/?', 'index.php?standalone=custom-file-2', 'top' );
}
add_action( 'init', 'my_standalone_rewrites' );

/*
 * Make `standalone` available as a query var.
 */
function my_query_vars( $vars ) {
  $vars[] = 'standalone';
  return $vars;
}
add_filter( 'query_vars', 'my_query_vars' );

/*
 * If `standalone` is set when parsing the main query, load the standalone file.
 */
function my_standalone_path( &$wp_query ) {
    if ( $wp_query->is_main_query() && get_query_var( 'standalone', false ) ) {
        // Load filename.php from your child theme root.
        get_template_part( get_query_var( 'standalone' ) );
        exit;
    }
}
add_action( 'parse_query', 'my_standalone_path' );
0

You could create a page with the slug you want, and add a custom field that specifies the HTML path to output (in this example using either htmlfilepath or htmlurl as the metakey):

add_action('wp','maybe_direct_html_output');

function maybe_direct_html_output() {
    if (is_singular()) {
        global $post;
        $htmlfilepath = get_post_meta($post->ID,'htmlfilepath',true);
        if ( ($htmlfilepath) && (file_exists($htmlfilepath)) ) {
            echo file_get_contents($htmlfilepath); exit;
        }
        $htmlurl = get_post_meta($post->ID,'htmlurl',true);
        if ($htmlurl) {
            $html = wp_remote_get($html);
            if (!is_wp_error($html)) {echo $html['body']; exit;}
        }
    }
}

So no need for .htaccess when doing it this way... I just noticed you want to use wp-content so you could just use a relative path and simplify this to (using htmlfile metakey):

add_action('wp','maybe_direct_html_output');

function maybe_direct_html_output() {
    if (is_singular()) {
        global $post;
        $htmlrelpath = get_post_meta($post->ID,'htmlfile',true);
        if (!$htmlrelpath) {return;}
        $htmlfilepath = WP_CONTENT_DIR.$htmlrelpath;
        if (!file_exists($htmlfilepath)) {return;}
        echo file_get_contents($htmlrelpath); exit;
    }
}

Remembering that WP_CONTENT_DIR has no trailing slash so you would enter a relative path custom field value for the page such as /raw/book-sale.html

2
  • I hadn't heard of creating a custom field / metakey for posts, so that's something cool for me to look into. Where are you saying that I should put this add_action statement and function definition? Thanks.
    – Ryan
    Jun 9, 2016 at 4:37
  • probably best place for customizations like this as a standalone php file in the /wp-content/mu-plugins/ directory so WordPress will always autoload it and nothing breaks if you change themes... if you want to get more elaborate with the UI you can always create your own metabox for the field with a corresponding save action, or use advanced custom fields plugin, but otherwise the custom fields metabox is more than sufficient for this task.
    – majick
    Jun 9, 2016 at 4:55
0

For anyone with similar problem, this free plugin has been around for a long time and does partly what is asked here (it doesn't work with PHP files). It lets you create custom HTML pages that bypass WordPress's templating system and they are called by custom URIs. https://wordpress.org/plugins/wp-custom-html-pages/

  1. Look for WP Custom HTML Pages plugin on the repository, install and activate
  2. Under Pages menu in admin panel look for HTML Pages menu item
  3. Create any number of pages and assign them custom URI. The pages are made by adding code into Ace editor.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.