Jump to content
fruid

variable on _main.php is undefined on template

Recommended Posts

I get an "Undefined Variable" Error on a template for a variable that I declare on the _main.php template which is clearly included.

Some background: At the beginning I didn't have a _main.php template for that particular project because I started off with a different profile but all my other projects work that way so I just created one and yes also included it on the config.php…

$config->prependTemplateFile = '_init.php';
$config->appendTemplateFile = '_main.php';
$config->useMarkupRegions = true;
$config->useFunctionsAPI = true; 

Might there be something that am I doing wrong or missing out on though? 

Also, not sure if related, when I include "namespace ProcessWire" on the top of the template, cause I thought that might be the issue, it wouldn't know the functions like __() and _x(), you know, the ones to make strings multilingual.

Call to undefined function _x(), did you mean _()?

 

Share this post


Link to post
Share on other sites

Where are you getting the error, and where are you declaring the variable? If you're trying to access a variable in the template file corresponding to the page template that has been declared in the _main.php, this won't work because the _main.php is executed last. The template files are included in the following order (assuming your config above):

_init.php -> [current-template].php -> _main.php

So if you want to declare a variable to use in all templates, you need to do that in the _init.php

All the template files should have the ProcessWire namespace. Not sure about the undefined function errors, those functions should be available in the ProcessWire namespace. Would need to see the file to diagnose.

  • Like 1

Share this post


Link to post
Share on other sites

OK I fixed it considering all the above. For some reason I always thought _main.php is prepended 😄, maybe because that's where my <header> and <head> (meta data), navigation menu and whatnot is located and I got pretty far with that wrong assumption. It's still puzzling though, because I always put a <div id="content"> on _main.php which is then replaced by what comes after, i.e. what's on the template files with that same id. 

Share this post


Link to post
Share on other sites

it's actually astonishing how far I got while not thinking too much about this detail. 

I re-read the whole output strategies documentation, I say re-read because I did before, it probably just was too much to take in at once. I have been using Markup Regions, it gives me the best of both worlds, just as it states. I also appreciate the fact that I can thereby escape the php-syntax highlighting in my editor when there's a lot of HTML-markup in the template file and have it show HTML-syntax-highlighting instead and still delay the output.

I also put 

$config->prependTemplateFile = '_init.php';
$config->appendTemplateFile = '_main.php';

$config->prependTemplateFile = '_head.php'; // this I added now
$config->appendTemplateFile = '_foot.php';  // this I added now

$config->useMarkupRegions = true;
$config->useFunctionsAPI = true; 

in the config.php file and remove the head and foot section from the _main.php file. Now I get the error:

Call to undefined function ProcessWire\ukIcon()

which I reckon is just one of many functions. If I add include '_head.php' to the top of whichever template, everything works fine, just not the prepending (and possibly appending) on config file. What could be the reason? What am I missing? As much as I enjoy programming, I dislike this guessing around for hours and days so I turn to the forum.

Does the order of the $config->prependTemplateFile-included files matter? Does in the above scenario _init.php get included before _head.php or vice versa?

Thanks for help!

Share this post


Link to post
Share on other sites
9 hours ago, fruid said:

$config->prependTemplateFile = '_init.php';
$config->appendTemplateFile = '_main.php';
$config->prependTemplateFile = '_head.php'; // this I added now
$config->appendTemplateFile = '_foot.php';  // this I added now

Hello, in line 3 and 4 you simply overwrite the values you assigned to the properties in line 1 and 2. In other words: your _init.php and _main.php do not get prepended/appended because what you added afterwards is to instruct ProcessWire to prepend/append _head.php/_foot.php instead.

I recommend removing the two lines you added and use _main.php to define the placeholders for your header and footer. Something like this:

In this linked example of @Pixrael <header> and <footer> are not defined as regions but you are free to do it if you need to change them on page-by-page cases.

 

Edited by szabesz
typos
  • Like 2

Share this post


Link to post
Share on other sites

OK thanks for the input, it helps. I stick with markup regions and just "include" _head.php and _foot.php in the _main.php rather than using markup regions in this case (i.e. <div id="head">) or prepending/appending.

But why did I even start want to change that?

Because I'm hooking the page-object to add a ->fulltitle and a ->shorttitle method.

the full title is $page->parent->title.'/'.$page->title; and will be used for the snipcart-basket.

And the shot title is $page->title and will be used for the breadcrumbs to avoid redundancies.

I thought the hooks kind of store whatever I tell them to store before anything else renders. Now I realise the value they return is composed at the moment the method gets called. So on the product-page I put:

