How do I add a class name to <li> from Zend Navigation XML - zend-framework

Can someone please help me out, I'm totally stuck! I don't know how to add a class name to <li> tag in Zend navigation XML
This is my XML
<configdata>
<nav>
<home>
<label>Home </label>
<uri>/</uri>
</home>
<request>
<label>Quotes </label>
<uri>/quote</uri>
</request>
<work>
<label>How It Works</label>
<uri>/how-it-works</uri>
</work>
<information>
<label>Informations </label>
<uri>/informations</uri>
</information>
<directory>
<class> last </class>
<label>Directory </label>
<uri>/directory</uri>
</directory>
</nav>
</configdata>
When I add <class>last</class> this is what i get:
<li>
<a class="last" href="/directory">Directory </a>
</li>
Currently I'm getting <a class="last"> but I need <li class="last">
Thanks so much in advance!
Cheers

I think that the best way to put css classes into li elements would be to write your own navigation menu helper, called for example My_View_Helper_NavigationMenu that extends original Zend_View_Helper_Navigation_Menu class. For this reason I prepared an example of such a helper that overloads _renderMenu() method. The code of the method seems long, but this is because original code is long. There are only few new/modified lines in overloaded _renderMenu():
File: APPLICATION_PATH/views/helpers/NavigationMenu.php
class My_View_Helper_NavigationMenu extends Zend_View_Helper_Navigation_Menu {
/**
* Renders a normal menu (called from {#link renderMenu()})
*
* #param Zend_Navigation_Container $container container to render
* #param string $ulClass CSS class for first UL
* #param string $indent initial indentation
* #param int|null $minDepth minimum depth
* #param int|null $maxDepth maximum depth
* #param bool $onlyActive render only active branch?
* #return string
*/
protected function _renderMenu(Zend_Navigation_Container $container,
$ulClass,
$indent,
$minDepth,
$maxDepth,
$onlyActive)
{
$html = '';
// find deepest active
if ($found = $this->findActive($container, $minDepth, $maxDepth)) {
$foundPage = $found['page'];
$foundDepth = $found['depth'];
} else {
$foundPage = null;
}
// create iterator
$iterator = new RecursiveIteratorIterator($container,
RecursiveIteratorIterator::SELF_FIRST);
if (is_int($maxDepth)) {
$iterator->setMaxDepth($maxDepth);
}
// iterate container
$prevDepth = -1;
foreach ($iterator as $page) {
$depth = $iterator->getDepth();
$isActive = $page->isActive(true);
if ($depth < $minDepth || !$this->accept($page)) {
// page is below minDepth or not accepted by acl/visibilty
continue;
} else if ($onlyActive && !$isActive) {
// page is not active itself, but might be in the active branch
$accept = false;
if ($foundPage) {
if ($foundPage->hasPage($page)) {
// accept if page is a direct child of the active page
$accept = true;
} else if ($foundPage->getParent()->hasPage($page)) {
// page is a sibling of the active page...
if (!$foundPage->hasPages() ||
is_int($maxDepth) && $foundDepth + 1 > $maxDepth) {
// accept if active page has no children, or the
// children are too deep to be rendered
$accept = true;
}
}
}
if (!$accept) {
continue;
}
}
// make sure indentation is correct
$depth -= $minDepth;
$myIndent = $indent . str_repeat(' ', $depth);
if ($depth > $prevDepth) {
// start new ul tag
if ($ulClass && $depth == 0) {
$ulClass = ' class="' . $ulClass . '"';
} else {
$ulClass = '';
}
$html .= $myIndent . '<ul' . $ulClass . '>' . self::EOL;
} else if ($prevDepth > $depth) {
// close li/ul tags until we're at current depth
for ($i = $prevDepth; $i > $depth; $i--) {
$ind = $indent . str_repeat(' ', $i);
$html .= $ind . ' </li>' . self::EOL;
$html .= $ind . '</ul>' . self::EOL;
}
// close previous li tag
$html .= $myIndent . ' </li>' . self::EOL;
} else {
// close previous li tag
$html .= $myIndent . ' </li>' . self::EOL;
}
// ***************** THESE ARE NEW LINES *************** //
$liMyClass = $page->get('liclass') ? $page->liclass : '' ;
if ($isActive) {
$liClass = " class=\"active $liMyClass\" ";
} else {
$liClass = $liMyClass ? " class=\"$liMyClass\" ":'';
}
// ***************** END OF NEW STUFF *************** //
// render li tag and page (ORGINAL LINE REMOVED)
//$liClass = $isActive ? ' class="active "' : '';
$html .= $myIndent . ' <li' . $liClass . '>' . self::EOL
. $myIndent . ' ' . $this->htmlify($page) . self::EOL;
// store as previous depth for next iteration
$prevDepth = $depth;
}
if ($html) {
// done iterating container; close open ul/li tags
for ($i = $prevDepth+1; $i > 0; $i--) {
$myIndent = $indent . str_repeat(' ', $i-1);
$html .= $myIndent . ' </li>' . self::EOL
. $myIndent . '</ul>' . self::EOL;
}
$html = rtrim($html, self::EOL);
}
return $html;
}
}
In your layout.phtml you need to indicate to the navigation view helper to use this new class. You can do this as follows:
<?php $this->navigation()->setDefaultProxy('navigationMenu'); ?>;
Finally in your navigation.xml you could define a class for a li element using liclass tag (you can use whatever name you want for this tag):
<directory>
<class> last </class>
<label>Directory </label>
<uri>/directory</uri>
<liclass>someclass</liclass>
</directory>
Hopefully this will be helpful to you. Ideally, I should have named the new class My_View_Helper_Navigation_Menu (located in APPLICATION_PATH/views/helpers/Navigation/Menu.php). However, I could not make Zend plugin loaders to load it and I went with My_View_Helper_NavigationMenu.

