Jump to content

TextformatterTagParser


netcarver
 Share

Recommended Posts

I found the parseTags() routine from Ryan's Login Notify plugin pretty useful in a couple of modules I wrote recently and will probably reuse it again in other modules. I thought others might find it useful too, especially if it were slightly more flexible in the setup of the context from which it pulled the values to use in its substitutions so I rewrote it as a Textformatter.

Originally parseTags() would turn something like this...

"Date: {datetime}\nUser: {name}\nIP: {REMOTE_ADDR}"


…into something like this…

Date: 12th September 2012, 14:45
User: ryan
IP: 127.0.0.1


...using a User as the context for the substitutions.

This text formatter extends this to allow an array of WireData instances to be used as the context for substitutions and extends the tag format from simply {fieldname} to {context.fieldname} to allow substitutions from specific places. This could allow you to use data from, say, a User and a Page when parsing your string. Something more complex can then be parsed successfully; like this...

Hello {user.name}, where have you been? It's {datetime} now and we haven't seen you in two weeks.

Your last edit was on page '{page.name}' from address {REMOTE_ADDR}


...where the name field from both the supplied User and Page can be substituted into the text.

It's entered in the modules directory here but most of the documentation is in the readme file on github. There is also a handy Process module that allows you to experiment with it from within the PW admin (thanks to Nik for the idea as it's based on his Test Selectors module.)
  • Like 11
Link to comment
Share on other sites

Great module Steve! On suggestion for documentation (it took my few reads to understand how it works). In this full example:

$body = "...";    // Setup the email body template
$subject = "..."; // Setup the email subject template
$parser = wire()->modules->get("TextformatterTagParser");
$parser
   ->set('context', $user)
   ->format($subject)
   ->format($body)
   ;
$sent = @email($user->email, $subject, $body);

I would show those subject and body lines too:

$body = "Hi {firstname} and welcome to our service. You can login using your username {name} and password.";    // Setup the email body template
$subject = "Welcome {name}"; // Setup the email subject template
$parser = wire()->modules->get("TextformatterTagParser");
$parser
   ->set('context', $user)
   ->format($subject)
   ->format($body)
   ;
$sent = @email($user->email, $subject, $body);

Above example is written assuming I did understaad how it should work ;)

Link to comment
Share on other sites

Bumped to version 1.1.0 with the addition of tag transformations. You can now do things like making a user's name all uppercase...

Hello {user.name>upper}, how are you?

You can choose 'upper', 'lower', 'title', 'strip', 'base64' or 'url' transformations on any tag. They can also be chained like so...

http://blahblahblah.com/index.html?p={page.title>lower>url}

Which would first lower the case of the page title and then url encode it.

Edited by netcarver
  • Like 1
Link to comment
Share on other sites

  • 1 year later...

Added new transforms...

  • "initial" - Pulls the initial letter of the first word of the field.
  • "initcap" - Pulls the initial letter of the field, capitalises it and appends '.'
  • "initials" - Pulls the initial letters of words of the field.
  • "initcaps" - Pulls the initial letters of words of the field, capitalised and postfixed with '.'
  • "thinspaces" - Replaces multiple spaces with a single space.
  • (integer) n - Selects the nth word of the field.

Also fixed a PHP notice.

Edited by netcarver
  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...
  • 3 weeks later...
Just a quick note:

On LOGIN ERROR (im my case a Session Throttle interception) the module sends a list of notices for the login screen:

Notice: Undefined index: debug in /.../site/modules/TextformatterTagParser/TextformatterTagParser.module on line 207

  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...
  • 10 months later...
  • 2 months later...

Folks,

I just uploaded a new test branch for this module to github that adds the ability to spit out alternative texts on each parse. The idea comes from products like spintex and allows you to use one text block to generate different output on every view.

Basically you write stuff like "Dear {{mum|dad|grandma|grandpa|Ryan}}, ..." and the textformatter makes a choice from the listed alternates at every point in your text. You can control the degree of randomness and I'm playing with setting it based on a cleaned up version of the referrer URL to make visits from different places have different versions of the text but repeated visits from the same place see a consistent version of the text. In other words, people coming from google will see something like "Dear dad, ..." each time they visited whilst those from Yahoo would see "Dear Ryan, ..." when they visited the very same URL (at least, that's the plan.)

  • Like 2
Link to comment
Share on other sites

  • 8 months later...

Hey Steve,

I haven't had a chance to look into to the test branch, but that would be a cool feature. 

One thing that I've run into a few times is when using Field Change Notifier is that when it's watching a page field the value is parsed as the page id. 

Would it be possible to look into adding support for sub-subfields?

Examples:

{page.page_field.title}

{page.page_field.id}

{page.page_field.summary}

or any other field associated with that page?

I modified my local version of Tag Parser to always use $page->title, but there are also times that I need it to send $page->id.

  • Like 1
Link to comment
Share on other sites

Thanks Steve! 

The update seems to be working great!

There's really no issue with FCN, it was more that I needed the Tag Parser to populate the notification emails with things like:

page.myPageField.title

page.myPageField.expiration

This update makes that possible.

:)

Link to comment
Share on other sites

  • 1 year later...

Just pushed version 2.1.0. By default, the module will set up the current page as the 'page' context and the page's parent as the 'parent' context. This allows you to access any field of the current page or the parent of the current page by default.

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...