How do I display image from the php function? [updated]
default.htm
<img id="avatar-image" alt="Jason's Image" src="{{ getAvatarImage() }}" />
Component.php
public function getAvatarImage()
{
$var = \System\Models\File::select('disk_name')->where('attachment_id', $avatar_id)->first();
if (count($var) == 0) return "";
return $var->path;
}
How do I get the image source and display the image?
First of all, are you sure that this function returns the correct file path? I'll consider that yes.
So, organizing things, what you're trying to do is use a custom function inside Twig environment.
To do so you need to register your function in the CMS extending twig.
STEP 1
Create a registerMarkupTags() method that returns an array of custom functions assigned by the "function name" in the plugin registration class.
YourPlugin/Plugin.php
public function registerMarkupTags() {
return [
'functions' => [
'getAvatarImage' => [ $this, 'getAvatarImageInternal' ]
]
];
}
STEP 2
We are referring the custom function to $this, so add the method in the same class.
YourPlugin/Plugin.php
public function registerMarkupTags() {
return [
'functions' => [
'getAvatarImage' => [ $this, 'getAvatarImageInternal' ]
]
];
}
/**
* Example of registering a Twig function.
*
* #return string
*/
public function getAvatarImageInternal() {
// Your function body goes here.
$path = 'http://app.localhost/storage/image.jpg';
return $path;
}
STEP 3
Now the custom function is registered and you can use inside Twig environment.
<img src="{{ getAvatarImage() }}" />
First, getAvatarImage is not a static Method. This means you need an instance of it to be able to call it. Second; to display the Image, you need to echo it back to get the return value (not just call it). Your code should have read something like this:
<?php
$avatar_id = 10; // JUST A SIMPLE SIMULATION. YOU SHOULD HAVE A WAY TO GET THE ID
$obj = new ClassContainingGetAvatarImageMethod();
$imgURL = $obj->getAvatarImage($avatar_id);
?>
<img id="avatar-image" alt="Jason's Image" src="<?php echo $imgURL;?>" />
OR
<img id="avatar-image" alt="Jason's Image" src="<?php
avatar_id = 10; // WHATEVER THE AVATAR_ID MAY BE
$obj = new ClassContainingGetAvatarImageMethod();
echo $obj->getAvatarImage($avatar_id);?>" />
It's not a good way to select the image directly from the file system. Instead you can use attachments system as I explained in this question
How to change the front page & component image from the backend? how to get HTML tag attributes in php?
Related
I am trying to return the images for each row in my database through the controller
public function getEmotions() {
$emotionsList = Emotions::all();
$images = DB::table('emotions')->select('image')->get();
return $images;
}
This returns the error Malformed UTF-8 characters, possibly incorrectly encoded
I have tried this as a solution
public function getEmotions() {
$emotionsList = Emotions::all();
$images = DB::table('emotions')->select('image')->get();
return utf8_encode($images);
}
But this then returns the error Method Illuminate\Support\Collection::__toString() must return a string value
I'm a but stuck with it now, can anyone see where I'm going wrong?
This data is also being passed to a Vue file where I want to display the images from. Could I add this as {{ emotion.image }}?
<label v-for="emotion in emotions" class="cb-container">{{ emotion.em_name }}
<input name="emotions[]" type="checkbox" :value="emotion.id">
<span class="checkmark"></span>
</label>
$images = DB::table('emotions')->select('image')->get();
The get() method provided by Laravel return an instance of Illuminate\Support\Collection class.
By definition an
Illuminate\Support\Collection class provides a fluent, convenient
wrapper for working with arrays of data.
Documentation
The point is: you need to loop through your $images var and utf8_encode each row separately like
foreach($images as $image) {
...
}
Edit
You may use
public function getEmotions() {
$emotionsList = Emotions::all();
foreach($emotionsList as $emotion) {
$emotion->image = 'data:image/jpeg;base64,' . base64_encode( $emotion->image);
}
return $emotionsList;
}
Usage
... v-for="emotion in emotions" ...
<img src="$emotion->image"/>
You must return a response:
return response($images->toArray());
Or if you want it encoded in json:
return response()->json($images);
I know that you can use extract() to achieve this however my circumstances are as followed:
I am building a very small basic MVC framework for personal projects and I have this in my controller:
public function index(){
$data = [
'title' => 'Welcome'
];
$this->view('pages/index', $data);
}
As you can see this passes the data array into the view and you can echo it like:
echo $data['title'];
But I want to echo it like echo $title; I know that extract() can do this but that means I have to manually put extract($data); at the top of every page which isnt the end of the world but I was just curious if there was a way it could be done automatically? I have tried to use extract by putting it inside the view function but that did not work. I have also tried to use extract by putting it in the header file that is required_once in index.php (thus making the header file a static header thats always required) but neither has worked so any advice would be great.
Here is the code for the view function as requested:
public function view($view, $data = []){
if(file_exists('../../views/'.$view.'.php')){
require_once '../../views/'.$view.'.php';
} else {
die('View does not exist');
}
}
Simple that is it ,use compact and extract function
index method
public function index(){
$title='Welcome';
$this->view('pages/index', compact('title'));
}
Wiew method
public function view($view, $data = []){
extract($data);
if(file_exists('../../views/'.$view.'.php')){
require_once '../../views/'.$view.'.php';
} else {
die('View does not exist');
}
}
In html
<h1> hello <?php echo $title; ?></h1>
Here is where I went wrong, I put extract in the view method before and it didn't work.
However the advice here was to put it in the view function and I now understand that I put the extract function after require_once '../../views/'.$view.'.php'; I just put extract before that line of code and it is now working!
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
I like to preface this question by apologizing for being noob.
For codeigniter URL, format goes:
example.com/class/function/ID
If I were to have the urls below
website.com/books/chapter/1
website.com/books/chapter/2
I know how to create class named "books" under which I would create public function "chapter", so...
public funtion chapter() {
$this->load->view("content");
}
How would I add the ID's 1 and 2, assuming the only difference between the two website is I would have:
1.png within my "content" for website.com/books/chapter/1
and
2.png within my "content" for website.com/books/chapter/2, with 2.png replacing where 1.png was supposed to be.
Thanks!
Since you are using this URL: website.com/books/chapter/2, you are already passing the id after the last slash. Therefore your controller method should receive that ID as a parameter like this:
Controller:
public function chapter($id) {
$data["image_id"] = $id;
$this->load->view("content", $data);
}
View:
<img src="<?= $image_id ?>.png">
Controller:
public function chapter() {
$data["image_id"] = $this->uri->segment(3); //since your ID(number) is in third segment so 3
$this->load->view("content", $data);
}
View:
<img src="<?= $image_id ?>.png">
for more info on URI class
https://ellislab.com/codeigniter/user-guide/libraries/uri.html
The ids are just the method parameters. You can get it by passing the parameter in your method.
In the controller:
public function chapter($id) {
$data["image_id"] = $id;
$this->load->view("your_view", $data);
}
In your view:
<img src="<?php echo $image_id;?>.png"/>
I'm creating a new block and I want to pass a defined variable to the block instance on add.
In my controller, I have the following:
// declare the var
public $hasMap = 0;
public function add() {
$this->set('hasMap', $this->generateMapNumber());
}
The generateMapNumber() function looks like this:
public function generateMapNumber() {
return intval(mt_rand(1,time()));
}
In my add.php form I have a hidden field:
<?php $myObj = $controller; ?>
<input type="hidden" name="hasMap" value="<?php echo $myObj->hasMap?>" />
When I create a new block, hasMap is always 0 and the hidden input value is always 0 too. Any suggestions? Thank you!
--- EDIT ---
From the concrete5 documentation:
// This...
$controller->set($key, $value)
// ... takes a string $key and a mixed $value, and makes a variable of that name
// available from within a block's view, add or edit template. This is
// typically used within the add(), edit() or view() function
Calling $this->set('name', $value) in a block controller sets a variable of that name with the given value in the appropriate add/edit/view file -- you don't need to get it from within the controller object. So just call <?php echo $hasMap; ?> in your add.php file, instead of $myObj->hasMap.
It will not be the same value, because the function will give diferrent values every timy it is called.
So here's the solution. In the controller...
public $hasMap = 0;
// no need for this:
// public function add() { }
public function generateMapNumber() {
if (intval($this->hasMap)>0) {
return $this->hasMap;
} else {
return intval(mt_rand(1,time()));
}
}
And then in the add.php file...
<?php $myObj = $controller; ?>
<input type="hidden" name="hasMap" value="<?php echo $myObj->generateMapNumber()?>" />
It works perfectly. On add, a new number is generated and on edit, the existing number is drawn from the hasMap field in the db.
Thanks for all the input. Hope that helps someone else!