Related

replace text with url in twitter feed

I have this code:
public function linkify($status_text)
{
$status_text = preg_replace('/(https?:\/\/\S+)/','\1', $status_text);
$status_text = preg_replace('/(^|\s)#(\w+)/','\1#\2',$status_text);
$status_text = preg_replace('/(^|\s)#(\w+)/','\1#\2',$status_text);
return $status_text;
}
and display feeds from twitter like this
foreach($feed as $feed_item) {
$html .= '<li>';
$html .= '' . $this->linkify($feed_item->text) . '';
$html .= '' . $this->relativedate((strtotime($feed_item->created_at))) . '';
$html .= '</li>';
}
echo $html;
result of this code is
<li>Twitter Feed Text http://t.co/TnkNfxCdRu</li>
if anyone can help me, how can I add text inside tag <a></a>. for example, to be exactly like this:
<li>Twitter Feed Text</li>
Thank you so much
Just change your first preg_replace to:
$status_text = preg_replace('~(https?://(\S+))~','$2',$status_text);

Zend Framework 2 form element error-class + custom ViewHelper to render form

This is my third question this week (and overall) - hope I don't get banned here :D
Anyway, searched around and couldn't find an exact explanation to solve my issue(s).
A. I've searched around and found a custom ViewHelper to render my forms. What it does is recursively get all fieldsets and when it gets to the element level, it goes like this:
public function renderElement($element) {
$html = '
<div class="row">' .
'<label class="col-md-12" for="' . $element->getAttribute('id') . '">' . $element->getLabel() . '</label>' .
$this->view->formElement($element) .
$this->view->FormElementErrors($element) .
'<div class="clearfix" style="height: 15px;"></div>';
return $html . PHP_EOL;
}
Form renders ok, except:
1) How can I add an error class to the form element? (like if I use formRow helper in my view, it automatically ads an 'input-error' class, while also keeping the initial class specified in my fieldset when creating the element - 'attributes' => array('class' => 'some-class')), so the element's class attribute becomes "some-class input-error" in case it's invalid.
2) How can I set a class for the 'ul' containing the error messages (the 'ul' rendered by $this->view->FormElementErrors($element))? Hope this is a one-liner and I don't have to go message-by-message and compose the html for the error messages list, but if not so be it (I don't know how to do that either).
B. Let's say that sometimes I don't use this custom ViewHelper to render my form. Zend's formRow view helper can be handy sometimes. This brings me to the following code in my view:
echo $this->formRow($this->form->get('user_fieldset')->get('user_name'));
I've noticed this automatically adds 'input-error' class on my element (in case it's invalid) which is perfect, BUT how can I also tell formRow to give a class to the 'ul' that's displaying the error messages?
I'd go even further and ask how I can turn this:
echo $this->formLabel($this->form->get('user_fieldset')->get('user_name'));
echo $this->formInput($this->form->get('user_fieldset')->get('user_name'));
echo $this->formElementErrors($this->form->get('user_fieldset')->get('user_name'), array('class' => 'form-validation-error'));
into something that ads an error-class to the element as well, not just to the error messages list, but if anyone answers to point A I think it's the same issue.
I've managed to do it like this:
public function renderElement($element) {
// FORM ROW
$html = '<div class="form-group">';
// LABEL
$html .= '<label class="form-label" for="' . $element->getAttribute('id') . '">' . $element->getLabel() . '</label>';
// ELEMENT
/*
- Check if element has error messages
- If it does, add my error-class to the element's existing one(s),
to style the element differently on error
*/
if (count($element->getMessages()) > 0) {
$classAttribute = ($element->hasAttribute('class') ? $element->getAttribute('class') . ' ' : '');
$classAttribute .= 'input-error';
/*
* Normally, here I would have added a space in my string (' input-error')
* Logically, I would figure that if the element already has a class "cls"
* and I would do $element->getAttribute('class') . 'another-class'
* then the class attribute would become "clsanother-class"
* BUT it seems that, even if I don't intentionally add a space in my string,
* I still get "cls another-class" as the resulted concatenated string
* I assume that when building the form, ZF2 automatically
* adds spaces after attributes values? so you/it won't have to
* consider that later, when you'd eventually need to add another
* value to an attribute?
*/
$element->setAttribute('class', $classAttribute);
}
$html .= $this->view->formElement($element);
/*
* Of course, you could decide/need to do things differently,
* depending on the element's type
switch ($element->getAttribute('type')) {
case 'text':
case 'email': {
break;
}
default: {
}
}
*/
// ERROR MESSAGES
// Custom class (.form-validation-error) for the default html wrapper - <ul>
$html .= $this->view->FormElementErrors($element, array('class' => 'form-validation-error'));
$html .= '</div>'; # /.form-group
$html .= '<div class="clearfix" style="height: 15px;"></div>';
return $html . PHP_EOL;
}
I'm not to fond of this, but I suppose there is no shorter way. I thought ZF2 shoud have something like:
if ($element->hasErrors()) { $element->addClass('some-class'); }
right out of the box. That's the answer I would have expected, that it would simply be a method I missed/couldn't find. But it turns out that ZF2 doesn't have quite anything in the whole world that you might need right out of the box, you end up having to write the (more or less) occasional helpers.
Anyway, if someone ever needs it here's the entire RenderForm view helper:
namespace User\View\Helper;
use Zend\View\Helper\AbstractHelper;
class RenderForm extends AbstractHelper {
public function __invoke($form) {
$form->prepare();
$html = $this->view->form()->openTag($form) . PHP_EOL;
$html .= $this->renderFieldsets($form->getFieldsets());
$html .= $this->renderElements($form->getElements());
$html .= $this->view->form()->closeTag($form) . PHP_EOL;
return $html;
}
public function renderFieldsets($fieldsets) {
foreach ($fieldsets as $fieldset) {
if (count($fieldset->getFieldsets()) > 0) {
$html = $this->renderFieldsets($fieldset->getFieldsets());
} else {
$html = '<fieldset>';
// You can use fieldset's name for the legend (if that's not inappropriate)
$html .= '<legend>' . ucfirst($fieldset->getName()) . '</legend>';
// or it's label (if you had set one)
// $html .= '<legend>' . ucfirst($fieldset->getLabel()) . '</legend>';
$html .= $this->renderElements($fieldset->getElements());
$html .= '</fieldset>';
// I actually never use the <fieldset> html tag.
// Feel free to use anything you like, if you do have to
// make grouping certain elements stand out to the user
}
}
return $html;
}
public function renderElements($elements) {
$html = '';
foreach ($elements as $element) {
$html .= $this->renderElement($element);
}
return $html;
}
public function renderElement($element) {
// FORM ROW
$html = '<div class="form-group">';
// LABEL
$html .= '<label class="form-label" for="' . $element->getAttribute('id') . '">' . $element->getLabel() . '</label>'; # add translation here
// ELEMENT
/*
- Check if element has error messages
- If it does, add my error-class to the element's existing one(s),
to style the element differently on error
*/
if (count($element->getMessages()) > 0) {
$classAttribute = ($element->hasAttribute('class') ? $element->getAttribute('class') . ' ' : '');
$classAttribute .= 'input-error';
$element->setAttribute('class', $classAttribute);
}
$html .= $this->view->formElement($element);
// ERROR MESSAGES
$html .= $this->view->FormElementErrors($element, array('class' => 'form-validation-error'));
$html .= '</div>'; # /.row
$html .= '<div class="clearfix" style="height: 15px;"></div>';
return $html . PHP_EOL;
}
}
User is my module. I've created a 'viewhelper.config.php' in it's config folder:
return array(
'invokables' => array(
'renderForm' => 'User\View\Helper\RenderForm',
),
);
and in Module.php:
public function getViewHelperConfig() {
return include __DIR__ . '/config/viewhelper.config.php';
}
Then, in your view simply call:
$this->renderForm($form);
Of course, if you don't have many view helpers, you could not create a separate config file just for that, leave Module.php alone and simply add:
'view_helpers' => array(
'invokables' => array(
'renderForm' => 'User\View\Helper\RenderForm',
),
),
to any configuration file.
I use getMessages() method to check if an element has an validation message. for eg.
<div class="form-group <?=($this->form->get('user_fieldset')->get('user_name')->getMessages())?'has-error':'';?>">
...
</div>
This question seems to be very old and you must have solved it by yourself. :)

