Sajnálatos módon nem vagyok programozó, de lelkesen dolgozok a probélma megolsásán. És rendszerint, bár egy szakmabelihez képset lassabban, de eljutok a megoldáshoz. Így volt ez ebben az esetben is.
Mi történik, ha egy cikk elérését pl. migráció után a Joomla megváltoztatja? Megpróbálhatjuk az error.php módosításával visszakeresni a hiányzónak vélt, de mégis létező cikket (amennyiben a cikk alias-a változatlan):
if($this->error->getCode()==404)
{
$uri = JFactory::getUri();
$pathA = explode('/', ltrim($uri->getPath(),'/'));
if(count($pathA)==2 && $pathA[0]=='cikkek')
{
$this->_db = JFactory::getDBO();
$query = $this->_db->getQuery(true);
$query->select('*')
->from('#__content')
->where('alias='.$this->_db->q($pathA[1]));
$this->_db->setQuery($query);
$article = $this->_db->loadObject();
if($article)
{
$url = JRoute::_('index.php?option=com_content&view=article&id='.$article->id.'&catid='.$article->catid);
JFactory::getApplication()->redirect($url, null, null, true);
}
}
}
Az alábbi megoldással lehet egy teljes oldalra érvényes vagy akár egyedi almenük megadásával is jobb kattintásos menüt létrehozni a weboldalon.
A működéshez 3 részre van szükség:
HTML kód (alap):
<body oncontextmenu="return false">
<div onmousedown="HideMenu('contextMenu-<?=id?>');" onmouseup="HideMenu('.cmmenu');" oncontextmenu="ShowMenu('contextMenu-<?=id?>',event);">...</div>
Illetve a menü szerkezete:
<div style="display:none;" class="cmmenu" id="contextMenu-<?=$id?>">
<div class="ContextItem">Menü 1</div>
<div class="ContextItem">Menü 2</div>
</div>
Ehhez a szükséges CSS:
div[id^="contextMenu"] {
background-color: #ffffff;
border: 1px solid #cccccc;
box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.1);
padding: 10px 0;
position: absolute;
top: 0;
left: 0;
width: 200px;
}
.ContextItem {
cursor: pointer;
padding: 8px 15px;
}
.ContextItem:hover {
background-color: #f8f8f8;
}
.ContextItem a {
text-decoration:none;
}
És a legfontosabb, maga a script:
<script language="javascript" type="text/javascript">
function ShowMenu(control, e) {
var posx = e.clientX +window.pageXOffset +'px'; //Left Position of Mouse Pointer
var posy = e.clientY + window.pageYOffset + 'px'; //Top Position of Mouse Pointer
document.getElementById(control).style.position = 'absolute';
document.getElementById(control).style.display = 'inline';
document.getElementById(control).style.left = posx;
document.getElementById(control).style.top = posy;
}
function HideMenu(control) {
document.querySelectorAll(control).forEach(a=>a.style.display = "none");
}
</script>
Néhány szó a működésről:
A fenti kód eredetijét a codeproject.com-on találtam, de az igényeknek és a szélesebb körű felhasználhatóságnak mefgelelően módosítottam.
A "body"-ban elhelyezett "oncontextmenu " paraméter letiltja az oldalon a böngésző saját jobb klikke menüjét.
Ahogyan látható, a context menüt indító hívásokat a legfelső részben kell elhelyezni ahol szeretnénk használni. Ha a teljes oldal, lehet a body vagy valamely "container", ha php-ből foreach-el vagy valamilyen más ciklussal lérehozott soroknál van rá szükség, akkor az adott sor vezérlőjébe kell betenni az első kódblokkot. Itt jelezve is van, pl. hogyan lehet egyedivé tenni az ID-t, hogy a menü és a vezérlés csak rá vonatkozzon.
A "cmenu" osztály bejegyzésre való váltás azért szükséges, hogy bármely más sorra kattintva be lehessen zárni a megnyitott menüt.
A script maga pedig lekéri az egér aktuális pozícióját, majd a paraméterben átadott ID (control) stílusát módosítja. Hogy ne legyen összeakadás, hogy mikor melyik funkciót indítsa, erről gondoskodik az "onmousedown" és az "onmouseup" esemény kezelők. Nyitáshoz pedig az "oncontextmenu" paraméter van használva. Ez direktben a context menü megnyitási szándékra indítja a függvényt.
Volt rá igény, úgyhogy lássuk a megoldást.
Egy oldalon nem minden tartalom rendelkezik önálló menüponttal. Azonban ilyenkor az oldal title szövege a cikk címe lesz. Ha szeretnénk ezt egyedileg megadni, két dolgot kell megtennünk.
Fel kell venni egy egyedi mezőt (field) ami típusát tekintve vagy sima text vagy nem beállított.
A field-nek elérhetőnek kell lenni az adott cikkeknél.
Ha ez megtörtént, akkor a cikk nézet (com_content > article view) sablon felülírásának elejére tegyük be a következő kódot:
JLoader::register('FieldsHelper', JPATH_ADMINISTRATOR . '/components/com_fields/helpers/fields.php');
foreach($this->item->jcfields as $jcfield)
{
$item->jcFields[$jcfield->name] = $jcfield;
}
$browserbar = $item->jcFields['fieldneve']->rawvalue;
$document = JFactory::getDocument();
$document->setTitle($browserbar);
Természetesen a 'fieldneve' az általunk megadott field név legyen (az alias, nem pedig a megadott, akár ékezetes elnevezés, ami a label!)
Nem rég találkoztam egy olyan problémával, ami miatt a Joomla - VirtueMart (custom field) kiválasztó rádiógombt kellett átdizájnolni... tekintve, hogy a kód elég kötött megpróbáltam leginkább CSS-ből megoldani a problémát.
A minap volt olyan problémám, hogy egy adminban választó mező értékéhez kellett egyedi class-t adni, hogy frontenden a megjelenésnél lehessen a színnel "játszani".
A legegyszerűbbnek az tűnt, ha a kódot kiegészítem és a választott értéknek megfelelő elnevezésű class-t adom hozzá. Igen ám, de az érték elnevezése tartalmazhat ékezetet, szünetet és speciális írásjeleket is, ezért át kellett alakítani, hogy ezek a karakterek ne kerüljenek bele.
Számos megoldást lehet találni, ahol pl. preg_replace vagy foreach megadással mennek végig a tartalmakon, ami feltehetően itt is működne, de ha a Joomla alapból tudja miért ne azt használjam?
Csupán ennyi kellett:
jimport('joomla.filter.output');
$class = JFilterOutput::stringURLSafe($label);
Weboldalon elhelyezett térkép esetében a mobil eszközök térnyerése miatt egyre nagyobb jelentőséget kap a linket térkép mobil alkalmazásban való megnyitása. Természetesen a legjobb egy olyan megoldás, amivel szét tudjuk választani, hogy PC-n továbbra is böngészőben lehessen megtekinteni a térképet, míg mobil eszközön a telepített akalmazással nyíljon meg, ezzel is elősegítve, hogy szükség esetén könnyen és gyorsan lehessen navigációhoz használni.
Az alábbi egyszerű script oldalba ágyazásával a feladat jól megoldható:
function mapsSelector() {
if /* Ha iOS-t használ, Apple Maps-ben nyílik meg */
((navigator.platform.indexOf("iPhone") != -1) ||
(navigator.platform.indexOf("iPad") != -1) ||
(navigator.platform.indexOf("iPod") != -1))
window.open("maps:https://goo.gl/maps/7gGV1YgG4spKBmcX7");
else /* ha nem mobil, normál link */
window.open("https://goo.gl/maps/7gGV1YgG4spKBmcX7");
}
Ezt követően minden szükséges helyen a következő módon linkeljük:
<a href="#" onClick="mapsSelector()">Térkép</a>
Hátránya, hogy a linket a Google nem tudja indexelni, de talán ez a legkevesebb...
Belefutottam a minap egy olyan problémába, hogy egy kiegészítő csak akkor jelenített meg képet, ha volt megadott. Viszont nem lehetett helyetteítő vagy dummy képet megadni, így ha nem volt feltöltve, az oldal megjelenés nem volt egységes, némileg szétcsúszott.
Erre született ez a megoldás:
preg_match('/custom_img="(.*?)"/', $element['attributes'], $dummyimage);
$image['link'] = $image['link'] ==''?$dummyimage:'';
Az alábbi kód a Yootheme Pro sablonhoz született, segítségével az "attribútumok" mezőben meg lehet adni a dummy image linkjét, amit ha nincs beállított kép, behelyettesít .
Párszor belefutottam a problémába, hogy videomegosztóról be kell ágyazni a tartalmat, amihez vagy valamilyen shortcode kiegészítőt, vagy egyéb szerkesztő kiegészítőt használatam. Azonban előfordul, hogy 1-1 video miatt nincs kedvem feltenni egy komplett kiegészítőt (pláne azt is frissítgetni...)
Erre itt egy gyorsabb, egyszerűbb megoldás.
Az alábbi CSS-t helyezzük el a sablon CSS felülírásába (vagy template.css-be, vagy máshova, ahonnan a rendszer képes azt betölteni):
.video-responsive{
overflow:hidden;
padding-bottom:56.25%;
position:relative;
height:0;
}
.video-responsive iframe{
left:0;
top:0;
height:100%;
width:100%;
position:absolute;
}
Majd a videó beágyazásnál használjuk ezt a formát (minta Youttube-al):
<div class="video-responsive">
<iframe width="420" height="315" src="#" frameborder="0" allowfullscreen></iframe>
</div>
Egy munka során merült fel igény termékekhez tájékoztató dokumentum feltöltés, amit azután a vásárló korlátozás nélkül le tud tölteni. A neten található mindenféle megoldás, amik általában többet tudnak mint ami minimálisan szükséges, viszont cseréve jellemzően 19-49$ áron érhető el, néhány esetben még tesztelni sem lehet.
Az alábbi megoldás J 3.x és VM 3.x pároson működik. Továbbfejleszthető...
Egyedi mező felvitele
A Custom fileds (egyedi mezők) menüben vegyünk fel egy új egyedi mezőt:
- Típus: String
- Title (cím): File / Letöltés / stb. (ez lesz a mező csoport elnevezése)
- Layout position: file
Egyedi mező létrehozás, felülírás sablonból
Ha ez meg van, készítsünk sablon felülírást erről a fileról (ha még nincs):
components > com_virtuemart > views > productdetails > default.php
ide:
templates > [saját sablon neve] > html > com_virtuemart > productdetails > default.php
Egyes sablonoknál előfordul, hogy a VM fájlok felül vannak írva, ezek esetében meg kell keresnünk a legjobb helyet a letölthető fájl(ok)nak.
Egyedi mező beillesztés
<?php// custom file
$product = $this->product;
$position = 'file';$class = 'product-fields';
if (!empty($product->customfieldsSorted[$position])) {
$custom_title = null;
foreach ($product->customfieldsSorted[$position] as $field) {
if ( $field->is_hidden ) continue; ?>
<div class="product-field product-field-type-<?php echo $field->field_type ?>">
<?php if (!$customTitle and $field->custom_title != $custom_title and $field->show_title) { ?>
<span class="product-fields-title-wrapper"><span class="product-fields-title"><strong><?php echo vmText::_ ($field->custom_title) ?></strong></span>
<?php if ($field->custom_tip) {
echo JHtml::tooltip ($field->custom_tip, vmText::_ ($field->custom_title), 'tooltip.png');
} ?></span>
<?php }
if (!empty($field->display)){
$filestring = $field->display;
if (!strpos($filestring,'|')) {
?>
<div class="product-field-display"><a href="/images/stories/virtuemart/pdf/<?php echo $field->display; ?>">file download</a></div>
<?php
} else {
$file = array();
$file = explode("|",$filestring);?>
<div class="product-field-display">
<a href="/images/stories/virtuemart/pdf/<?php echo $file[1] ?>"><?php echo $file[0]; ?></a>
</div><?php
> }}
if (!empty($field->custom_desc)) {
?>
<div class="product-field-desc"><?php echo vmText::_($field->custom_desc) ?></div>
<?php } ?>
</div>
<?php }} // custom file end ?>
A kódot értelem szerint oda tegyük, ahol a tartalmat meg szeretnénk jeleníteni. A kód alapvető formázáshoz szükséges osztályokkal is rendelkezik, amik kiolvashatók.
Működés
A letölthető állományokat a "images/stories/virtuemart/pdf/" könyvtárba kell helyezni.
Termék oldalon hozzá adjuk a létrehozott egyedi mezőt.
A mező értéke egyszerű esetben a fájlnév. Ebben az esetben a "Download file" felirat jelenik meg. (Nyelvi változóval helyettesíthető)
Ha szeretnénk egyedi címet adni, azt ilyen formában tehetjük:
állomány cím|filenev.file
Azaz a név és a fájlnév közé tegyünk egy | (pipe) jelet.