Jump to content
qwertyeee

Fieldtype, formatValue (Page $page, Field $field, $value), add javascript.

Recommended Posts

hi all. Is for example

class Fieldtypetest extends Fieldtype {

}

when it is displayed in the template page

echo "{$ page-> testField}";

need to include javascript file and add something to the value

I try to do so:

class Fieldtypetest extends Fieldtype {

    public function formatValue (Page $page, Field $field, $value)

    {

        $this->config->scripts->add($this->config->urls->Fieldtypetest. "test_js.js");

        return '<div>'.$value.'</div>';

    }

}

*

( $this->config->urls->Fieldtypetest - have correct value )

But it does not work, javascript not included.

Please tell me how to correctly include the required javascript and add something to value, such as 

'<div>'. $ value. '</ div>';  for example.

Share this post


Link to post
Share on other sites

Welcome to the forums Queryeee. I'm glad to see you experimenting with Fieldtypes. Your formatValue() function looks correct. Though you are using it in a different way than I've seen before. So I wanted to pass along some info that I thought might help in the context you are using it. First off, I would suggest that you post your entire Fieldtypetest class, because I want to make sure the other prerequisites are accounted for.

Fieldtypes define database schema for a type of field, they identify an Inputfield to handle input, they sleep and wake values for going to/from the database, and they handle sanitization and formatting of their type of values for pages. I want to make sure that your Fieldtype is covering these areas, because it may not work otherwise.

When you create a new Fieldtype, you should capitalize the "test" part, like FieldtypeTest rather than Fieldtypetest. When you've successfully created a new Fieldtype module, you have to install it in Admin > Modules. Then you have to create a new field in Admin > Setup > Fields, and choose "test" as your fieldtype. Then you'll add that field to one or more templates, making it apply to any pages using those templates. I'm going to assume you already know all this, but I wanted to mention it just in case.

Fieldtypes can optionally specify a formatValue() function to handle runtime formatting. Most fields don't use it, but some do. Examples of fields that use it are text fields where you've added markdown or entity encoding formatters to it. And date fields also use outputFormatting to show formatted dates when it's ON and unix timestamps when it's OFF. The formatValue function is triggered every time you call $page->testField (or any field) and $page->outputFormatting == true. By default, $page->outputFormatting is always TRUE in your web site, so you don't have to think about it unless you need an unformatted value. However, if you are using the API from admin modules or command line scripts, then $page->outputFormatting is FALSE by default.

For fields where it matters, you want outputFormatting to be TRUE when you are outputting values for presentation to a web site, but you want it to be FALSE when you are manipulating those values and saving pages. So for those fields, if you try to modify their value on a page when outputFormatting is TRUE, and then try to save the page ($page->save), ProcessWire will throw a fatal error to prevent you from corrupting the data. Why? If it didn't, then you might end up saving values to your page that have runtime formatters applied to them... so the next time you view that page, you'd have double-formatted values, i.e. two <div> tags rather than one, in your case. Luckily, ProcessWire prevents you from doing that.

You can set whether outputFormatting is on or off for any page by calling:

$page->setOutputFormatting(true or false);  

If you aren't seeing your <div>...</div> in your $page->testValue, then I'm guessing that $page->outputFormatting is FALSE in the place where you are using it. If you want to confirm, you can do this:

echo $page->outputFormatting ? "ON" : "OFF"; 

However, if you are doing this from one of your site templates, it is going to be ON unless you've specifically turned it off. So if that is the context you are in, then I'm also confused why you aren't seeing your value with the <div></div> between it... and why I think it may be a good idea to post the class file here (or email to me if you prefer).

Next, lets look at: $this->config->scripts->add(...)

ProcessWire admin uses that a lot so that markup generating modules (Inputfield and Process) can tell it what scripts to load in the admin template. If you look at /wire/templates-admin/default.php, you'll see something like this in the <head> section:

<?php 

foreach($config->styles->unique() as $file) 
    echo "\n\t<link type='text/css' href='$file' rel='stylesheet' />"; 

