menu with fontawesome icons in typo3 - menu

I try to implement an menu using fontawesome icons in typo3 8.7.13 .
My idea was to extend the table pages with the field tx_fontawesome_icon - no problem - it can be used in the page properties an is also saved in the database.
But how can I use it in the typoscript?
[ts]
lib.mainnav_mobile = HMENU
lib.mainnav_mobile {
wrap = <ul>|</ul>
1 = TMENU
1 {
expAll = 1
NO = 1
NO {
wrapItemAndSub =<li>|</li>
stdWrap.wrap = <i class="fas fa-home fa-2x"></i>|
stdWrap.htmlSpecialChars = 1
ATagTitle.field = title
ATagParams = class="home-link"
}
}
}
[/ts]
Thanks
Volker

I assume you store the complete iconname in the field. If you might skip the prefix, build the prefix in your wrap.
Your attempt with .stdWrap would be possible so I would prefer the property for this: .before
You can use something like this (fill in the rest of the menu definition):
:
NO {
:
before.cObject = TEXT
before.cObject {
field = tx_fontawesome_icon
## have a default icon:
ifEmpty = fa_home
noTrimWrap = |<i class="fas | fa-2x"></i>|
# if you want the icon to be linked too:
typoLink.parameter.field = uid
}
}
use .noTrimWrap so you stay with the spaces before and after the icon-name.
If the icon should be inside of only one link, you need to add the icon to the item text (page title).
Therefor you use .stdWrap.wrap as you started. but you need to build the wrap from a cObject (see above) or use a datawrap:
:
NO {
:
stdWrap.dataWrap = <i class="fas {field:tx_fontawesome} fa-2x"></i>|
:
}

