how to get url segment in yii - yii

I am new to YII and i want to get the controller name i hit to add active class in menu item .my URL is like this www.myblog.com/news . I want to get the parameter "news" .Without params are possible in yii like codeigniter $product_id = $this->uri->segment(4);
my menu structure is like this
<ul class="nav navbar-nav">
<li class="active">News / Article</li>
<li>Players</li>
<li>Forum</li>
<li class="dropdown">
Rules <b class="caret"></b>
<ul class="dropdown-menu">
<li>Action</li>
<li>Another action</li>
</ul>
</li>
<li>Profile</li>
<li>Gallery</li>
</ul>

Controller Name -
Yii::app()->controller->id;
Action Name -
Yii::app()->controller->action->id;

Yii::$app->controller->id;
and
Yii::$app->controller->action->id;

Yii::$app->request->pathInfo
then take what you want

Related

How to keep the tab active? ASP.NET Core Razor Pages

Hi there,
I have a problem with my tabs in navbar.
The result I wish:
See the "Home" tab class active by default
Clicking on another tab must to remove active class from the <a> that is already active (at the starting point it is "Home" tab)
Add the same class active to the tab I click on (which also mean that app redirects me)
Keep the clicked tab active
What I've got so far:
I see the "Home" tab set active by default
Clicking on any tab removes class active as I mentioned above and adds the same class to the clicked tab
Redirection happens and "Home" tab returns its default state (becomes active again)
I share my code below:
HTML
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse" id="navigation">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link active" id="home" asp-area="" asp-page="/home/Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" id="declarations" asp-area="" asp-page="/declarations/Index">Declarations</a>
</li>
<li class="nav-item">
<a class="nav-link" id="topics" asp-area="" asp-page="/topics/Index">List of Topics</a>
</li>
<li class="nav-item">
<a class="nav-link" id="contacts" asp-area="" asp-page="/contacts/Index">Contacts</a>
</li>
<li class="nav-item">
<a class="nav-link" id="faq" asp-area="" asp-page="/faq/Index">FAQ</a>
</li>
</ul>
</div>
jQuery
$("#navigation .navbar-nav a").click(function() {
$("#navigation .navbar-nav").find("a.active").removeClass("active");
$(this).addClass("active");
localStorage.className = "active";
});
$(document).ready(function() {
stayActive();
});
function stayActive() {
$(this).children().addClass(localStorage.className);
}
Since you are using Razor page, everytime user clicks on a tab, the page will be rendered again on server and then sent back. Therefore I suggest that we set the active class on serverside based on the current route.
Add a new HtmlHelper class
public static class HtmlHelperExtensions
{
public static string ActiveClass(this IHtmlHelper htmlHelper, string route)
{
var routeData = htmlHelper.ViewContext.RouteData;
var pageRoute = routeData.Values["page"].ToString();
return route == pageRoute ? "active" : "";
}
}
Go to your _ViewImports.cshtml and add this import.
Without this, it will not recognize the helper we're about to add in step 3.
#using <Namespace of the class you wrote in step 1, if not already here>
Then your cshtml will be
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse" id="navigation">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link #Html.ActiveClass("/home/Index")" id="home" asp-area="" asp-page="/home/Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link #Html.ActiveClass("/declarations/Index")" id="declarations" asp-area="" asp-page="/declarations/Index">Declarations</a>
</li>
...Same for 3 other tabs, make sure that the route you pass in ActiveClass method
...must be the same as the route in asp-page
...If you're afraid of duplication, make some static class to store these routes as constants
</ul>
</div>
In addition to #Nam Le answer I suggest complete solution.
I've found the way how can we use the exception properly.
First of all, as we set active class on serverside based on the current route, we have to add asp-route-routeId="{routeId:int}" in the cshtml we work with.
Secondly, use this jQuery code:
jQuery
$("#navigation .navbar-nav a").click(function() {
$("#navigation .navbar-nav").find("a.active").removeClass("active");
$(this).addClass("active");
localStorage.className = "active";
});
$(document).ready(function() {
stayActive();
});
function stayActive() {
$(this).addClass(localStorage.className);
}
And the last step is to setup "launchUrl": "route/routeId" in the launchSetting.json file to run the application with certain route. This action make our HtmlHelper extension react and add active status to the tab we want.
Hope that here is no any gross mistakes in the solution I suggest :)
UPD: don't forget to add route in cshtml #page "/route/routeId"

Getting nested <li> tags also.....just need the direct <li> item

