I wrote a PHP Class that works by constructing a paginator by passing it a current page value and a number of pages to show value like this:
$paginator = new Paginator(1,4);
then I out put it like this
<?php
require_once("./partials/pagination.php");
?>
... tons of html
<?php
$paginator = new Paginator(4,2 );
echo($paginator->paginator)
?>
I'd love to be able to simplify it down to something like
<?php
<Paginator pageNum='1' numToShow='3' />
?>
anyone have any thoughts on how this might be done? Other than writing a parser.
This project must be done in PHP for a variety of reasons or I would use react/angular. If anyone has any tips on how to write a "Componentized" php front end, i'd love to hear.
(Needs to be served statically, so I cannot use JS for this)
Thanks
Why not just separate logic of instanciating paginator and view layer? You'll finally get just this:
<?= $paginator->paginate(2,4); ?>
Related
I've been given a website to maintain. The website is using PRADO framework and I had to do some minor changes. There were no problems with the HTML and CSS changes, but now I have to pass some data from a page to a view.
I've tried using:
$this->HomeCalendar2->DataSource = $result['data'];
$this->HomeCalendar2->dataBind();
but it says Component property 'Home.HomeCalendar2' is not defined.
Above my code there is the following code:
$this->HomeCalendar->DataSource = $result;
$this->HomeCalendar->dataBind();
and it works perfectly fine and I can't see where is the definition of HomeCalendar.
Any help will be appreciated.
P.S: I've never worked with PRADO before.
This question is quite old now, hope you already solved it.
Using DataSource means that there must be in your template (.page or .tpl) a TDataBoundControl component like the folowwing (using TRepeater for example)
<com:TRepeater ID="HomeCalendar">
<!--- [ properties like ItemTemplate here and it contents ] --->
</com:TRepeater>
Subclasses of TDataBoundControl are for component needing to loop results, (sorts of for or foreach somehow).
If you juste need to pass a signle result to the view you can use a component like TPanel/TActivePanel, TLiteral, etc. or simply use the expression tag.
Examples :
Expression tag :
Php :
<?php
$this->myvalue = 'Hello World!';
Template :
<h1><%= $this->myvalue %></h1>
Or another solution:
Template :
<com:TLiteral ID="MyLiteral" />
PHP :
<?php
$this->MyLiteral->getControls()->add('<h1>Hello world !</h1>');
I don't even know if this is possible but hopefully someone will be able to point me in the right direction.
Basically I want to know if there is a way of getting the css class of a div and then displaying content based on that class.
So for example if;
<body class="home">
Then a div would display as follows;
<div><p>This is the Home page</p></div>
Like I said, I don't even know if this is possible but any help would be greatly appreciated.
Thanks
What you're trying to do can be done with Javascript, but if you want to use php only, then try to use php before you provide the "class" parameter. For example, if $_GET['class']=="home" then <div class="<? echo $_GET['class']?>">some text</div>
Perhaps, you can use Javascript, with IDs for example:
<div id="home"></div>
<script>document.getElementById('home').InnerHTML = "this is text for home";</script>
Hope it helps!
See you point, but you goes the wrong way. If you want to put all content in one page differs by some query param, there is no need to do so. You just can hide unneeded blocks with css and show them with js. On the other hand, if this is some sort of server-side utilization, there is definitely no reason to do so too. On the server you can totally control the output, so make separate templates.
Is there a reason not to use PHP instead of reading the class of a div?
#index.html
<html>
<?php include /contentDefinitions.php; ?>
...
<?php $content = home; ?>
...
</html>
#contentDefinitions.php
<?php
if($content = home){
<p>This is the homepage. I am a happy paragraph.</p>
}
?>
**this would be a little more efficient with an array or something,
but at the end of the day the easiest thing would just be to include
home.php, page2.php, page3.php etc. as needed instead of going the
route of variables etc... though having an array would let you edit
all the content within one file.
I'm no master of code and have zero familiarity with Joomla, so this may be absolutely useless to you. :)
I don't want to use an MVC framework. I don't want to use a template engine. I am a few man shop where the developers where all the hats, no graphic artists. We do it all (all layers). I do not want code mixed with presentation, like I have with Classic ASP.
But, I do not know what my code is suppose to look like between server side and the actual presentation.
If I'm not emitting HTML in my server side code, how does it get to the HTML page so I can do things like <span><?= $myvar ?></span>? and put loops in the html page?
Thank you for any advice.
For using loops and all, I use the alternative syntax for the control structures.
An example:
<div id="messages"<?php if(!(isset($messages) && count($messages))): ?> class="hidden"<?php endif; ?>>
<?php if(isset($messages)): ?>
<?php foreach($messages as $message): ?>
<div class="message"><?php echo $message; ?></div>
<?php endforeach; ?>
<?php endif; ?>
</div>
For more information, see this: http://php.net/manual/en/control-structures.alternative-syntax.php
Oh also, I use a semi-MVC structure, where I have a class that handles templates (views), basically it's just a class that I create an instance of, pass a set of variables, then render the template when the instance get destroyed. I have an array of variables in that class, and then use extract to pass all variables in the include, like so:
extract($this->variables, EXTR_SKIP);
include($this->file);
EDIT: Here is the same example in Smarty:
<div id="messages"{if isset($messages) && !count($messages)} class="hidden"{/if}>
{if isset($messages)}
{foreach from=$messages item=message}
<div class="message">{$message}</div>
{/foreach}
{/if}
</div>
Simple PHP projects usually generate the full HTML in-place instead of populating templates, so you'd just echo it out in your PHP code.
This gets messy, so you WILL end up coding some kind of templating system for any moderately complex website.
A possible alternative is to serve your page as completely static HTML/CSS and use AJAX to fetch the actual contents dynamically (JSON would be a good transport format, it's native to JS and can easily be generated from PHP). This gets you rid of all the HTML littered across your PHP code. Whether this is a viable alternative or not depends on the case.
<span><?= $myvar ?></span> works.
A loop would look like:
<html>
<body>
<?php
for ($i=1; $i<=5; $i++)
{
echo "The number is " . $i . "<br />";
}
?>
</body>
</html>
Example taken from here.
I really recommend that you use the php Template Inheritance system. (Don't let it scare you, it's only one file.) This is a simple set of functions that helps you to build extensible PHP views without the problems and limitations of manual includes.
It's still Pure PHP, so you don't need to learn some strange template language. It may not look like much, but it's really powerful once you start using it.
To be sure, you can do it all by yourself - but what you want is still MVC pattern, or separation of concerns ("I do not want code mixed with presentation"). Or at least MV, for very simple applications (although it's still dirty, having models directly influence the view).
The easiest way to achieve this is to first collect and process all data, then just print them. No complex code allowed in the php files directly exposed to the web.
<?php
require('model.inc');
process_capuchin_monkey_order_form();
?>
...
<h1>Thank you for your order of <?php echo $order->num_monkeys; ?> monkeys.</h1>
...
typically you would want to just make sure you have as little PHP in your HTML as possible. This means doing all of the data processing before hand, and simply passing a set of variables in one way or another to a method or function that includes the HTML.
Any HTML with PHP intermixed could be considered a template. Here's a simplified example:
// view class
class View {
public function render($html_template) {
include('view_path/' . $html_template . '.php');
}
}
// html template file 'view_path/main.php'
<html>
<body>
<h1><?= $this->title ?></h1>
</body>
</html>
// usage
$view = new View();
$view->title = 'Some Title';
$view->render('main');
You should use an MVC-like separation of concerns no matter what you do. This means:
At least one file is all html and is given a handful of variables. (view/template)
At least one file is all php and only talks to the database. (model)
At least one file processes the http request, pulls data from database, and executes the view.
The core of every php templating language is the use of extract() and include inside a function:
function render_template($___filename, $___data) {
extract($___data, EXTR_SKIP);
include $__filename;
}
You can pretty this up with a class interface (view objects) or with output buffering, but this is the core of every template system. Your controller's responsibility is simply to assemble that $__data argument (usually with data from a database) for a given view.
I'm relatively new to php, and I'm working on a project using a mysql database. The project consists of users being able to write posts, which are then shown in a list format. The problem is, the posts are shown in different locations on the site, like the index (main) page, and the users profile page. Similar to twitter if you're confused. My question is, what is the best way to display the posts? Currently I'm using a class that I created. It has functions to retrieve posts from the database, save them all in a multidimensional array. Then another function in the class formats the entire list using foreach, and then returns the formatted HTML list of posts. All I have to do is echo what is returned. But I read somewhere that it's bad practice to write functions (especially class functions) that output HTML. What would be the best way to do this, without having to rewrite the same code on every page the posts are shown. Is it really bad practice to use HTML in functions?
Example...
a profile page looks something like this.
<
require('class.php');
require('header.php');
$profile = new Profile();
$userProfile = $profile->GetUserProfile($userID);
echo $userProfile;
$class = new Posts();
$posts = $class->GetUserPosts($userID);
echo $posts;
require('footer.php');
?>
And the main page looks something like this
<
$class = new Posts();
$posts = $class->GetAllPosts();
echo $posts;
?>
where the profile class would take a user id and output the users profile, already formatted in HTML.
And the posts class has functions to return a determined number of posts already formatted in an HTML list.
Should I keep everything in the class, or is there a better way?
Thanks
Well, if you're not using an MVC framework of some kind, then I would say that having functions that output HTML isn't going to kill anyone.
Generally however, it's helpful to separate HTML from logic, and this is usually done by creating an HTML template and template fragments with interspersed PHP. Something like this:
<div>
<h1><?php echo $title; ?></h1>
</div>
You could then set up a $title variable (and others), and include('title_fragment.php') to output that bit of HTML. You can extend this to work with entire pages, making it so that your code only has to deal with small amounts of data that get passed to the template.
When it comes time to make changes to the page layout or look, you don't have to go hunting through the code to find the bits of generated HTML... you can go straight to the template files.
This is important for maintainable design as well as code, and it makes it easier to produce other output types later on.
With PHP, one of the simplest libraries for separating the two is Smarty templates. Using Smarty (or any other templating library), you can write an HTML file with the layout and some simple loops or other constructs, and then render that template using a data structure. At the very least, I would suggest altering your class to utilize a template and produce output that way, rather than a mish-mash of print or echo statements with a bunch of HTML in them.
I'd even shy away from #zombat's solution of echo statements in HTML fragments, they quickly become ugly.
Example Smarty template to achieve something like what you want:
{section name=i loop=$posts}
<li>{$posts[i].author} — {$post[i].text}</li>
{/section}
And some PHP supporting code:
// Instantiate Smarty object
$smarty = new Smarty();
// Assign a hash of data
$smarty->assign('posts', array(
array('author' => 'Jim', 'text' => 'Hi this is my post!'),
array('author' => 'Sally', 'text' => 'My first post to the system')
)
);
// Use the file with the above template in it
$smarty->display('posts.html');
The part where you assign data to the template should probably be done via some programmatic means to convert your list of class objects into a list of hashes.
This way you can easily change the way the output looks just by editing the HTML template and you don't have to worry about touching any code to change the output.
Your class should ideally provide the data only. Use another PHP file or generic class to output HTML, so later you could output e.g. XML, JSON, etc from the same data class. This separates your data processing (model/controller) from your data representation (view).
I would disagree with using a template engine like Smarty. PHP is a template engine.
You can use output buffering. It's helping to build your templates and not be forced to process data in the display order.
<?php
$posts = take_data_from_class();
ob_start();
require_once('path/to/posts.php');
$html_posts = ob_get_clean();
// you can do the same with other parts like header or footer
ob_start();
require_once('path/to/header.php');
$header = ob_get_clean();
ob_start();
require_once('path/to/footer.php');
$footer = ob_get_clean();
?>
In posts.php you can display the posts:
<? foreach ($posts as $p) { ?>
<div class="...">
post data here
</div>
<? } ?>
Now, to display the whole thing:
<?php echo $header . $html_posts . $footer; ?>
More at http://us3.php.net/manual/en/book.outcontrol.php
Enjoy!
Im not familiar with Smarty at all...how exactly does that work, and what are the benefits of using a smarty vs. just creating functions to take large amounts of data and return html containing that data just to be echoed later?
So I had a question on general organization of code for the Zend framework with regard to the layout.
My layout is basically this:
(LAYOUT.PHTML)
<div id='header'>
<?= $this->Layout()->header ?>
</div>
<div id='main'>
<?= $this->Layout()->main ?>
</div>
<div id='footer'>
<?= $this->Layout()->footer ?>
</div>
and so on and so forth. Now, in order to keep my code in my header separate from the code of my main and the code of my footer, I've created a folder for my view that holds header.phtml, main.phtml, footer.phtml. I then use this code to assign the content of header.phtml into $this->layout()->header:
(INDEX.PHTML)
$this->Layout()->header = file_get_contents('index/header.phtml');
$this->Layout()->main = file_get_contents('index/main.phtml');
$this->Layout()->footer = file_get_contents('index/footer.phtml');
That was working great, but I've hit a point where I don't want main to be static HTML anymore. I would like to be able to insert some values with PHP. So in my Controller in indexAction, I want to be able to load from my database and put values into index/main.phtml. Is there a way to do this without restructuring my site?
If not is there a way to do it so that I can have:
The ability to put code into different sections of my layout, such as Layout()->header, Layout->footer.
Separate these pieces into different files, so that they're easy to find and organize, like my index/footer.phtml, index/main.phtml etc.
Not have to put that code into quotes unnecessarily to turn it into a string to pass it to Layout()->header etc.
Thank you guys so much for your help.
-Ethan
Here is an idea:
Assign layout()->header the filename instead of the contents.
Put your code in this file
In your layout file, include() or require() the layout->header().
Since your layout headers/footers are now parsed, you can use them just like a view.
The ->header in $this->layout()->header is response segment. You can render parts of response using $this->_helper->viewRenderer->setResponseSegment('header'); in an action.
If you use
$this->layout()->header = $this->render('index/header.phtml');
It will even use the view, therefore keeping all your variables defined when rendering the header.
I would suggest using something like
<?php echo ($header = $this->layout()->header)?
$header : $this->render('headerDefault.phtml'); ?>
in your layout file - it will render a default header from the layout folder if the view script doesn't override it.
Have you tried looking at view helpers. They are a way of structuring view logic into reusable and modular code. In this case you would use a view helper to generate each of your required segments. So your example view script would look like
$this->Layout()->header = $this->header();
$this->Layout()->main = $this->main();
$this->Layout()->footer = $this->footer();
The benefit of using view helpers over include and require statements is that all of the file handling and name resolution is handled by the framework. The manual has more information on how to set up the paths and usage examples etc.
helpers are good. Another option is like the above, putting filenames in header/footer - put the template names and use $this->render($this->layout()->header)), etc etc. This is just like the include/require above, but more consistent.