Output custom function result in php template with UMI CMS - php

I made my custom function in modules/custom.php file, and I'm trying to output its result into php template.
public function pagetemp($template = 'default') {
list($template_block) = emarket::loadTemplates('emarket/' . $template, 'personal_link');
$block_arr = [];
return emarket::parseTemplate($template_block, $block_arr);
}
But it doesn't works.
How do I pass result of my custom function into php template? Hope my question makes sense.

Use method
macros($module, $method) : mixed
like this http://dev.docs.umi-cms.ru/spravochnik_makrosov_umicms/blogi/blogs20_commentslist/#php-templating (without $this->render)
Documentation: http://dev.docs.umi-cms.ru/shablony_i_makrosy/php-shablonizator_umi_cms/opisanie_api_php-shablonizatora/

Related

Is it possible to link to other static pages in a Timber template?

Currently, to link to a "FAQ" page, I have the following:
Check out our FAQ page.
However, I'd like to be able to link to other internal pages in my WordPress theme without manually writing in the URL parameters after it. Something like:
Check out our FAQ page.
Is this not possible in Timber? I've checked through the docs but don't see any references to it, but I feel like I must be missing something.
Wordpress has two functions to resolve it: get_page_by_path() and get_permalink()
get_page_by_path('page-slug');
get_permalink(page_id);
Using Timber you could write something like this calling a Timber function:
{{ function('get_permalink', function('get_page_by_path', 'page-slug')) }}
But sure, you should define a wp function to not be insane. You can add functions to WordPress using the functions.php file, even you should have defined a class to extends Timber (if not, copy and paste it)
class StarterSite extends Timber\Site {
public function __construct() {
add_filter( 'timber/twig', array( $this, 'add_to_twig' ) );
add_filter( 'timber/context', array( $this, 'add_to_context' ) );
$this->add_routes();
parent::__construct();
}
public function add_to_context( $context ) {
$context['menu'] = new Timber\Menu();
$context['site'] = $this;
return $context;
}
public function add_to_twig( $twig ) {
$twig->addFunction( new Timber\Twig_Function( 'get_permalink_by_slug', function($slug) {
return get_permalink( get_page_by_path($slug) );
} ) );
return $twig;
}
}
new StarterSite();
As you can see I defined a Twig function named get_page_by_slug that receives a string with the page slug. Now, you can write it on your templates:
{{ get_permalink_by_slug('page-slug') }}
Enjoy :)
You can add the pages into your context using the filter timber_context
add_filter('timber_context', 'add_to_context');
function add_to_context($context){
/* this is where you can add your own data to Timber's context object */
$extraLinks = [];
$extraLinks['faq'] = get_permalink($faq_ID);
$context['site']['extraLinks'] = $extraLinks;
return $context;
}
So you can call in your twig file
Check out our FAQ page.
source

How can I re-use my wordpress action hook functions as 'normal' functions

I have an function action hook which collects subscriptions from our database. I want to use this so that I can display the subscriptions on the page, but I also want to use this function in another function that calculates the new subscription price. Is this possible?
My code looks somewhat like this
add_action( 'wp_ajax_get_get_subs_with_type', 'get_subs_with_type' );
add_action( 'wp_ajax_nopriv_get_get_subs_with_type', 'get_subs_with_type' );
function get_subs_with_type($sub_type) {
$subs = //get alot of info from database......
echo $subs;
}
But I also want to use this function with a return statement instead of echo to be used in another function.
functon calc_subs(){
$subs = get_subs_with_type();
return $subs[1]->price + 1;
}
So can I use a function tied to an action hook as a 'normal' function as well? Or what should I do?
EDIT:
If there is no good way of doing this, I made a little hacky solution:
add_action( 'wp_ajax_get_get_subs_with_type', 'get_subs_with_type' );
add_action( 'wp_ajax_nopriv_get_get_subs_with_type', 'get_subs_with_type' );
function get_subs_with_type($sub_type) {
$subs = get_sub_from_db()
echo $subs;
}
function get_sub_from_db() {
$subs = //get alot of info from database......
return $subs;
}
Now I can use get_sub_from_db() in my other function as well.
functon calc_subs(){
$subs = get_sub_from_db();
return $subs[1]->price + 1;
}
What do you think of this?
You can for example do something like:
/**
* Returns bla bla bla
* #return array
*/
function get_subs_with_type($sub_type) {
$subs = //get alot of info from database......
return $subs;
}
add_action( 'wp_ajax_get_get_subs_with_type', function () {
echo get_subs_with_type();
});
but remember that while using anonymous function you will not be able to remove this action with remove_action.
The solution you proposed, by creating two different function, one returning the database call & the other calling the first one looks quite good.
Don't forget to add a wp_die(); function after you echoed all this information to the ajax handler. This is required to terminate any ajax call immediately and return a proper response.

