Jump to content

Recommended Posts

Posted

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
Posted

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 ;)

Posted

Ok Antti, that's done, thank you. :)

For anyone really having trouble seeing how the tag parser works I suggest installing the helper module that allows you to play with the parser from a new page in the admin interface until you get the hang of it.

  • Like 1
Posted (edited)

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
Posted

Forgot to mention: you can do a PW style 'or' in the field part of the tag. Like this...

Look at the "{title|name|id}" page to...

Or this...

Hello {user.firstname|name>title}, ...
  • Like 2
Posted

Version 1.1.1 now available.

Just fixed a bug that occurred if multi-byte support was not installed on your host. (Thanks to renobird for finding that.)

  • Like 2
Posted

I've pushed some changes to the development branches of the TagParser and the ParserTester that add debug information and "global" transformations. The debug option can really help show what's going on behind the scenes. You'll need to grab both of the modules to use the new features.

  • 1 year later...
Posted (edited)

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
  • 2 weeks later...
Posted

Just bumped to v1.5.0 adding new transformations...

  • "nospaces" - Removes all spaces from a field.
  • "nl2br" - converts newlines to HTML breaks.
  • "nl2spaces" - converts newlines to ASCII spaces.
  • Like 3
  • 3 weeks later...
Posted
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
Posted

@ceberlin,

Thank you for letting me know. Could you try changing that line to...

if (isset($this->data['debug'])) {

... and let me know if that solves the issue for you.

  • Like 2
  • 2 weeks later...
Posted

Hi netcarver,

sorry for not replying earlier. I somehow overlooked it.

I tried your code update - and from my quick testing it seems to work fine now. Thank you very much!!!!

  • 10 months later...
  • 2 months later...
Posted

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
  • 8 months later...
Posted

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
Posted

Tom,

Can you try the branch, here? I think it might solve your sub-sub-field request. Not sure I fully understand your issue with the Field Change Notifier. Could you elaborate?

  • Like 2
Posted

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.

:)

  • 1 year later...
Posted

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

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
×
×
  • Create New...