Go to main content

Textpattern CMS support forum

You are not logged in. Register | Login | Help

#1 2021-06-30 14:29:34

jakob
Admin
From: Germany
Registered: 2005-01-20
Posts: 4,596
Website

non-htaccess redirect using pretext callback [SOLVED]

I’m trying to move some redirects previously done using .htaccess to Textpattern’s internal url-handling routine. On the whole it works well and makes the code more portable between apache and nginx-based environments, but I’ve come across a special case when outputting a form using the ?f=form-name method added in Textpattern 4.8 (I think).

I have it nearly working but a couple of environment variables and plugin-loaded site variable prefs are not being processed.

What I’m trying to achieve:

/domain.com/news-feed -> /domain.com/?f=news_rss_feed
/domain.com/sitemap.xml -> /domain.com/?f=sitemap_xml

The two forms are in a custom feed form type set to mediatype="application/xml" in Admin › Preferences › Advanced options.

The forms work correctly using the messy urls.

This is the basic plugin code (plugin load order is set to 4) using the same output_component() method as used index.php:

<?php
if (defined('txpinterface') && txpinterface == 'public') {
  // callback for custom url handling
  register_callback('mw_feed_handler', 'pretext', '');
}

function mw_feed_handler()
{
  global $pretext;
  if ($pretext[1] === "news-feed") {
    // output feed form 'news_rss_feed'
    $pretext['skin'] = 'theme-name';
    $pretext['pg'] = '';
    output_component('news_rss_feed');
    die(); // stop 404 page being output
  } else if ($pretext[1] === "sitemap.xml") {
    // output 'sitemap_xml' form
    $pretext['skin'] = 'theme-name';
    $pretext['pg'] = '';
    output_component('sitemap_xml');
    die(); // stop 404 page being output
  }
}

The redirects work but produces missing array errors unless I add the respective $pretext[‘…‘] array items. However, I have some variables that are set using oui_prefs (e.g. canonical_url) that don’t appear via the redirect but do using the regular ?f=news_rss_feed method.

What am I doing wrong?


TXP Builders – finely-crafted code, design and txp

Offline

#2 2021-06-30 15:05:44

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 11,271
Website GitHub

Re: non-htaccess redirect using pretext callback [SOLVED]

I’ve not tried it but does it work if you do it pre-pretext?

register_callback('mw_feed_handler', 'pretext', 1);

The smd plugin menagerie — for when you need one more gribble of power from Textpattern. Bleeding-edge code available on GitHub.

Txp Builders – finely-crafted code, design and Txp

Offline

#3 2021-06-30 16:10:29

etc
Developer
Registered: 2010-11-11
Posts: 5,053
Website GitHub

Re: non-htaccess redirect using pretext callback [SOLVED]

jakob wrote #330822:

The redirects work but produces missing array errors unless I add the respective $pretext[‘…‘] array items. However, I have some variables that are set using oui_prefs (e.g. canonical_url) that don’t appear via the redirect but do using the regular ?f=news_rss_feed method.

You are probably calling it too early, try to register it on pretext_end. Also, rather than intercepting the workflow, you can try to set global $f and leave the hand to txp.

Offline

#4 2021-06-30 16:11:13

jakob
Admin
From: Germany
Registered: 2005-01-20
Posts: 4,596
Website

Re: non-htaccess redirect using pretext callback [SOLVED]

Bloke wrote #330825:

register_callback('mw_feed_handler', 'pretext', 1);...

With that I get a straight 404 error page, but in my notes I have it should be register_callback('mw_feed_handler', 'pretext', '', 1); (my notes could be wrong, though). Using the latter I get two Warning: Undefined array key 1 at line… – which correspond to the $pretext[1] === lines – and a 404 error page, which presumably means that pre-pretext means I have to use another method to rewrite the URL … ?


TXP Builders – finely-crafted code, design and txp

Offline

#5 2021-06-30 16:21:05

etc
Developer
Registered: 2010-11-11
Posts: 5,053
Website GitHub

Re: non-htaccess redirect using pretext callback [SOLVED]

jakob wrote #330830:

pre-pretext means I have to use another method to rewrite the URL … ?

Pre-pretext callbacks are mainly meant for $_SERVER rewrites and other holly hacks. You can try to rewrite $_SERVER['REQUEST_URI'] and $_SERVER['QUERY_STRING'] and let txp do the rest.

Edit: you will need to set the plugin load order to something lower than 5.

Offline

#6 2021-06-30 16:35:15

jakob
Admin
From: Germany
Registered: 2005-01-20
Posts: 4,596
Website

Re: non-htaccess redirect using pretext callback [SOLVED]

etc wrote #330829:

You are probably calling it too early, try to register it on pretext_end. Also, rather than intercepting the workflow, you can try to set global $f and leave the hand to txp.

Not sure if I understand quite how to do that, but if I try this:

<?php
if (defined('txpinterface') && txpinterface == 'public') {
  // callback for custom url handling
  register_callback('mw_feed_handler', 'pretext_end');  // same with … , '', 1)
}

