Member Avatar for LastMitch

Hi

I still learning how Smarty templates works. I can't seem to make the image appear on the Smarty Template.

I try to used this {html_image} it doesn't work.

I used <img> instead.

<img src="images/{$book->image[tbl]}" width="115">

These are my files.

This is my index.php

<?php

require("libs/Smarty.class.php");
require_once("get_data.php");
require_once("books.php");

$book = new n_books();

$smarty = new Smarty();

$smarty->assign("book",$book);

$output = $smarty->fetch('index.tpl');

$smarty->display('index.tpl');

?>

This is my index.tpl

<html>
<head>
<title> Book Sale </title>
</head>
<body>
<table border="0" width="100%">
<tr>
<td>
<h1> Book Sale</h1>
</td>
</tr>
</table> 

<table border="1" width="50%">
{section name=tbl loop=$book->title}
<tr>
<td align="left">
<table>
<tr>
<td> 
<img src="images/{$book->image[tbl]}" width="115">
</td>
<td valign="top">
<font size=+1><b> {$book->title[tbl]} </b></font><br> 
<font size=-1 color=blue><b>  {$book->author[tbl]} </b></font><br>
{$book->description[tbl]} <br>
</td>
</tr>
</table>

</td> 
{/section}
</tr>
</table>
</body>
</html>

This is my get_data.php

<?php

class books {

//public
public $title = array(); 
public $image = array(); 
public $author = array(); 
public $description = array(); 

// private 
private $filename = "bookdata.txt";

//class constructor
function __construct(){

//get the lines as an array
$i=-1;
$lines = file($this->filename);

// get each variable in an array
foreach ( $lines as $line) {

if (strlen($line) > 2) {

$line = rtrim($line);

list($what, $content) = explode("=>", $line);

if ($what == "Title") {
$i++;
$this->title[$i]=$content;
}
elseif ($what == "Image") {
$this->image[$i]=$content;
}
elseif ($what == "Author") {
$this->author[$i]=$content;
}
elseif ($what == "Description") {
$this->description[$i]=$content;
}
};
};

} // end constructor

} // end GetData

?>

This is my books.php

<?php

class n_books {

//public
public $title = array(); 
public $image = array(); 
public $author = array(); 
public $description = array(); 

//private 
protected $DataObject;

function __construct(){

$this->DataObject = new books();
$this->title = $this->DataObject->title;
$this->image = $this->DataObject->image;
$this->author = $this->DataObject->author;
$this->description = $this->DataObject->description;
}

} // end class n_books

?>

This is my bookdata.txt

Title=> Book 1
Image=> 1.jpg
Author=> Sam Rock
Description=> Book 1 demo 

Title=> Book 2
Image=> 2.jpg
Author=> John Rock
Description=> Book 2 demo

Title=> Book 3
Image=> 3.jpg
Author=> Tim Rock
Description=> Book 3 demo

Title=> Book 4
Image=> 4.jpg
Author=> Chris Rock
Description=> Book 4 demo

I attached an image of the template how it looks like now but it doesn't have image appear yet.

Any Suggestions and explanation will help. I appreciate it. Thanks!

Smartyc2

What is in the src in your resulting html? Since you explode on => there may be an additional space. You may have to trim it for the image.

Can I just point out that your use of classes in that post is a bit odd. Or, at least, not in line with how traditional OOP goes. Generally you want to try to have each single item represented by a single object instance. In your case, you have books, so you'd want to have a Book class representing each of them. You could then, of course, create a second object to manage a list of Books, but each book should still be represented by a Book object.

The way you have your classes now, they aren't so much object instances as they are class-flavored multidimensional arrays. Your code could easily be rearanged to become a single function that returns all the books as a multidimensional array.

Here is an example of what would be considered a more OOP way of writing the above code.

<?php
class Book {
    public $title;
    public $image;
    public $author;
    public $description;