$product->title = $page->title; // which is the full title

And since the _main.php renders last and that's where my _breadcrumbs.php is included, the ->shorttitle method thinks the ->title is the fullttitle and basically overwrites what the hook is doing.

I hope I made myself clear.

Solutions could be to not set $product->title = $page->title but I don't know any other way to change the title that gets sent to the cart.
Or, include the breadcrumbs on _init.php ? But then it's above all the content… Store it in a variable on _init.php and return on _main.php?

I had a working version where I basically manually composed on each page it's required what my ->fulltitle hook is doing and then disassemble it manually with standard php to accomplish what my short-title hook is doing. I thought using hooks would make this matter simpler, now in doubt.

Thanks for further help! 

Share this post


Link to post
Share on other sites
17 hours ago, fruid said:

Solutions could be to not set $product->title = $page->title

I presume that $product is a ProcessWire page object, so you should not overwrite its $title property anyway.

17 hours ago, fruid said:

Store it in a variable on _init.php and return on _main.php?

You should be able to compose the breadcrumb's html block in advance and store it in a variable to be outputted ("rendered") later on. If you render the breadcrumb on almost all pages, the simplest solution is to compose it _main.php's opening <?php namespace ProcessWire; block. I am not saying this is the best place, you should be able to do it in _init.php too.

For example, in one of my sites I use Ryan's ukBreadcrumb() function: https://github.com/ryancramerdesign/regular/blob/master/site-regular/templates/_uikit.php

Which is included like this in _init-php:  include_once('pages/shared/utils/uikit.php'); // UIkit 3 library of Regular Blog Site Profile
I do not even store its returned value in a variable, I just output it like this where it needs to be: <?= ukBreadcrumb() ?>

Hope this helps.

Edited by szabesz
typos

Share this post


Link to post
Share on other sites

why shouldn't I overwrite the title? If I shouldn't and consequently won't, then there's no need for any mentioned work-around-solutions after all. Using the full title (i.e. parents-title/page-title) for the products and the actual title (here short title) for breadcrumbs and admin backend is what I need. 

16 minutes ago, szabesz said:

You should be able to compose the breadcrumb's html block in advance and store it in a variable to be outputted ("rendered") later on. If you render the breadcrumb on almost all pages, the simplest solution is to compose it _main.php's opening <?php namespace ProcessWire; block. I am not saying this is the best place, you should be able to do it in _init.php too.

Composing the breadcrumbs on the _main.php won't work for me. I was able to accomplish what I need by including _breadcrumbs.php on _init.php. On _breadcrumbs.php I compose the breadcrumb-markup making use of the ->shorttitle and ->fulltitle hooks I created on _init.php, and store this markup in a $breadcrumbs variable. On _main.php I output this variable and done.

However, now I'm in doubt again because…

21 minutes ago, szabesz said:

You should be able to compose the breadcrumb's html block in advance and store it in a variable to be outputted ("rendered") later on. If you render the breadcrumb on almost all pages, the simplest solution is to compose it _main.php's opening <?php namespace ProcessWire; block. I am not saying this is the best place, you should be able to do it in _init.php too.

What's the concern? It seems to work fine…

 

Share this post


Link to post
Share on other sites
On 10/15/2020 at 5:00 PM, fruid said:

$product->title = $page->title; // which is the full title

Unless I want to save the value of a page object's property in the database, I would not change a page object's property because it is reasonable to expect that a property corresponds to a value in the database. If I change the property but do not save it to the database, then from that point on it is "confusing" to keep track of the actual value of the property as its value is no longer "in sync" with the database (as long as we are talking about the same request being executed, of course).