foreach($config->scripts->unique() as $file) 
    echo "\n\t<script type='text/javascript' src='$file'></script>";

?>

ProcessWire can do this because it's for it's own use, in the admin panel. But it won't make any assumptions about your own templates. It doesn't know or care what you are doing with your own templates, so it's not going to output <script> tags. As a result, if you want to use $config->scripts or $config->styles, then your template will have to do something like the above. And it's perfectly fine to use $config->scripts and $config->styles, that's what they are there for.

If you want that script included without your template having to account for it, then I would suggest doing it inline. So your formatValue function would include the <script src='...'></script> tag directly in the returned value, after the </div>. I know that inline scripts are not a best practice in regular markup, but that is in lieu of other factors. if you are trying to build a self-contained Fieldtype that needs to output markup, and you don't want to have to add markup anywhere else, then it would be acceptable to output the <script> tag as part of your value.

Share this post


Link to post
Share on other sites

I installed it and tested it – very cool! It looks like you already know how this all works. And it looks like your Fieldtype is nearly functional on the front end too. This helps me to see what you are doing, and I should be able to answer any questions you have more easily now. Actually I've been wanting to make a Google Maps fieldtype, so am happy you are making one already. Just let me know if there is anything I can do to help.

Thanks,

Ryan

Share this post


Link to post
Share on other sites

I forgot, in site/templates/head.inc need add this

<script type='text/javascript' src='/wire/modules/GMap/scripts/GMap2.js'></script>

<script type='text/javascript' src='/wire/modules/GMap/scripts/FieldtypeGMap.js'></script>

Share this post


Link to post
Share on other sites

Great it looks like it works for me once I added those! Cool fieldtype.

My computer doesn't recognize something about the language/localization, as all the buttons are a series of question marks. But I think that's just because my computer must not have that language installed.

I'm wondering if it would still work if you output those two scripts from your formatValue function, since you are already outputting an inline script there? Though it may be that Google Maps requires it to be loaded in the <head> section, I'm not sure.

Also, I recommend placing your GMap module in /site/modules/ rather than /wire/modules/. This is because /site/modules/ is for user-installed Fieldtypes, whereas /wire/modules/ is for Fieldtypes that are permanent. When you upgrade ProcessWire, you replace the entire /wire/ dir, so you don't want to put anything custom in there. Whereas everything in /site/ is custom to your site, so any modules you put into /site/modules/ won't get overwritten when you upgrade ProcessWire.

Share this post


Link to post
Share on other sites

I think you are doing a great job of understanding this stuff. I haven't actually written the documentation for fieldtypes and inputfields, so I'm impressed that you seem to have figured this out on your own.

Share this post


Link to post
Share on other sites

Also, I recommend placing your GMap module in /site/modules/ rather than /wire/modules/.

Little offtopic: Just a thought, but maybe there should be an empty folder in place when you install pw? Just created blanko site and installed AdminBar (for first time actually), and I had to think for few minutes that where I put the files :)

Qwertyeee: Welcome to the forums! Looks like a very useful fieldtype. Just quickly tested it and same ????? chars on my map also.

Share this post


Link to post
Share on other sites

Strangely, there is a /site/modules/ in the master copy of my default site profile. But you are right that the dir doesn't exist in the git clone or the installation zip. I'm wondering if Git is ignoring it because it's empty... if need be I'll put a "hello world" module in there as a placeholder.

Share this post


Link to post
Share on other sites

Strangely, there is a /site/modules/ in the master copy of my default site profile. But you are right that the dir doesn't exist in the git clone or the installation zip. I'm wondering if Git is ignoring it because it's empty... if need be I'll put a "hello world" module in there as a placeholder.

Ah, ok. That could be nice fix, also because putting hello world there will guide to write own modules in that dir instead on /wire/modules/.

Share this post


Link to post
Share on other sites

I also need to make a new HelloWorld module to put in there too. The one that comes with it now is kind of specific to the Skyscrapers profile, which isn't used by many people.

Share this post


Link to post
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

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...