function mw_feed_handler()
{
  global $f, $pretext;
  if ($pretext[1] === "news-feed") {
    // output feed form 'news_rss_feed'
    $f = 'news_rss_feed';
  } else if ($pretext[1] === "sitemap.xml") {
    // output 'sitemap_xml' form
    $f = 'sitemap_xml';
  }
}

I just get a 404 error page. A dmp($f); shows the correct form and if I add output_component($f); die(); I get my output but still missing the variables loaded via the plugin.


TXP Builders – finely-crafted code, design and txp

Offline

#7 2021-06-30 17:00:50

etc
Developer
Registered: 2010-11-11
Posts: 5,053
Website GitHub

Re: non-htaccess redirect using pretext callback [SOLVED]

Almost there, but it must be $pretext['f'] instead of $f, sorry. Also, set $pretext['status'] = 200, for good measure.

Offline

#8 2021-06-30 17:06:48

jakob
Admin
From: Germany
Registered: 2005-01-20
Posts: 4,596
Website

Re: non-htaccess redirect using pretext callback [SOLVED]

etc wrote #330834:

Almost there, but it must be $pretext['f'] instead of $f, sorry. Also, set $pretext['status'] = 200, for good measure.

That’s it! Thank you!

This is working nicely [EDIT: see below for a more elegant solution]:

<?php
if (defined('txpinterface') && txpinterface == 'public') {
  // callback for custom url handling
  register_callback('mw_feed_handler', 'pretext_end');
}

function mw_feed_handler()
{
  global $pretext;
  if ($pretext[1] === "news-feed") {
    // output feed form 'news_rss_feed'
    $pretext['f'] = 'news_rss_feed';
  } else if ($pretext[1] === "sitemap.xml") {
    // output 'sitemap_xml' form
    $pretext['f'] = 'sitemap_xml';
  }
  $pretext['status'] = 200;
}

Also sits nicely alongside another url handling $pretext callback.


TXP Builders – finely-crafted code, design and txp

Offline

#9 2021-06-30 17:43:28

etc
Developer
Registered: 2010-11-11
Posts: 5,053
Website GitHub

Re: non-htaccess redirect using pretext callback [SOLVED]

Fine, but this unconditional $pretext['status'] = 200 could break txp error handling.

You could set some

$forms = array(
    'news-feed' => 'news_rss_feed',
    'sitemap.xml' => 'sitemap_xml'
);

and check

if (isset($forms[$pretext[1]]) {
    $pretext['f'] = $forms[$pretext[1]];
    $pretext['status'] = 200;
}

Offline

#10 2021-06-30 17:45:32

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 11,271
Website GitHub

Re: non-htaccess redirect using pretext callback [SOLVED]

jakob wrote #330830:

in my notes I have it should be register_callback('mw_feed_handler', 'pretext', '', 1);

Yes, sorry. handler, event, step, pre: in that order.

But it seems that’s not the way to go anyway so I’m glad Oleg was here to show you the correct way to do it :)


The smd plugin menagerie — for when you need one more gribble of power from Textpattern. Bleeding-edge code available on GitHub.

Txp Builders – finely-crafted code, design and Txp

Offline

#11 2021-06-30 18:10:07

jakob
Admin
From: Germany
Registered: 2005-01-20
Posts: 4,596
Website

Re: non-htaccess redirect using pretext callback [SOLVED]

etc wrote #330838:

Fine, but this unconditional $pretext['status'] = 200 could break txp error handling.

Got it. I put that line back inside each conditional, but …

You could set some … and check …

… your solution is so much more elegant :-)

<?php
if (defined('txpinterface') && txpinterface == 'public') {
  // callback for custom url handling
  register_callback('mw_feed_handler', 'pretext_end');
}

// Access '/?f=form_name' links via a clean url
function mw_feed_handler()
{
  global $pretext;

  // 'clean-url' => 'form_name'
  $forms = array(
    'news-feed' => 'news_rss_feed',
    'sitemap.xml' => 'sitemap_xml'
  );

  if (isset($forms[$pretext[1]])) {
    $pretext['f'] = $forms[$pretext[1]];
    $pretext['status'] = 200;
  }
}

Thanks again. The ability to rewrite the parts of $pretext using the regular ‘pretext’ callback is already a fairly straightforward way to replace the humungous gbp_permanent_links with just a few lines of specific instructions. This simple, extendable solution for those former “rah_eo” instances makes it possible to make certain forms accessible via a clean url.


TXP Builders – finely-crafted code, design and txp

Offline

#12 2021-06-30 21:00:06

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 11,271
Website GitHub

Re: non-htaccess redirect using pretext callback [SOLVED]

That’s really cool. I learned something today.

I wonder if a similar technique could be used to help Kjeld with his article list from custom fields conundrum? i.e. palm off /location/{something} to a form, whose content then does the appropriate <txp:article_(custom)> call to fetch the matching content to display.


The smd plugin menagerie — for when you need one more gribble of power from Textpattern. Bleeding-edge code available on GitHub.

Txp Builders – finely-crafted code, design and Txp

Offline

Board footer

Powered by FluxBB