Pass variable to _preprocess_node function for use in node template

I've been racking my brains over this one but I'll do my best to describe the problem as best as possible. I have a custom function written within template.php, with a bunch of conditionals. When a condition is true, I would like to assign a value to a variable, and then pass that variable intro a node preprocess function that allows that variables to be rendered on a node template.
The function containing the condition:
function _mytheme_date_repeat_string($vars) {
$exdate_pos = strpos($rrule['WKST'], 'EXDATE:');
if($exdate_pos > 0) {
$vars['testvar'] = 'abc123';
}
}
The preprocess function that I would like to render the variable in for node template use:
function mytheme_preprocess_node(&$vars, $hook) {
$vars['new_variable'] = $testvar;
}
Intended usage in node.tpl.php:
<?php print $new_variable; ?>
I'm not great with PHP, but I know enough about programming to know that variable scope might be an issue here. What would be the best way to implement this? Any guidance is greatly appreciated.
Thanks,
Mark.
If it is not called, your _mytheme_date_repeat_string() function will never be executed. Preprocess functions (ie. any function starting mytheme_preprocess_, are called automatically by Drupal's theme system.
What you need is either move the code of _mytheme_date_repeat_string() in mytheme_preprocess_node() or refactor it and call it.
function _mytheme_date_repeat_string($rrule) {
$exdate_pos = strpos($rrule['WKST'], 'EXDATE:');
if($exdate_pos > 0) {
return 'abc123';
}
else {
return NULL;
}
}
/**
* Prepares variables for node templates.
*/
function mytheme_preprocess_node(&$variables, $hook) {
// Get $rrule from somewhere
$rrule = ... ;
$testvar = _mytheme_date_repeat_string($rrule);
if ($testvar) {
$variables['new_variable'] = $testvar;
}
}
You code does not show where the $rrule calue comes from. I assume you would get it for $variables['node'].

Output two array in one view (Kohana)

I have one controller which need to output in one view file and $_GET param.
Controller code is:
public function action_register_final() {
//Detect view file
$block_center = View::factory('pages/v_register_final');
$block_center = $this->request->param('user_id');
//Detect block
$this->template->block_center = array($block_center);
}
But this code is output only $_GET param... if i remove $block_center = $this->request->param('user_id'); view is loading good and output. I know i replace $block_center but how I can to output both values.
Thx.
Watch. You overwrite your variable. I think you need this:
public function action_register_final()
{
// Detect view file
$this->template = View::factory('pages/v_register_final');
$this->template->block_center = array($this->request->param('user_id'));
}
Or.
public function action_register_final()
{
// Detect view file
$this->template = View::factory('pages/v_register_final');
$block_center = this->request->param('user_id');
$this->template->block_center = array($block_center);
}
Not tested. This is what you need? Where is your second array? Try merge.

Simple template var replacement, but with a twist

So I'm setting up a system that has a lot of emails, and variable replacement within it, so I'm writing a class to manage some variable replacement for templates stored in the database.
Here's a brief example:
// template is stored in db, so that's how this would get loaded in
$template = "Hello, %customer_name%, thank you for contacting %website_name%";
// The array of replacements is built manually and passed to the class
// with actual values being called from db
$replacements = array('%customer_name%'=>'Bob', '%website_name%'=>'Acme');
$rendered = str_replace(array_keys($replacements), $replacements, $template);
Now, that works well and good for single var replacements, basic stuff. However, there are some places where there should be a for loop, and I'm lost how to implement it.
The idea is there'd be a template like this:
"hello, %customer_name%, thank you for
requesting information on {products}"
Where, {products} would be an array passed to the template, which the is looped over for products requested, with a format like:
Our product %product_name% has a cost
of %product_price%. Learn more at
%product_url%.
So an example rendered version of this would be:
"hello, bob, thank you for requesting
information on:
Our product WidgetA has a cost of $1.
Learn more at example/A
Our product WidgetB has a cost of $2.
Learn more at example/B
Our product WidgetC has a cost of $3.
Learn more at example/C.
What's the best way to accomplish this?
Well, I really dont see the point in a template engine that uses repalcements/regex
PHP Is already a template engine, when you write <?php echo $var?> its just like doing <{$var}> or {$var}
Think of it this way, PHP Already translates <?php echo '<b>hello</b>'?> into <b>hello</b> by its engine, so why make it do everything 2 times over.
The way i would implement a template engine is like so
Firstly create a template class
class Template
{
var $vars = array();
function __set($key,$val)
{
$this->vars[$key] = $val;
}
function __get($key)
{
return isset($this->vars[$key]) ? $this->vars[$key] : false;
}
function output($tpl = false)
{
if($tpl === false)
{
die('No template file selected in Template::output(...)');
}
if(!file_exists(($dir = 'templates/' . $tpl . '.php')))
{
die(sprintf('Tpl file does not exists (%s)',$dir));
}
new TemplateLoader($dir,$this->vars);
return true;
}
}
This is what you use in your login such as index.php, you will set data just like an stdClass just google it if your unsure. and when you run the output command it sends the data and tpl to the next class below.
And then create a standalone class to compile the tpl file within.
class TemplateLoader
{
private $vars = array();
private $_vars = array(); //hold vars set within the tpl file
function __construct($file,$variables)
{
$this->vars = $variables;
//Start the capture;
ob_start();
include $file;
$contents = ob_get_contents();
ob_end_clean(); //Clean it
//Return here if you wish
echo $contents;
}
function __get($key)
{
return isset($this->vars[$key]) ? $this->vars[$key] : (isset($this->_vars[$key]) ? $this->_vars[$key] : false) : false;
}
function __set($key,$val)
{
$this->_vars[$key] = $val;
return true;
}
function bold($key)
{
return '<strong>' . $this->$key . '</string>';
}
}
The reason we keep this seperate is so it has its own space to run in, you just load your tpl file as an include in your constructor so it only can be loaded once, then when the file is included it has access to all the data and methods within TemplateLoader.
Index.php
<?php
require_once 'includes/Template.php';
require_once 'includes/TemplateLoader.php';
$Template = new Template();
$Template->foo = 'somestring';
$Template->bar = array('some' => 'array');
$Template->zed = new stdClass(); // Showing Objects
$Template->output('index'); // loads templates/index.php
?>
Now here we dont really want to mix html with this page because by seperating the php and the view / templates you making sure all your php has completed because when you send html or use html it stops certain aspects of your script from running.
templates/index.php
header
<h1><?php $this->foo;?></h1>
<ul>
<?php foreach($this->bar as $this->_foo):?>
<li><?php echo $this->_foo; ?></li>
<?php endforeach; ?>
</ul>
<p>Testing Objects</p>
<?php $this->sidebar = $this->foo->show_sidebar ? $this->foo->show_sidebar : false;?>
<?php if($this->sidebar):?>
Showing my sidebar.
<?php endif;?>
footer
Now here we can see that were mixing html with php but this is ok because in ehre you should only use basic stuff such as Foreach,For etc. and Variables.
NOTE: IN the TemplateLoader Class you can add a function like..
function bold($key)
{
return '<strong>' . $this->$key . '</string>';
}
This will allow you to increase your actions in your templates so bold,italic,atuoloop,css_secure,stripslashs..
You still have all the normal tools such as stripslashes/htmlentites etc.
Heres a small example of the bold.
$this->bold('foo'); //Returns <strong>somestring</string>
You can add lots of tools into the TempalteLoader class such as inc() to load other tpl files, you can develop a helper system so you can go $this->helpers->jquery->googleSource
If you have any more questions feel free to ask me.
----------
An example of storing in your database.
<?php
if(false != ($data = mysql_query('SELECT * FROM tpl_catch where item_name = \'index\' AND item_save_time > '.time() - 3600 .' LIMIT 1 ORDER BY item_save_time DESC')))
{
if(myslq_num_rows($data) > 0)
{
$row = mysql_fetch_assc($data);
die($row[0]['item_content']);
}else
{
//Compile it with the sample code in first section (index.php)
//Followed by inserting it into the database
then print out the content.
}
}
?>
If you wish to store your tpl files including PHP then that's not a problem, within Template where you passing in the tpl file name just search db instead of the filesystem
$products = array('...');
function parse_products($matches)
{
global $products;
$str = '';
foreach($products as $product) {
$str .= str_replace('%product_name%', $product, $matches[1]); // $matches[1] is whatever is between {products} and {/products}
}
return $str;
}
$str = preg_replace_callback('#\{products}(.*)\{/products}#s', 'parse_products', $str);
The idea is to find string between {products} and {products}, pass it to some function, do whatever you need to do with it, iterating over $products array.
Whatever the function returns replaces whole "{products}[anything here]{/products}".
The input string would look like that:
Requested products: {products}%product_name%{/products}

Categories