    public function loadFromFile($fh)
    {
        if (!$fh) {
            throw new ArgumentException("An open file handler must be passed.");
        }
        else {
            // Read the next four non-empty lines. They should contain
            // the data for the class. If they don't, throw an exception.
            $count = 0;
            while (($line = fgets($fh)) && $count < 4) {
                $line = trim($line);
                if (!empty($line)) {
                    ++$count;
                    $parts = explode("=>", $line);
                    $key = strtolower(trim($parts[0]));
                    if (property_exists($this, $key)) {
                        $this->{$key} = trim($parts[1]);
                    }
                }
            }
            if (empty($this->title) || empty($this->image) || empty($this->author) || empty($this->description)) {
                throw new UnexpectedValueException("Invalid file data!");
            }
        }
    }
}



<?php
class BookList implements Iterator {
    public $books;

    public function __construct() {
        $this->books = array();
    }

    public function loadFromFile($fileName="data.txt") {
        $fh = fopen($fileName, "r");
        if ($fh) {
            try {
                while (true) {
                    $book = new Book();
                    $book->loadFromFile($fh);
                    $this->books[] = $book;
                }
            }
            catch (UnexpectedValueException $e) {
                // To be expected. This will happen when there is no
                // more valid data left in the file.
            }
            fclose($fh);
        }
    }

    /*
     * Iterator methods
     */

    private $currentItem = 0;

    public function current() {
        return $this->books[$this->currentItem];
    }

    public function next() {
        ++$this->currentItem;
    }

    public function rewind() {
        $this->currentItem = 0;
    }

    public function key() {
        return $this->currentItem;
    }

    public function valid() {
        return isset($this->books[$this->currentItem]);
    }
}

Note that the BookList class implements the Iterator interface, allowing you to use it in for loop as you would an array. This lets you do things like this in your templates:

// In PHP:
$list = new BookList();
$list->loadFromFile("data.txt");
$smarty->assign("books", $list);

// And in your Smarty template:
{foreach from=$books item=book}
    Title: {$book->title}
    Author: {$book->author}
    Description: {$book->description}
    Image: {$book->image}
{/foreach}
commented: Thanks for the example for me to play around with +9

@Mitch,

It could be just a url stuff and nothing serious. If you could output the other data off from the same file, maybe it is just the directory reference mishaps. Did you try

    ../images/

On your image's src?

Back to the case of smarty's iteration function.. I totally agree with all of you. I have no problem digesting whatever is posted here. Except for the odd implementation on the constructor.

For the template, LastMitch implemented the section loop instead of the foreach loop. So, it is pretty much capable of what the foreach can do.

    {section name=tbl loop=$book->title}

I preferred using dot notation though as much as possible, but it just only me :).

commented: Yes, it was the URL all along +9
Member Avatar for LastMitch

@pritaeas

What is in the src in your resulting html? Since you explode on => there may be an additional space. You may have to trim it for the image.

Thanks for the reply and explanation.

The src is linking to the folder that has the images.

Regarding about the space. I'll check and make sure there's no white space. I'll get back to you.Thanks

Member Avatar for LastMitch

@Atli

Can I just point out that your use of classes in that post is a bit odd. Or, at least, not in line with how traditional OOP goes. Generally you want to try to have each single item represented by a single object instance. In your case, you have books, so you'd want to have a Book class representing each of them. You could then, of course, create a second object to manage a list of Books, but each book should still be represented by a Book object.

Thanks for the reply and explanation and example.

You're right about my OOP being odd. Well, so far all thread that has OOP is odd. I think most of the members who help me in the past know my OOP being odd. So I'm still learning it. Thanks for your patience.

I will test it out and get back too you. Thanks.

Member Avatar for LastMitch

@veedeoo

It could be just a url stuff and nothing serious. If you could output the other data off from the same file, maybe it is just the directory reference mishaps. Did you try

../images/

On your image's src?

Thanks for the reply and explanation.

I did try that before I created this thread and it didn't work. I will try again and get back to you. Thanks.

Member Avatar for LastMitch

@veedeoo

Sorry replying back so late! You are right about the URL!

I couldn't link it by ../image/.. or ../../image

So what I did was I fill in another folder name.

Instead of this:

<img src="images/{$book->image[tbl]}" width="115">

I change it to this:

<img src="../example/images/{$book->image[tbl]}" width="115">

So it works fine now.

I appreciate you taking time to help me. Thanks!

I attach a image of how it looks like:

Smarty

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.