the solution for me is:
lib.mainnav_mobile = HMENU
lib.mainnav_mobile {
wrap = <ul>|</ul>
1 = TMENU
1 {
expAll = 1
NO = 1
NO {
wrapItemAndSub =<li>|</li>
stdWrap.htmlSpecialChars = 1
ATagTitle.field = description // subtitle // title
ATagParams = class="home-link"
ATagBeforeWrap = 1
stdWrap.wrap.cObject = TEXT
stdWrap.wrap.cObject {
field = tx_fontawesome_icon
## have a default icon:
ifEmpty = fa-home
noTrimWrap = |<i class="fas | fa-2x"></i> |
}
}
Thanks for the help!
Volker

Related

Razor Pages: Passing query parameters in a link

I tried in the razor page:
<div>
#foreach (var cat in Model.Categories)
{
<a asp-page="/Index?catId=#cat.Id">#cat.Name</a>
}
</div>
And in the cs file:
public void OnGet()
{
CurPage = 1;
CatId = -1;
Search = "";
HasCarousel = false;
Title = "All Products";
var queryParams = Request.Query;
foreach(var qp in queryParams)
{
if (qp.Key == "curPage") CurPage = int.Parse(qp.Value);
if (qp.Key == "catId") CatId = int.Parse(qp.Value);
if (qp.Key == "search") Search = qp.Value;
if (qp.Key == "hasCarousel") HasCarousel = bool.Parse(qp.Value);
}
But when i click the link no query parameter is added to the address and the Request.Query is empty.
What am I doing wrong? Or what is the right way to pass the query parameters to a razor page via a link?
To add query parameters to your link you can use asp-route- in your a tag.
In your case it would look like
<a asp-page="Index" asp-route-catId="#cat.Id">#cat.Name</a>
You're also making receiving the query parameters in your OnGet() harder than it has to be. You can add parameters to your method signature like
OnGet(int catId)
and they will be passed in by the query parameters.

How to define new icons with winjs commands?

How to use an icon which is not provided by WinJS? For example, use one from here.
The html looks like:
<div data-win-control="WinJS.UI.SplitViewCommand" data-win-options="{ label: 'Home', icon: 'home'}"></div>
The png image should be 20x20 pixels with a transparent background (https://msdn.microsoft.com/en-us/library/windows/apps/hh700483.aspx). The png is set as in javascript:
document.getElementById("thatFancyButton").style.backgroundImage = url('pathOfPNGImage');
so in your case it is (notice \' \' in url()):
<div data-win-control="WinJS.UI.SplitViewCommand" data-win-options="{ label: 'Home', icon: 'url(\'pathOfPng.png\')'}"></div>
You can also set one letter glyphs like icon: '©' and it will show it as icon.
Below is the snippet of the SplitViewCommand icon setting logic:
/// <field type="String" locid="WinJS.UI.SplitViewCommand.icon" helpKeyword="WinJS.UI.SplitViewCommand.icon">
/// Gets or sets the icon of the SplitViewCommand. This value is either one of the values of the AppBarIcon enumeration or the path of a custom PNG file.
/// </field>
icon: {
get: function () {
return this._icon;
},
set: function (value) {
this._icon = (_Icon[value] || value);
// If the icon's a single character, presume a glyph
if (this._icon && this._icon.length === 1) {
// Set the glyph
this._imageSpan.textContent = this._icon;
this._imageSpan.style.backgroundImage = "";
this._imageSpan.style.msHighContrastAdjust = "";
this._imageSpan.style.display = "";
} else if (this._icon && this._icon.length > 1) {
// Must be an image, set that
this._imageSpan.textContent = "";
this._imageSpan.style.backgroundImage = this._icon;
this._imageSpan.style.msHighContrastAdjust = "none";
this._imageSpan.style.display = "";
} else {
this._imageSpan.textContent = "";
this._imageSpan.style.backgroundImage = "";
this._imageSpan.style.msHighContrastAdjust = "";
this._imageSpan.style.display = "none";
}
}
},
If you happen to have errors with the background image size, modify win-commandimage class. I did this fix in styles to fit the image into button correctly:
.win-commandimage {
background-size:contain;
}

Typo3: page link in menu using value from custom record

I have :
a 3 level menu
custom records from a table called
"tx_products_domain_model_product"
products have a field called "url_alias"
On any page on that menu, I can have a product record.
For pages that have a product record I want the link to look like:
http://www.sitedomain.com/<url_alias>
Can this be done with typoscript?
EDIT
It looks like it's too complex to do all this with typoscript, so I'm using a userFunc. I'm checking if there is a product record with a shop ID and want to return that shop id. If not, return the current menu page UID. The problem is, how can I pass the menu page UID as parameter to the userFunc?
class user_productsOnCurrentPage
{
function main( $content, $conf )
{
if ( TYPO3_MODE !== 'FE' )
{
return FALSE;
}
$product = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow(
'shop_id', 'tx_products_domain_model_product', 'pid=' . $conf['currentPageId'] . ' AND deleted=0 AND hidden=0' );
if ( is_array( $product ) && ! empty( $product ['shop_id'] ) )
{
return $product ['shop_id'];
}
return $conf['currentPageId'];
}
}
The menu:
lib.mainMenu = HMENU
lib.mainMenu {
...
1 = TMENU
1 {
...
NO = 1
NO {
...
# show direct url for external links
doNotLinkIt = 1
stdWrap.cObject = CASE
stdWrap.cObject {
key.field = doktype
default = TEXT
default {
field = nav_title // title
typolink.parameter.cObject = USER
typolink.parameter.cObject {
userFunc = user_productsOnCurrentPage->main
currentPageId = ?????
}
typolink.wrap = |<span><strong></strong></span>
typolink.ATagBeforeWrap = 1
stdWrap.htmlSpecialChars = 1
}
...
I could access the page ID directly in the user function:
TypoScript:
typolink.userFunc = user_mcfazabosOnCurrentPage->main
PHP:
$pageId = $this->cObj->getFieldVal( 'uid' );

onMouseOut effect fired when mouse cursor goes to child div.... I dont want to do that

Here is my code --
<li>
<a id="LoginTxt2" onmouseover="MouseOver(this);" onmouseout="MouseOut(this);" href="#">
<div style="background-color:#CCC;">OLD Text</div>
</a>
</li>
JS--
MouseOver = function(obj){
var id = obj.id;
document.getElementById(id).innerHTML='<div style="background-color:#DDD;">NEW Text</div>';
}
MouseOut = function(obj){
var id = obj.id;
document.getElementById(id).innerHTML="<div style="background-color:#CCC;">OLD Text</div>";
}
when my mouse goes to child div, MouseOut fierd i dont want to do that... plz help
This is the way the event works and there's no way of avoiding the MouseOut() function to be called. What you can do is check, inside the MouseOut() function, if the element you're now hovering is a child element of the outer element:
MouseOut = function(obj, event) {
// this is the original element the event handler was assigned to
var e = event.toElement || event.relatedTarget;
// check for all children levels (checking from bottom up)
while (e && e.parentNode && e.parentNode != window) {
if (e.parentNode == this|| e == this) {
if(e.preventDefault) {
e.preventDefault();
}
return false;
}
e = e.parentNode;
}
var id = obj.id;
document.getElementById(id).innerHTML="<div style="background-color:#CCC;">OLD Text</div>";
}
Note that you need to change the onmouseout declaration to onmouseout="MouseOut(this,event);".
NOTE: solution derived from https://stackoverflow.com/a/13141057/1417546

Looping through node created by HtmlAgilityPack

I need to parse this html code using HtmlAgilityPack and C#. I can get the
div class="patent_bibdata" node, but I don'know how to loop thru the child nodes.
In this sample there are 6 hrefs, but I need to separate them into two groups; Inventors, Classification. I'm not interested in the last two. There can be any number of hrefs in this div.
As you can see there is a text before the two groups that says what the hrefs are.
code snippet
HtmlWeb hw = new HtmlWeb();
HtmlDocument doc = m_hw.Load("http://www.google.com/patents/US3748943");
string xpath = "/html/body/table[#id='viewport_table']/tr/td[#id='viewport_td']/div[#class='vertical_module_list_row'][1]/div[#id='overview']/div[#id='overview_v']/table[#id='summarytable']/tr/td/div[#class='patent_bibdata']";
HtmlNode node = m_doc.DocumentNode.SelectSingleNode(xpath);
So how would you do this?
<div class="patent_bibdata">
<b>Inventors</b>:
<a href="http://www.google.com/search?tbo=p&tbm=pts&hl=en&q=ininventor:%22Ronald+T.+Lashley%22">
Ronald T. Lashley
</a>,
<a href="http://www.google.com/search?tbo=p&tbm=pts&hl=en&q=ininventor:%22Ronald+T.+Lashley%22">
Ronald T. Lashley
</a><br>
<b>Current U.S. Classification</b>:
84/312.00P;
84/312.00R<br>
<br>
<a href="http://www.google.com/url?id=3eF8AAAAEBAJ&q=http://patft.uspto.gov/netacgi/nph-Parser%3FSect2%3DPTO1%26Sect2%3DHITOFF%26p%3D1%26u%3D/netahtml/PTO/search-bool.html%26r%3D1%26f%3DG%26l%3D50%26d%3DPALL%26RefSrch%3Dyes%26Query%3DPN/3748943&usg=AFQjCNGKUic_9BaMHWdCZtCghtG5SYog-A">
View patent at USPTO</a><br>
<a href="http://www.google.com/url?id=3eF8AAAAEBAJ&q=http://assignments.uspto.gov/assignments/q%3Fdb%3Dpat%26pat%3D3748943&usg=AFQjCNGbD7fvsJjOib3GgdU1gCXKiVjQsw">
Search USPTO Assignment Database
</a><br>
</div>
Wanted result
InventorGroup =
<a href="http://www.google.com/search?tbo=p&tbm=pts&hl=en&q=ininventor:%22Ronald+T.+Lashley%22">
Ronald T. Lashley
</a>
<a href="http://www.google.com/search?tbo=p&tbm=pts&hl=en&q=ininventor:%22Ronald+T.+Lashley%22">
Thomas R. Lashley
</a>
ClassificationGroup
84/312.00P;
84/312.00R
The page I'm trying to scrape: http://www.google.com/patents/US3748943
// Anders
PS! I know that in this page the names of the inventors are the same, but in most of them they are different!
XPATH is your friend! Something like this will get you the inventors name:
HtmlWeb w = new HtmlWeb();
HtmlDocument doc = w.Load("http://www.google.com/patents/US3748943");
foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//div[#class='patent_bibdata']/br[1]/preceding-sibling::a"))
{
Console.WriteLine(node.InnerHtml);
}
So it's obvious that I don't understand XPath (yet). So I came up with this solution.
Maybe not the smartest solution, but it works!
// Anders
List<string> inventorList = new List<string>();
List<string> classificationList = new List<string>();
string xpath = "/html/body/table[#id='viewport_table']/tr/td[#id='viewport_td']/div[#class='vertical_module_list_row'][1]/div[#id='overview']/div[#id='overview_v']/table[#id='summarytable']/tr/td/div[#class='patent_bibdata']";
HtmlNode nodes = m_doc.DocumentNode.SelectSingleNode(xpath);
bool bInventors = false;
bool bClassification = false;
for (int i = 0; i < nodes.ChildNodes.Count; i++)
{
HtmlNode node = nodes.ChildNodes[i];
string txt = node.InnerText;
if (txt.IndexOf("Inventor") > -1)
{
bClassification = false;
bInventors = true;
}
if (txt.IndexOf("Classification") > -1)
{
bClassification = true;
bInventors = false;
}
if (txt.IndexOf("USPTO") > -1)
{
bClassification = false;
bInventors = false;
}
string name = node.Name;
if (name.IndexOf("a") > -1)
{
if (bInventors)
{
string inventor = node.InnerText;
inventorList.Add(inventor);
}
if (bClassification)
{
string classification = node.InnerText;
classificationList.Add(classification);
}
}

Resources