To tell the truth, I do not really get what you are trying to solve. I was just trying to point out a few things that might – but not necessarily – cause issues.

  • Like 3

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.

  • Similar Content

    • By Gadgetto
      SnipWire - Snipcart integration for ProcessWire
      Snipcart is a powerful 3rd party, developer-first HTML/JavaScript shopping cart platform. SnipWire is the missing link between Snipcart and the content management framework ProcessWire.
      With SnipWire, you can quickly turn any ProcessWire site into a Snipcart online shop. The SnipWire plugin helps you to get your store up and running in no time. Detailed knowledge of the Snipcart system is not required.
      SnipWire is free and open source licensed under Mozilla Public License 2.0! A lot of work and effort has gone into development. It would be nice if you could donate an amount to support further development:

      Status update links (inside this thread) for SnipWire development
      2020-07-03 -- SnipWire 0.8.7 (beta) released! Fixes some small bugs and adds an indicator for TEST mode 2020-04-06 -- SnipWire 0.8.6 (beta) released! Adds support for Snipcart subscriptions and also fixes some problems 2020-03-21 -- SnipWire 0.8.5 (beta) released! Improves SnipWires webhooks interface and provides some other fixes and additions 2020-03-03 -- SnipWire 0.8.4 (beta) released! Improves compatibility for Windows based Systems. 2020-03-01 -- SnipWire 0.8.3 (beta) released! The installation and uninstallation process has been heavily revised. 2020-02-08 -- SnipWire 0.8.2 (beta) released! Added a feature to change the cart and catalogue currency by GET, POST or SESSION param 2020-02-03 -- SnipWire 0.8.1 (beta) released! All custom classes moved into their own namespaces. 2020-02-01 -- SnipWire is now available via ProcessWire's module directory! 2020-01-30 -- SnipWire 0.8.0 (beta) first public release! (module just submitted to the PW modules directory) 2020-01-28 -- added Custom Order Fields feature (first SnipWire release version is near!) 2020-01-21 -- Snipcart v3 - when will the new cart system be implemented? 2020-01-19 -- integrated taxes provider finished (+ very flexible shipping taxes handling) 2020-01-14 -- new date range picker, discount editor, order notifiactions, order statuses, and more ... 2019-11-15 -- orders filter, order details, download + resend invoices, refunds 2019-10-18 -- list filters, REST API improvements, new docs platform, and more ... 2019-08-08 -- dashboard interface, currency selector, managing Orders, Customers and Products, Added a WireTabs, refinded caching behavior 2019-06-15 -- taxes provider, shop templates update, multiCURL implementation, and more ... 2019-06-02 -- FieldtypeSnipWireTaxSelector 2019-05-25 -- SnipWire will be free and open source Plugin Key Features
      Fast and simple store setup Full integration of the Snipcart dashboard into the ProcessWire backend (no need to leave the ProcessWire admin area) Browse and manage orders, customers, discounts, abandoned carts, and more Multi currency support Custom order and cart fields Process refunds and send customer notifications from within the ProcessWire backend Process Abandoned Carts + sending messages to customers from within the ProcessWire backend Complete Snipcart webhooks integration (all events are hookable via ProcessWire hooks) Integrated taxes provider (which is more flexible then Snipcart own provider) Useful Links
      SnipWire in PW modules directory SnipWire Docs (please note that the documentation is a work in progress) SnipWire @GitHub (feature requests and suggestions for improvement are welcome - I also accept pull requests) Snipcart Website  

       
      ---- INITIAL POST FROM 2019-05-25 ----
       
    • By Ivo
      Hi Folks,
      This PW site https://ancientlakesmagnesium.com.au/ currently runs Snipcart. Products are built in PW pages but the cart and checkout is managed by Snipcart. Snipcart adds new products to its inventory when first added to the cart, thus a copy of the product catalog is on the Snipcart account. My Client manages all the sales/transactions on Snipcart. The problem is Snipcart is limited, my client wishes to connect to smile.io which is much cheaper to do with a pre-built Shopify app and to have PayPal Subscriptions. Snipcart is showing to be limited in several things now that their business has grown.  
       
      My question is, has anyone had success plugging in products from PW pages into Shopify via the Shopify API? I spoke to Shopify support and they pointed me to the one post in this forum, but it doesn't give any detailed instructions and it quite old now. My other option is to build a Shopify system as a sub domain and somehow build an app that mirrors the menu structure on the PW site so that the user doesn't have to maintain 2 menus. 
       
      If anyone has any suggestions that would be most appreciated.
       
      cheers,
      Ivo
    • By maxlab
      Hey everyone,

      Max from Snipcart here!

      We just published a full tutorial showing how to use ProcessWire + Snipcart (our dev-first HTML/JS shopping cart platform) to enable e-commerce. It was pretty much my first time playing around with the Apache/MySQL/PHP stack, so I'd love to get some feedback on the demo code. Oh, and also, if you feel like the Snipcart integration could have been done in a different/better way with ProcessWire, let me know!

      > Blog post tutorial
      > (Very) simple live demo
      > GitHub repo

      Cheers folks.
    • By Tyssen
      I have a PW site which is integrated with Snipcart and now the owners want to add stock management.
      Because each item comes in different sizes and colours, I'm using a repeater field with each row containing a size column.
      The guys at Snipcart have written a blog post on how to achieve basically what I need in a plugin for Craft CMS. I need that converted into a module for PW and instead of updating an individual field, it's updating a column in a repeater field.
      Anyone able to help me out with that?
×
×
  • Create New...