I have a page structure where it includes hyperlinks with different levels of nested list items. I am writing the xpath for just the second nested list items(level 2) but it is also giving me all the list items below level 2(level 3 or below), which i don't need. It's getting really frustrating now because I have tried different xpaths and cssSelectors, everytime it is taking the level 3 list items along with level 2.
The page structure is exactly like following:
<div>
<ul class="menuBar_menu_lvl_0">
<li class="item_lvl_1">
<li class="item_lvl_1">
<ul class="menu_lvl_1">
<li class="item_lvl_2"></li>
<li class="item_lvl_2"></li>
<li class="item_lvl_2">
<ul class="menu_lvl_2">
<li class="item_lvl_3"></li>
<li class="item_lvl_3"></li>
<li class="item_lvl_3"></li>
</ul>
</li>
</ul>
<li class="item_lvl_1">
<li class="item_lvl_1">
xpath = //ul[#class="menuBar_menu_lvl_0"]//li[#class="item_lvl_1"]//ul[#class="menu_lvl_1"]//li[#class="item_lvl_2"]
This is also giving me item number 3 elements along with item level 2. I want to get each level item correctly and separately. Anybody's help would be highly appreciated
Welcome to SO.
Here is the sample that used.
<html>
<body>
<div>
<ul class="menuBar_menu_lvl_0">
<li class="item_lvl_1">
<li class="item_lvl_1">
<ul class="menu_lvl_1">
<li class="item_lvl_2">Level1-li1</li>
<li class="item_lvl_2">Level1-li2</li>
<li class="item_lvl_2">
<ul class="menu_lvl_2">
<li class="item_lvl_3">Level2-li1</li>
<li class="item_lvl_3">Level2-li2</li>
<li class="item_lvl_3">Level2-li1</li>
</ul>
Level1-li3
</li>
</ul>
<li class="item_lvl_1">
<li class="item_lvl_1">
</ul>
</div>
</body>
</html>
And below is the xpath
//ul[#class='menu_lvl_1']//li[not(parent::ul[#class='menu_lvl_2'])]
Here is the output:
Here is the method to get the text from parent element only.
def get_text_exclude_children(element):
return driver.execute_script(
"""
var parent = arguments[0];
var child = parent.firstChild;
var textValue = "";
while(child) {
if (child.nodeType === Node.TEXT_NODE)
textValue += child.textContent;
child = child.nextSibling;
}
return textValue;""",
element).strip()

change class of glyphicon when nav-item is open

I am using bootstrap menu on a web page.
my menu list looks something like this:
<li><a class="nav-link dropdown-toggle" href="#" id="navbarDropdown"
role="button" data-toggle="dropdown" aria-haspopup="true" aria-
expanded="false">main item
<span class="pull-left glyph-btn-menu">
<em class="glyphicon glyphicon-menu-down"></em>
</span>
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
sub item1<br>
sub item2<br>
sub item2<br>
</div>
</li>
I want glyphicon symbol to change to class glyphicon-menu-up when nav-link is clicked and submenu items open and then again to change back to glyphicon-menu-down when nav-item is closed or when a different nav-item is clicked.
What would be the best way to acheive that
So this is my solution.
I gave the parent ul the an id value: id="theme"
bootstrap adds the class open to an open li so I check to see if any li have the class open, remove and add glyphicon classes as needed
$('#theme li').click(function () {
if($(this).hasClass('open')){
//alert('aaa');
$(this).children('a').children('span').children('em').removeClass('glyphicon-menu-up');
$(this).children('a').children('span').children('em').addClass('glyphicon-menu-down');
} else {
$(this).children('a').children('span').children('em').removeClass('glyphicon-menu-down');
$(this).children('a').children('span').children('em').addClass('glyphicon-menu-up');
}
});

accessing translated header in FCE fails

I have a Typo3 Page with several wrappers and referenced elements on it.
I'm using flux-grid to create the content of the wrappers and then access it like this:
<v:variable.set name="contentElements" value="{flux:content.get(area:'content', render:'FALSE')}" />
<ul class="myClass">
<f:for each="{contentElements}" as="contentElement" iteration="iteration">
<li>
<h3 data-number="{iteration.cycle}">{contentElement.header}</h3>
<ul class="content" id="acc_{v:format.sanitizeString(string: '{contentElement.header}')}">
<li>
<v:content.render contentUids="{0:contentElement.uid}" />
</li>
</ul>
</li>
</f:for>
</ul>
Problem is, I always get the default language for contentElement.header instead of the translated version. The content itself that's been fetched via v:vcontent.render is shown in the correct language.
What am I doing wrong?
(Typo3 8.7.9)
I had to get the content first and then render it separately:
<f:for each="{contentElements}" as="contentElement" iteration="iteration">
<v:variable.set name="head" value="{v:content.get(contentUids: '{0: contentElement.uid}', render:'0')}" />
<v:variable.set name="theContent" value="{v:content.get(contentUids: '{0: head.0.records}', render:'0')}" />
<li>
<h3 data-number="{iteration.cycle}">{theContent.0.header}</h3>
<ul class="content" id="acc_{v:format.sanitizeString(string: '{theContent.0.header}')}">
<li>
<f:format.raw>{theContent.0.bodytext}</f:format.raw>
</li>
</ul>
</li>
</f:for>
Hope it helps someone...

Nesting a # foreach in Webmatrix 2

I'm a tad rusty here so bear with me. I'm trying to get my list of items within their groups like so.
<h2>Category Heading 1</h2>
<ul>
<li>Item list 1</li>
<li>Item list 2</li>
</ul>
<h2>Category Heading 2</h2>
<ul>
<li>Item list 1</li>
<li>Item list 2</li>
</ul>
And my code is - I'm getting errors
#foreach (var group in db.Query(GroupName)){
<h3>#group.Name</h3>
<ul>
#foreach(var row in db.Query(queryList)){
<li> #row.title</li>
}
</ul>
}
Any help would be appreciated
You should be able to do this by getting all the data in one go and using the LINQ GroupBy operator. Here is an article I wrote about displaying hierarchical data like this: http://www.mikesdotnetting.com/Article/189/Efficiently-Displaying-Hierarchical-Data-With-The-jQuery-Accordion-In-Razor-Web-Pages
You can ignore the 2nd half where I introduce the jQuery accordion...