1

I'm having trouble with using PHP code on my pages, within my body content area. I've searched tirelessly on this site, Drupal's site, and other sites in general, so I apologize if the answer is on this site somewhere, but I can't find it and I need help.

We have a lot of info we reuse throughout our site that I'd like to store in a PHP file as variables. We do this on our site now, but I'm rewriting our whole site to use Drupal. So, for example, we sell software, and I'd like a variable for each of our product URLs for various 'add to cart' buttons on the site. I don't want to have to hardcode the product URL into each link, but rather to seta PHP variable that I can call on any drupal page.

I cannot get anything to work; I've read about several suggestions but none work. I've tried setting the variables as their own block, then calling them from within a page when I create a new page. I can echo the variables on the pages but only within the block they are inside, I cannot call them and get them to echo from other blocks or content areas. I've tried using the global keyword (as per one suggestion) but that didn't work for me.

I hope this makes sense. Other info? I'm using Drupal 6.x, I do have PHP code enabled when creating pages, I do have the PHP filter module enabled, I can get PHP code to render so I know it's working, it's just not working where I need it to be.

I should say (if it's not obvious just from reading this!) I am a Drupal newbie so if anyone can help and try to explain their suggestion as plainly as possible for me, I'd really appreciate it!

Thanks in advance.

EDIT 3/15/11

To try to explain further, I'll post some sample code. I haven't done this yet because there isn't much to show yet, and I thought it might confuse the issue even more.

So, I've made a Drupal 'page' which is for our software trial downloads. The PHP variables that I want to set are for our download links; I want to set them in one place so that if, in the future, the download link needs to change, I only have to do so in one spot. You see, we have download links on various site pages. The same is true of our 'buy now' links. Here is the page code:

<p>Try [product] free for 30 days.</p>

<!--<p>[token_custom_ewintry]</p>-->

<p><?php global $ewintry; ?><a href="<?php print $ewintry; ?>">Download for Windows PC</a></p>

<p><?php global $emactry; ?><a href="<?php print $emactry; ?>">Download for Mac OS X</a></p>

<p><?php global $ebbtry; ?><a href="<?php print $ebbtry; ?>">Download for   BlackBerry</a></p>


<?php 
$ebbtryprint = variable_get("ebbtry", "default");
print $ebbtryprint;
?>

<p><a href="<?php print $ewmtry; ?>">Download for Windows Mobile</a></p>

<p><?php global $ipewlstorelink; ?>iPhone, iPad, iPod touch owners: <a href="<?php print $ipewlstorelink; ?>">Download [product] on the iTunes App Store</a>. You'll be able to create 10 cards for free to try [product] before you buy!</p>

For this sample I've left in everything I've tried. You'll see my calls to global variables, which never worked. I have the global variables defined in a custom block that I created and placed in my 'content top' region. I learned that apparently nothing from that region is actually accesible to my page's body content, because the calls never worked.

I have a custom token that I made yesterday with the Tokens module; it never worked, but then I read on a different post that by default, tokens are available in the body content area, and I need a special filter. I've yet to find a filter, and so I am not sure this solution will ever work.

I have my call to variable_get. Now, this did work. I have variable_set defined within my template.php page. My value does print using the print call above in my code sample. However, I looked at this page this morning and I don't think that's the answer I need. Because now I'll have to call variable_get on all my pages before I can print anything, right? And that doesn't solve the problem where I wanted to only have to set everything in one place to call anywhere. I tried putting the variable_get call in my custom block, but again I can't access anything in 'content top' from my body content area. The variable_get call prints the value in 'content top' but then it will not re-print below that in the content area.

So maybe that code will help someone to help me. I am going to look in detail at CCK now, as that's the only other suggestion I haven't tried. Thanks in advance if anyone can help.

apaderno
  • 28,547
  • 16
  • 75
  • 90
Julie
  • 11
  • 1
  • 3
  • 1
    You need to post your code, or at least some samples of it. – Jared Farrish Mar 14 '11 at 14:44
  • 2
    Maybe it's time to rethink how you're app is put together, it's called refactoring and it looks to me that you badly need to do so . Global variables in php are concidered a bad practice http://blog.case.edu/gps10/2006/07/22/why_global_variables_in_php_is_bad_programming_practice . In some cases you could use constants, maybe static class variables would be a better choice ? not realy shure but it looks like you badly need to document you're self on how Drupal handles such things and just "go with the flow" to preserve standards . – Poelinca Dorin Mar 14 '11 at 14:52
  • In addition to Poelinca's answer: putting PHP in your body (that is, the database) is really considered a bad practice too. It is a very unfortunate "feature" in Drupal, one that causes more trouble then it will ever solve. – berkes Mar 14 '11 at 19:22

3 Answers3

1

If you're trying to set a global variable, and then use it within a function/method block, you need to use the global keyword on import:

<?php 

// For some reason, this sometimes gives me problems
$foo = 'test';

// So I do this instead, they are equivalent
$GLOBALS['bar'] = 'test';

echo "<p>Global <br/> foo: $foo <br/> bar: $bar</p>";

function globalTest() {
    global $foo;

    echo "<p>globalTest() <br/> foo: $foo <br/> bar: $bar</p>";
}

globalTest();

function globalBarTest() {
    global $foo, $bar;

    echo "<p>globalBarTest() <br/> foo: $foo <br/> bar: $bar</p>";
}

globalBarTest();

?>

In action: http://jfcoder.com/test/globals.php

Prints:

Global
foo: test
bar: test

globalTest()
foo: test
bar:

globalBarTest()
foo: test
bar: test

I have always gotten in the habit of setting a global variable using $GLOBALS, I never have any issues doing it this way.

I would caution, though, that setting globally scoped variables is considered harmful (or at least unnecessary), since they are so easy to accidentally overwrite somewhere else in your code (by you and/or someone else).

Your stated approach in the description sounds quite messy; you should be using a database and let Drupal abstract how you organize, set and get the data from the datastore, instead of editing your files and hardcoding some links and data into a PHP file. This is what I'm thinking reading your description, which may not be fair, but I thought I needed to mention it.

EDIT

In Drupal, you can set global variables in the default/settings.php page using variable_set(), and then use variable_get() to get the variable by name.

http://api.drupal.org/api/drupal/sites--default--default.settings.php/6

variable_set('foo','bar');

http://api.drupal.org/api/drupal/includes--theme.inc/function/template_preprocess/6

function yourtemplate_preprocess (&$variables) {
    $vars['foo'] = variable_get('foo');
}

EDIT 2

Note the source for the variable_set() function:

<?php

function variable_set($name, $value) {
    global $conf;

    $serialized_value = serialize($value);
    db_query("UPDATE {variable} SET value = '%s' WHERE name = '%s'", $serialized_value, $name);
    if (!db_affected_rows()) {
        @db_query("INSERT INTO {variable} (name, value) VALUES ('%s', '%s')", $name, $serialized_value);
    }

    cache_clear_all('variables', 'cache');

    $conf[$name] = $value;
}

?>

EDIT

Ok, here is what you can do:

/drupal-root/htdocs/sites/settings.php

Open the settings.php file and at the bottom, set your PHP variables using the $GLOBALS global variables, as so:

$GLOBALS['test1_variable'] = 'test 1 variable';

And then in your template (with the PHP Input Format selected):

<?php

echo "<p>This is my {$GLOBALS['test1_variable']}.</p>";

?>

Or...

<p>This is my short tag <?=$GLOBALS['test1_variable'];?>.</p>

And you should see your variable printed out on the page from the template code. Note the curly braces surrounding the $GLOBALS variable.

Jared Farrish
  • 48,585
  • 17
  • 95
  • 104
  • I would love to get more info about what you mean when you say 'using a database'. I'd be happy to set up our new site in a more 'Drupal-compliant' manner, so to speak. Right now, our site is just a basic PHP site, which is why I make use of PHP include files to store variables that need to be used globally throughout any site page. If there is a way to save this in a DB and that's the Drupal way to do it, can you provide a link or more info for me? – Julie Mar 14 '11 at 18:09
  • The concept you're looking for are content-types. In Drupal, these are somewhat equivalent to creating a table with columns/rows, although it's not entirely analogous. See DrColossos' answer for more details. http://drupal.org/node/306792 – Jared Farrish Mar 14 '11 at 18:22
  • Also, you can set a $GLOBALS variable in any scope - global, function, method - and it will be available in any of those scopes. – Jared Farrish Mar 14 '11 at 18:27
  • There's also variable_get() - http://api.drupal.org/api/drupal/includes--bootstrap.inc/function/variable_get/6 – Jared Farrish Mar 14 '11 at 18:34
  • @JaredFarrish Thanks for the edits. So it looks like varaible_set and get are not going to be the answer for me. Is that right? You have variable_get in a template preprocess function, and from what I've learned so far (from testing different placements of calling PHP on my own when trying to figure this out last week) the variables still won't be accessible on my actual site page's body content area. Is that true? Please correct me if I'm wrong. However, I'm looking at CCK anyway, and hoping that will be a solutin. From what everyone is saying, that'd be a safer way to do what I need. – Julie Mar 15 '11 at 00:36
  • @Julie - It would be a lot easier to make suggestions if we see your actual code. Drupal is predicated on the code not being injected within the content it's displaying, so your difficulties could be associated with that, but if we can see what you're trying to do (in code), we could suggest possibly some better options. – Jared Farrish Mar 15 '11 at 00:39
  • @Julie - And I do think variable_get/set() might work, depending on what you're trying to do. – Jared Farrish Mar 15 '11 at 00:40
  • @Julie - Also, if you're really just wanting to set a constant for something like COMPANY_NAME so that your users can include it and it gets expanded out, you could post-process the content and do a str_replace() to expand your pre-determined constants within their content, affecting the result before it gets saved to the database. There are, of course, several ways of doing this in reality. – Jared Farrish Mar 15 '11 at 01:16
  • @JaredFarrish I have edited my original post to include some code from my site. I hope it helps. If you have additional info to offer, please do. You've been really helpful so far, it's just that unfortunately I've yet to find the solution that I need! – Julie Mar 15 '11 at 13:46
  • @Julie - See my last edit. I did test this, so it does work. Now, having said that, I would still consider creating a preprocess handler (see the template.php file), or add a function content_identity() to your template.php file and edit the page.tpl.php file to wrap the $content variable on that page, so that you can set up variables ($GLOBALS or variable_set()/variable_get()) such as $COMPANY_NAME and allow for shorthand statements such as "Welcome to `!c_name!` corporate website" within the page content, and it will automatically replace that `!c_name!` with the appropriate variable name. – Jared Farrish Mar 17 '11 at 01:22
0

If you want to provide additional info that should go with some nodes, you should use CCK to create a content type, that has all the additional infos. With styling inside a template, you can archive almost anything.

If CCK is not siutable (in most cases, it is exactly what you want), you need to implement a _preprocess_ function. This would look like

function yourtemplate_preprocess_page(&$variables) {
  $vars['my_custom_var'] = "hello"; //anything can go here
}

Now you have a $my_custom_var in your page-template file available.

Be sure to make yourself familiar with the template system of Drupal (if you haven't already).

DrColossos
  • 12,656
  • 3
  • 46
  • 67
  • Thanks for the reply. I did try the preprocess_page function, but that only made my variables available on page.tpl.php. What I need is something to make my variables available within the body content area on the site itself. As in, when I click to create a new page, and the body area is set to accept PHP code, I want to call my variables there. Is there some way to access them there after setting them in the preprocess_page function? Perhaps I did it wrong. In the meantime, I will look into the CCK to see if it will solve this for me; I've gotten other recommendations so far to use it. – Julie Mar 14 '11 at 18:01
0

It sounds like you are looking for the token_filter module. My problem is that it isn't ready (in token module) for D7 yet.