Skip to content

Fix broken markdown URL for static front page#6

Closed
TBarregren wants to merge 1 commit intoProgressPlanner:mainfrom
TBarregren:fix/front-page-markdown-url
Closed

Fix broken markdown URL for static front page#6
TBarregren wants to merge 1 commit intoProgressPlanner:mainfrom
TBarregren:fix/front-page-markdown-url

Conversation

@TBarregren
Copy link

Summary

Fixes #5.

  • When a static page is set as the front page, get_permalink() returns the site root URL (e.g. https://example.com/). The existing rtrim('/') . '.md' logic produces an invalid URL like https://example.com.md.
  • This fix detects the front page case and generates /index.md instead. The slug is filterable via a new markdown_alternate_front_page_slug filter (default: "index").
  • Three locations are fixed: AlternateLinkHandler::output_alternate_link(), RewriteHandler::handle_accept_negotiation(), and RewriteHandler::parse_markdown_url().

Test plan

  • Set a static page as the front page (Settings → Reading)
  • Visit the front page and inspect the HTML <head> — verify the <link rel="alternate"> points to /index.md (not example.com.md)
  • Visit /index.md directly — verify it serves the front page as markdown
  • Send a request with Accept: text/markdown to the front page — verify it redirects to /index.md
  • Verify existing .md URLs for regular posts/pages still work
  • Test the markdown_alternate_front_page_slug filter to change "index" to e.g. "home"

🤖 Generated with Claude Code

When a static page is set as the front page, get_permalink() returns
the site root URL (e.g. https://example.com/). The existing code
strips the trailing slash and appends .md, producing an invalid URL
like https://example.com.md.

This fix detects the front page case and uses /index.md instead.
The slug is filterable via 'markdown_alternate_front_page_slug'.

Affected locations:
- AlternateLinkHandler: <link rel="alternate"> tag generation
- RewriteHandler: Accept header content negotiation redirect
- RewriteHandler: REQUEST_URI parsing for /index.md routing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jdevalk
Copy link
Member

jdevalk commented Feb 15, 2026

@ilicfilip could you see if this or #8 is the better approach?

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a bug where static front pages produce invalid markdown URLs (e.g., https://example.com.md instead of https://example.com/index.md). The issue occurs because get_permalink() returns the site root URL for the front page, and appending .md after stripping the trailing slash creates a malformed URL.

Changes:

  • Added front page detection logic using URL comparison in three locations
  • Introduced a new filterable slug markdown_alternate_front_page_slug (default: "index") for the front page markdown URL
  • Extracted URL building logic into a private method in AlternateLinkHandler

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.

File Description
src/Discovery/AlternateLinkHandler.php Added build_markdown_url() method to detect front pages and generate appropriate markdown URLs
src/Router/RewriteHandler.php Added front page detection in parse_markdown_url() to route /index.md to the front page, and in handle_accept_negotiation() to generate correct redirect URLs

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

// Build markdown URL — detect front page to avoid invalid domain.md URL.
$site_url = trailingslashit(home_url());
if (trailingslashit($canonical) === $site_url) {
$front_slug = apply_filters('markdown_alternate_front_page_slug', 'index');
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The coding style here is inconsistent with the rest of the RewriteHandler.php file. This file uses no spaces inside function call parentheses (e.g., line 157: apply_filters('markdown_alternate_supported_post_types', $default_types)), but this line has spaces. For consistency with the existing code in this file, this should be apply_filters('markdown_alternate_front_page_slug', 'index') without spaces.

Copilot uses AI. Check for mistakes.
$slug = $matches[1];

// Check if this is the front page slug (default "index", filterable).
$front_slug = apply_filters('markdown_alternate_front_page_slug', 'index');
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The filter output should be sanitized before use to prevent potential security issues. Consider using sanitize_title() or at minimum validating that the slug contains only safe URL characters. This prevents malicious or malformed slugs from being used in URL construction, even though the impact is limited since WordPress will ultimately handle the URL.

Suggested change
$front_slug = apply_filters('markdown_alternate_front_page_slug', 'index');
$front_slug = apply_filters('markdown_alternate_front_page_slug', 'index');
// Ensure the filtered slug is safe before using it in routing logic.
if (!is_string($front_slug)) {
$front_slug = 'index';
} elseif (!preg_match('/^[A-Za-z0-9\-._~\/]+$/', $front_slug)) {
// Fallback to a safe default if the slug contains unexpected characters.
$front_slug = 'index';
}

Copilot uses AI. Check for mistakes.
Comment on lines +103 to +105
// Detect if this is the static front page by comparing to site URL.
$site_url = trailingslashit( home_url() );
if ( trailingslashit( $permalink ) === $site_url ) {
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using a more direct approach to detect the front page by comparing post IDs instead of URLs. This would be more reliable and clearer. For example: if ((int) get_option('page_on_front') === $post->ID && get_option('show_on_front') === 'page'). This approach avoids potential edge cases with URL formatting and is more explicit about checking the WordPress front page setting.

Suggested change
// Detect if this is the static front page by comparing to site URL.
$site_url = trailingslashit( home_url() );
if ( trailingslashit( $permalink ) === $site_url ) {
// Detect if this is the static front page using WordPress front page settings.
$is_static_front_page = (
get_option( 'show_on_front' ) === 'page'
&& (int) get_option( 'page_on_front' ) === (int) $post->ID
);
if ( $is_static_front_page ) {
$site_url = trailingslashit( home_url() );

Copilot uses AI. Check for mistakes.
Comment on lines +350 to +357
// Build markdown URL — detect front page to avoid invalid domain.md URL.
$site_url = trailingslashit(home_url());
if (trailingslashit($canonical) === $site_url) {
$front_slug = apply_filters('markdown_alternate_front_page_slug', 'index');
$md_url = $site_url . $front_slug . '.md';
} else {
$md_url = rtrim($canonical, '/') . '.md';
}
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using a more direct approach to detect the front page. Since this code runs during template_redirect (when WordPress query is available), you could use is_front_page() to check if the current page is the front page, which would be clearer and more reliable than URL comparison. This would also be consistent with WordPress conventions for front page detection.

Copilot uses AI. Check for mistakes.
// Detect if this is the static front page by comparing to site URL.
$site_url = trailingslashit( home_url() );
if ( trailingslashit( $permalink ) === $site_url ) {
$front_slug = apply_filters( 'markdown_alternate_front_page_slug', 'index' );
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The filter output should be sanitized before use in URL construction. Consider using sanitize_title() to ensure the slug contains only safe URL characters. This prevents potential security issues from malicious filter values and ensures the generated URL is well-formed.

Suggested change
$front_slug = apply_filters( 'markdown_alternate_front_page_slug', 'index' );
$front_slug = apply_filters( 'markdown_alternate_front_page_slug', 'index' );
$front_slug = sanitize_title( (string) $front_slug );
if ( $front_slug === '' ) {
$front_slug = 'index';
}

Copilot uses AI. Check for mistakes.
// Build markdown URL — detect front page to avoid invalid domain.md URL.
$site_url = trailingslashit(home_url());
if (trailingslashit($canonical) === $site_url) {
$front_slug = apply_filters('markdown_alternate_front_page_slug', 'index');
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The filter output should be sanitized before use in URL construction. Consider using sanitize_title() to ensure the slug contains only safe URL characters. This prevents potential security issues from malicious filter values and ensures the generated URL is well-formed.

Suggested change
$front_slug = apply_filters('markdown_alternate_front_page_slug', 'index');
$front_slug = apply_filters('markdown_alternate_front_page_slug', 'index');
$front_slug = sanitize_title($front_slug);

Copilot uses AI. Check for mistakes.
$slug = $matches[1];

// Check if this is the front page slug (default "index", filterable).
$front_slug = apply_filters('markdown_alternate_front_page_slug', 'index');
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The coding style here is inconsistent with the rest of the RewriteHandler.php file. This file uses no spaces inside function call parentheses (e.g., line 157: apply_filters('markdown_alternate_supported_post_types', $default_types)), but this line has spaces. For consistency with the existing code in this file, this should be apply_filters('markdown_alternate_front_page_slug', 'index') without spaces.

Copilot uses AI. Check for mistakes.
@jdevalk
Copy link
Member

jdevalk commented Feb 17, 2026

Thanks for this fix — this appears superseded by #8 (same static front-page markdown URL area) and is currently conflicting with main. Closing to reduce overlap and keep one active path for this fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Static front page produces invalid .md URL (e.g. example.com.md)

2 participants

Comments