zend search lucence return hit id of search insted id of field

i have poblem zend search lucence :
zend search lucence return hit id of search insted id of field.for example:
i have this codde in Yii controller for create index of news data:
public function createNewsIndex()
{
setlocale(LC_CTYPE, 'de_DE.iso-8859-1');
Zend_Search_Lucene_Analysis_Analyzer_Common_TextNum_CaseInsensitive::setDefault(new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8());
Zend_Search_Lucene_Analysis_Analyzer::setDefault(new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8_CaseInsensitive());
$index = new Zend_Search_Lucene(Yii::getPathOfAlias('application.' . $this->_indexFiles.'.news'), true);
$news= News::model()->findAll();
foreach ($news as $newsItem) {
$news_doc=new Zend_Search_Lucene_Document();
$news_doc->addField(Zend_Search_Lucene_Field::Text('id',CHtml::encode($newsItem->id),'utf-8'));
$news_doc->addField(Zend_Search_Lucene_Field::Text('title',CHtml::encode($newsItem->title),'utf-8'));
$news_doc->addField(Zend_Search_Lucene_Field::Text('keywords',CHtml::encode($newsItem->keywords),'utf-8'));
$index->addDocument($news_doc);
}
$index->commit();
$index->optimize();
}
i have this code for search news :
public function searchNews($term) {
setlocale(LC_CTYPE, 'de_DE.iso-8859-1');
Zend_Search_Lucene_Analysis_Analyzer_Common_TextNum_CaseInsensitive::setDefault(new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8());
Zend_Search_Lucene_Analysis_Analyzer::setDefault(new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8_CaseInsensitive());
try
{
$index = new Zend_Search_Lucene(Yii::getPathOfAlias('application.' . $this->_indexFiles . '.news'));
}
catch(Zend_Search_Lucene_Exception $e)
{
$this->createNewsIndex();
$index = new Zend_Search_Lucene(Yii::getPathOfAlias('application.' . $this->_indexFiles . '.news'));
}
$query = Zend_Search_Lucene_Search_QueryParser::parse($term);
$results = $index->find($term . '*');
$this->render('search', array(
'results' => $results,
)
}
and this code in view:
<?php foreach ($results as $result)
{
print "ID: " . $result->id . "\n";
print "Score: " . $result->title . "\n<br>";
print CHtml::link(CHtml::encode($result->title), array($controller.'/view', 'id'=>$result->id));
}
?>
i want $result->id be id of this news title but I think this is a hit ID of I think this is a test Aht ID. hit in find function according this link:(see find function)
http://phpcrossref.com/zendframework/library/Zend/Search/Lucene.php.html
.
Sorry for weak English.
i fix problem by rename id field name:
$news_doc->addField(Zend_Search_Lucene_Field::Text('news_id',CHtml::encode($newsItem->id),'utf-8'));
and in view:
<?php foreach ($results as $result)
{
print "ID: " . $result->news_id . "\n";
print "Score: " . $result->title . "\n<br>";
print CHtml::link(CHtml::encode($result->title), array($controller.'/view', 'id'=>$result->news_id));
}
?>

Zend - How do I combine a form and pagination in the same view

This is probably simpler that it seems but I am stumped. I have a simple controller that builds a small form for inputting parameters. When the form is submitted, the same page is redrawn with the same form at the top but with a paginated view of results under it. My controller is here:
public function indexAction()
{
$form = new Application_Form_Battery();
$request = $this->getRequest();
if ($request->isPost()) {
$data = $request->getPost();
$form->populate($data);
// get the data
Zend_View_Helper_PaginationControl::setDefaultViewPartial('pagination.phtml');
$reportsTBL = new Model_DBTable_Reports();
$paginator = new Zend_Paginator(new Zend_Paginator_Adapter_Array($reportsTBL->getBatteryLog($data)));
$paginator->setCurrentPageNumber($this->_getParam('page',1))
->setItemCountPerPage(50);
$this->view->paginator = $paginator;
}
$this->view->form = $form;
}
As you can see, after the form is submitted, the paginated results are overwritten by the view->form statement... How can I combine them after form submit? I can't have two view calls...
Some thing like untested here,
indexController
public function indexAction()
{
.....
$_category = new Admin_Model_DbTable_Category();
$category = $_category->browse($browseArray);
$this->view->vCount = count($category);
$paginator = Zend_Paginator::factory($category);
$page = ($postData['page'] > 0) ? $postData['page'] : 1;
$paginator->setCurrentPageNumber($page);
$paginator->setItemCountPerPage(10);
$paginator->setPageRange(5);
$this->view->categoryList = $paginator; // print_obj($paginator);
....
}
index.phtml
.....
<ul>
<?php if (count($this->categoryList) != 0) { ?>
<?php
foreach ($this->categoryList AS $key => $category) {
?>
<li>
<div >
<?php echo $category['name'] ?>
</div>
</li>
<?php } ?>
<li>
<div><?php echo "Total Category(" . $this->vCount . ")"; ?></div>
<div style="text-align:center;"><?php echo $this->paginationControl($this->categoryList, 'Sliding', 'pagination.phtml'); ?></div>
</li>
<?php } else { ?>
<li><div style="text-align:center;">No records found</div></li>
<?php } ?>
</ul>
...
Category.php
class Admin_Model_DbTable_Category extends Zend_Db_Table_Abstract
{
...
protected $_name = 'category';
protected $_primary = 'category_id';
public function browse($browseArray = array())
{
extract($browseArray);
$whereSQL = ' `parent` = 0 ';
if($category_id)
$whereSQL .= ' AND `category_id` = "'. $category_id .'"';
if($catname)
$whereSQL .= ' AND `name` = "'. $catname .'"';
if($name)
$whereSQL .= ' AND `name` LIKE "%'. $name .'%"';
if($description)
$whereSQL .= ' AND `description` LIKE "%'. $description .'%"';
if($status)
$whereSQL .= ' AND `status` = "'. $status .'"';
$select = $this->_db->select()
->from($this->_name)
->where($whereSQL);
$result = $this->getAdapter()->fetchAll($select);
return $result;
}
....
}
You can use general function named browse which will fetch result from table , by using the result we can paginate the data when page is rendering.
I solved it. I was using a view that called a form template and I was trying to display the paginated results on that form. I moved the paginated results to the actual view script and everything is solved.
Thanks for the help.

tt_news: Modify image src

In order to be able to use lazy loading, I need to modify the src attribute of tt_news' image output like so:
<img src="/foo/bar/baz.png" … /> // <-- before
<img data-original="/foo/bar/baz.png" … /> // <-- after, no src!
I have tried:
plugin.tt_news.displayList.content_stdWrap {
parseFunc < lib.parseFunc_RTE
HTMLparser = 1
HTMLparser.keepNonMatchedTags = 1
HTMLparser.tags.img.fixAttrib.src.unset = 1
}
but to no avail, since
The image in question is not being inserted via RTE, but the "normal" media integration.
That wouldn't copy the src attribute over to data-original before unsetting.
So, what should I do aside from pulling my hair out?
This cannot be solved via typoscript, because the src attribute is hard coded in the cImage function:
$theValue = '<img src="' . htmlspecialchars($GLOBALS['TSFE']->absRefPrefix .
t3lib_div::rawUrlEncodeFP($info[3])) . '" width="' . $info[0] . '" height="' . $info[1] . '"' .
$this->getBorderAttr(' border="' . intval($conf['border']) . '"') .
$params .
($altParam) . ' />';
The only way I see to modify the src attribute is through a user function. tt_news provides a hook for a user function that allows the custom processing of images (see line 2150 of class.tx_ttnews.php).
Example:
Insert the following typoscript:
includeLibs.user_ttnewsImageMarkerFunc = fileadmin/templates/php/user_ttnewsImageMarkerFunc.php
plugin.tt_news.imageMarkerFunc = user_ttnewsImageMarkerFunc->ttnewsImageMarkerFunc
Whereas the file user_ttnewsImageMarkerFunc.php contains:
<?php
class user_ttnewsImageMarkerFunc {
/**
* Fills the image markers with data.
*
* #param array $paramArray: $markerArray and $config of the current news item in an array
* #param [type] $conf: ...
* #return array the processed markerArray
*/
function ttnewsImageMarkerFunc($paramArray, $conf) {
$markerArray = $paramArray[0];
$lConf = $paramArray[1];
$pObj = &$conf['parentObj'];
$row = $pObj->local_cObj->data;
$imageNum = isset($lConf['imageCount']) ? $lConf['imageCount'] : 1;
$imageNum = t3lib_div::intInRange($imageNum, 0, 100);
$theImgCode = '';
$imgs = t3lib_div::trimExplode(',', $row['image'], 1);
$imgsCaptions = explode(chr(10), $row['imagecaption']);
$imgsAltTexts = explode(chr(10), $row['imagealttext']);
$imgsTitleTexts = explode(chr(10), $row['imagetitletext']);
reset($imgs);
if ($pObj->config['code'] == 'SINGLE') {
$markerArray = $this->getSingleViewImages($lConf, $imgs, $imgsCaptions, $imgsAltTexts, $imgsTitleTexts, $imageNum, $markerArray, $pObj);
} else {
$imageMode = (strpos($textRenderObj, 'LATEST') ? $lConf['latestImageMode'] : $lConf['listImageMode']);
$suf = '';
if (is_numeric(substr($lConf['image.']['file.']['maxW'], - 1))) { // 'm' or 'c' not set by TS
if ($imageMode) {
switch ($imageMode) {
case 'resize2max' :
$suf = 'm';
break;
case 'crop' :
$suf = 'c';
break;
case 'resize' :
$suf = '';
break;
}
}
}
// only insert width/height if it is not given by TS and width/height is empty
if ($lConf['image.']['file.']['maxW'] && ! $lConf['image.']['file.']['width']) {
$lConf['image.']['file.']['width'] = $lConf['image.']['file.']['maxW'] . $suf;
unset($lConf['image.']['file.']['maxW']);
}
if ($lConf['image.']['file.']['maxH'] && ! $lConf['image.']['file.']['height']) {
$lConf['image.']['file.']['height'] = $lConf['image.']['file.']['maxH'] . $suf;
unset($lConf['image.']['file.']['maxH']);
}
$cc = 0;
foreach ($imgs as $val) {
if ($cc == $imageNum)
break;
if ($val) {
$lConf['image.']['altText'] = $imgsAltTexts[$cc];
$lConf['image.']['titleText'] = $imgsTitleTexts[$cc];
$lConf['image.']['file'] = 'uploads/pics/' . $val;
$theImgCode .= str_replace('src="', 'class="lazy" data-original="', $pObj->local_cObj->IMAGE($lConf['image.'])) . $pObj->local_cObj->stdWrap($imgsCaptions[$cc], $lConf['caption_stdWrap.']);
}
$cc++;
}
if ($cc) {
$markerArray['###NEWS_IMAGE###'] = $pObj->local_cObj->wrap($theImgCode, $lConf['imageWrapIfAny']);
} else {
$markerArray['###NEWS_IMAGE###'] = $pObj->local_cObj->stdWrap($markerArray['###NEWS_IMAGE###'], $lConf['image.']['noImage_stdWrap.']);
}
}
if ($pObj->debugTimes) {
$pObj->hObj->getParsetime(__METHOD__);
}
// debug($markerArray, '$$markerArray ('.__CLASS__.'::'.__FUNCTION__.')', __LINE__, __FILE__, 2);
return $markerArray;
}
/**
* Fills the image markers for the SINGLE view with data. Supports Optionssplit for some parameters
*
* #param [type] $lConf: ...
* #param [type] $imgs: ...
* #param [type] $imgsCaptions: ...
* #param [type] $imgsAltTexts: ...
* #param [type] $imgsTitleTexts: ...
* #param [type] $imageNum: ...
* #return array $markerArray: filled markerarray
*/
function getSingleViewImages($lConf, $imgs, $imgsCaptions, $imgsAltTexts, $imgsTitleTexts, $imageNum, $markerArray, $pObj) {
$marker = 'NEWS_IMAGE';
$sViewSplitLConf = array();
$tmpMarkers = array();
$iC = count($imgs);
// remove first img from image array in single view if the TSvar firstImageIsPreview is set
if (($iC > 1 && $pObj->config['firstImageIsPreview']) || ($iC >= 1 && $pObj->config['forceFirstImageIsPreview'])) {
array_shift($imgs);
array_shift($imgsCaptions);
array_shift($imgsAltTexts);
array_shift($imgsTitleTexts);
$iC--;
}
if ($iC > $imageNum) {
$iC = $imageNum;
}
// get img array parts for single view pages
if ($pObj->piVars[$pObj->config['singleViewPointerName']]) {
/**
* TODO
* does this work with optionsplit ?
*/
$spage = $pObj->piVars[$pObj->config['singleViewPointerName']];
$astart = $imageNum * $spage;
$imgs = array_slice($imgs, $astart, $imageNum);
$imgsCaptions = array_slice($imgsCaptions, $astart, $imageNum);
$imgsAltTexts = array_slice($imgsAltTexts, $astart, $imageNum);
$imgsTitleTexts = array_slice($imgsTitleTexts, $astart, $imageNum);
}
if ($pObj->conf['enableOptionSplit']) {
if ($lConf['imageMarkerOptionSplit']) {
$ostmp = explode('|*|', $lConf['imageMarkerOptionSplit']);
$osCount = count($ostmp);
}
$sViewSplitLConf = $pObj->processOptionSplit($lConf, $iC);
}
// reset markers for optionSplitted images
for ($m = 1; $m <= $imageNum; $m++) {
$markerArray['###' . $marker . '_' . $m . '###'] = '';
}
$cc = 0;
foreach ($imgs as $val) {
if ($cc == $imageNum)
break;
if ($val) {
if (! empty($sViewSplitLConf[$cc])) {
$lConf = $sViewSplitLConf[$cc];
}
// if (1) {
// $lConf['image.']['imgList.'] = '';
// $lConf['image.']['imgList'] = $val;
// $lConf['image.']['imgPath'] = 'uploads/pics/';
// debug($lConf['image.'], ' ('.__CLASS__.'::'.__FUNCTION__.')', __LINE__, __FILE__, 3);
//
// $imgHtml = $pObj->local_cObj->IMGTEXT($lConf['image.']);
//
// } else {
$lConf['image.']['altText'] = $imgsAltTexts[$cc];
$lConf['image.']['titleText'] = $imgsTitleTexts[$cc];
$lConf['image.']['file'] = 'uploads/pics/' . $val;
$imgHtml = str_replace('src="', 'class="lazy" data-original="', $pObj->local_cObj->IMAGE($lConf['image.'])) . $pObj->local_cObj->stdWrap($imgsCaptions[$cc], $lConf['caption_stdWrap.']);
// }
//debug($imgHtml, '$imgHtml ('.__CLASS__.'::'.__FUNCTION__.')', __LINE__, __FILE__, 3);
if ($osCount) {
if ($iC > 1) {
$mName = '###' . $marker . '_' . $lConf['imageMarkerOptionSplit'] . '###';
} else { // fall back to the first image marker if only one image has been found
$mName = '###' . $marker . '_1###';
}
$tmpMarkers[$mName]['html'] .= $imgHtml;
$tmpMarkers[$mName]['wrap'] = $lConf['imageWrapIfAny'];
} else {
$theImgCode .= $imgHtml;
}
}
$cc++;
}
if ($cc) {
if ($osCount) {
foreach ($tmpMarkers as $mName => $res) {
$markerArray[$mName] = $pObj->local_cObj->wrap($res['html'], $res['wrap']);
}
} else {
$markerArray['###' . $marker . '###'] = $pObj->local_cObj->wrap($theImgCode, $lConf['imageWrapIfAny']);
}
} else {
if ($lConf['imageMarkerOptionSplit']) {
$m = '_1';
}
$markerArray['###' . $marker . $m . '###'] = $pObj->local_cObj->stdWrap($markerArray['###' . $marker . $m . '###'], $lConf['image.']['noImage_stdWrap.']);
}
// debug($sViewSplitLConf, '$sViewSplitLConf ('.__CLASS__.'::'.__FUNCTION__.')', __LINE__, __FILE__, 2);
return $markerArray;
}
}
?>
Most of this code is copied from class.tx_ttnews.php. The important line is the following (in each of the two functions):
str_replace('src="', 'class="lazy" data-original="', $pObj->local_cObj->IMAGE($lConf['image.']))
Then you'll get the following image tags:
<img class="lazy" data-original="uploads/pics/myimage.jpg" width="110" height="70" border="0" alt="" />
In 2019 tt_news is still around. I use it with TYPO3 8 LTS, the version from github as its not anymore in the official extension repository. (For new Projects use "news")
So I think, because tt_news has to be updated in TYPO3 9, its legit to just hack the code directly, by changing tt_news/Classes/Plugin/TtNews.php like this:
--- a/Classes/Plugin/TtNews.php
+++ b/Classes/Plugin/TtNews.php
## -2621,6 +2621,7 ## class TtNews extends AbstractPlugin
$markerArray['###NEWS_IMAGE###'] = $this->local_cObj->stdWrap($markerArray['###NEWS_IMAGE###'],
$lConf['image.']['noImage_stdWrap.']);
}
+ $markerArray['###NEWS_IMAGE###'] = $this->LazyLoading($markerArray['###NEWS_IMAGE###']);
}
}
## -2632,6 +2633,13 ## class TtNews extends AbstractPlugin
}
+ function LazyLoading($html){
+ $html = str_replace('src="', 'class="lazy" data-original="', $html);
+ return $html;
+ }
+
+
/**
* Fills the image markers for the SINGLE view with data. Supports Optionssplit for some parameters
*