I have setup my posts in Hexo and assigned tags to each post. However the title tag is not capitalizing the way I would like.
This is the rendered HTML:
<title>Viewing pizza | My site</title>
But I would to achieve this:
<title>Viewing Pizza | My site</title>
The tag: pizza is lowercase, and not sure how to make the tag begin with a capital letter within the title tag (e.g. Pizza, Pasta, Italy and so on).
My code:
<%
function capitalize (str) { return str.charAt(0).toUpperCase() + str.substring(1).toLowerCase() }
var title = page.title;
if (is_archive()) {
title = capitalize(__('Viewing'));
if (is_month()) {
title += ': ' + page.year + '/' + page.month;
} else if (is_year()) {
title += ': ' + page.year;
}
} else if (is_category()) {
title = capitalize(__('Viewing')) + ': ' + page.category;
} else if (is_tag()) {
title = capitalize(__('Viewing')) + ': ' + page.tag;
}
%>
<title><% if (title) { %><%= title %> | <% } %><%= config.title %></title>
Thanks in advance!
Here is a function to capitalize each words of a sentence :
function capWords(str) {
// we split string by words in an array
// and we iterate on each word to capitalize the first letter
// and we join each element with a space
return str.split(' ').map(function(str) {
return str[0].toUpperCase() + str.substr(1).toLowerCase()
}).join(' ');
}
In your code :
<%
function capWords(str) {
// we split string by words in an array
// and we iterate on each word to capitalize the first letter
// and we join each element with a space
return str.split(' ').map(function(str) {
return str[0].toUpperCase() + str.substr(1).toLowerCase()
}).join(' ');
}
var title = page.title;
if (is_archive()) {
title = __('Viewing');
if (is_month()) {
title += ': ' + page.year + '/' + page.month;
} else if (is_year()) {
title += ': ' + page.year;
}
} else if (is_category()) {
title = __('Viewing') + ': ' + page.category;
} else if (is_tag()) {
title = __('Viewing') + ': ' + page.tag;
}
%>
<title>
<% if (title) { %>
<%= capWords(title) + ' | ' %>
<% } %>
<%= config.title %>
</title>
I don't know if this is new in hexo, but if you're still looking, there is titlecase, which is a function you can use in your templates.
This should come with your hexo installation now. If you are using ejs as your renderer, you can use it as the documentation states:
You could do <%- titlecase('pizza') %> and get what you want.
Should you need to write your own functions, the preferred way is to write them in a /scripts/my_helpers.js file (name the .js file anything you want, but it has to be in scripts in your project directory). Alternatively, publish your module prefixed with hexo- and import it into your project (make sure it's listed in package.json if you're doing this).
You can then make your javascript function available with the following incantation in your .js file:
// note, I haven't tested this code.
hexo.extend.helper.register('capitalize', (aString) => {
return aString.split(" ").map(function(word) {
return word[0].toUpperCase() + word.substring(1).toLowerCase()}).join(" ")
});
Then you can use <%- capitalize("i am a strInG") %>
<title>
<% if (page.title) { %>
<%= capitalize(page.title) %> |
<% } %>
<%= config.title %>
</title>
`
Related
I have this Play template, dynamicLink.scala.html...
#( urlWithQuotes: Html, id: Html, toClick: Html )
#uniqueId_With_Quotes() = {
Html("\"" + (#id) + "_" + scala.util.Random.nextInt.toString + "\"")
}
#defining(uniqueId_With_Quotes()) { uniqueID =>
<a id=#uniqueID class="dynamicLink" href=#urlWithQuotes> #toClick </a>
<script><!--Do stuff with dynamic link using jQuery--></script>
}
It generates a special link with some Javascript. I render this link like so...
#dynamicLink(
Html("#{routes.Controller.action()}"),
Html("MyID"),
Html("Click Me")
)
When I render it, I get...
<a id=
Html("\"" + (MyID) + "_" + scala.util.Random.nextInt.toString + "\"")
class="dynamicLink" href=#{routes.Controler.action()}> Click Me </a>
This is not what I want to render. I want to render this...
<a id="MyID_31734697" class="dynamicLink" href="/path/to/controller/action"> Click Me </a>
How do I make this HTML escape correctly?
* Take #2 - replacing Html params with String *
#(urlWithQuotes: String, id: String, toClickOn: String)
#uniqueId_With_Quotes() = {
Html("\"" + (#id) + "_" + scala.util.Random.nextInt.toString + "\"")
}
#defining(uniqueId_With_Quotes) { uniqueID =>
<a id=#uniqueID class="dynamicLink" href=#urlWithQuotes> #toClickOn </a>
...
}
With...
#dynamicLink2(
"#{routes.Controller.action()}",
"MyID",
"Click Me"
)
Renders...
<a id=
Html("\"" + (MyID) + "_" + scala.util.Random.nextInt.toString + "\"")
class="dynamicLink" href=#{routes.Controller.action()}> Click Me </a>
<script>
...
</script>
* Changing Html to String didn't work *
* Note that " #uniqueId_With_Quotes() " expands into " Html("\"" + (MyID) + "_" + scala.util.Random.nextInt.toString + "\"") ". I want it to actually execute string concatenation. *
Also, this should be obvious, but I want each link and the accompanying jquery to be rendered with an ID that is unique to that link and I don't want the controller to have to worry about assigning these unique id's. My way of doing that is by appending a random number to each id (although it might just be better for the view to have a count). I need to have this stateful behavior in the view because I need "dynamicLink" to be totally transparent to the controller.
Did you tried to use the variables as String types?
#( urlWithQuotes: String, id: String, toClick: String )
I find the solution. You have to pass a Call object.
#dynamicLink(
({routes.Controller.action()}),
"MyID",
"Click Me"
)
Pass those parameters into...
#(urlNoQuotes: Call, id: String = "", toClickOn: String = "")
#uniqueId_With_Quotes() = #{
Html("\"" + (id) + "_" + scala.util.Random.nextInt.toString + "\"")
}
#url() = #{
Html("\"" + urlNoQuotes + "\"")
}
#defining( url() ) { processedURL =>
#defining(uniqueId_With_Quotes()) { uniqueID =>
...
}
}
^ Now it works.
I have used the jQuery UI Autocomplete demo source code for the Categories example (http://jqueryui.com/autocomplete/#categories) and have it working (querying a database which returns a JSON array).
I'm building a search function for an art gallery and my categories are Artists and Exhibitions. I want to show results from one or both categories. My problem is that results are only showing when the search term covers a result in both categories.
My suggestions script uses the search term to query two different database tables. I format and append the results into a single JSON array with rows for ["id"], ["value"], ["label"] and ["category"].
So for the search term CORN, the results that come back might be:
{ label: "Christopher Corner", category: "Artists" },
{ label: "New Pictures From Cornwall", category: "Exhibitions" },
{ label: "Cornie Collins", category: "Artists" },
At the moment when I type a search term, the possible results are only shown as long as a result is possible in ALL my categories, rather than what I want, which is one or more. So when I type CORN, I can see an Artist named Corner, and an Exhibition about Cornwall, but the minute I type the E of CORNE, all the options disappear, including the Artist whose name is Corner (which I would expect to remain).
I'm new to jQuery and jQuery UI and struggling to understand where the logic would be to select a list item from any category rather than all of them.
I have edited to add my code. This is the backend suggestions file - search_suggestions.php:
<?php
# if the 'term' variable is not sent with the request, exit
if (!isset($_REQUEST['term'])) {
exit;
}
# retrieve the search term that autocomplete sends
$term = trim(strip_tags($_GET['term']));
$a_json = array();
$a_json_row = array();
# connect to database, send relevant query and retrieve recordset
include 'includes/db_access.php';
$compoundFind = $fm->newCompoundFindCommand('web_Artists');
$request1 = $fm->newFindRequest('web_Artists');
$request2 = $fm->newFindRequest('web_Artists');
$request1->addFindCriterion('Last name', '*'.$term.'*');
$request2->addFindCriterion('First name', '*'.$term.'*');
$compoundFind->add(1, $request1);
$compoundFind->add(2, $request2);
$compoundFind->addSortRule('Last name', 1, FILEMAKER_SORT_ASCEND);
$result = $compoundFind->execute();
if (FileMaker::isError($result)) {
die();
}
$records = $result->getRecords();
# loop through records compiling JSON array
foreach ($records as $record) {
$artistID = htmlentities(stripslashes($record->getRecordID())) ;
$artistName = htmlentities(stripslashes($record->getField('Full name'))) ;
$a_json_row["id"] = $artistID;
$a_json_row["value"] = $artistName;
$a_json_row["label"] = $artistName;
$a_json_row["category"] = "Artists";
array_push($a_json, $a_json_row);
}
$findCommand = $fm->newFindCommand('web_Exhibitions');
$findCommand->addFindCriterion('Title', '*'.$term.'*');
$result = $findCommand->execute();
if (FileMaker::isError($result)) {
die();
}
$records = $result->getRecords();
foreach ($records as $record) {
$exhibitionID = htmlentities(stripslashes($record->getField('Exhibition ID'))) ;
$exhibitionTitle = htmlentities(stripslashes($record->getField('Title'))) ;
$a_json_row["id"] = $exhibitionID;
$a_json_row["value"] = $exhibitionTitle;
$a_json_row["label"] = $exhibitionTitle;
$a_json_row["category"] = "Exhibitions";
array_push($a_json, $a_json_row);
}
echo json_encode($a_json);
flush();
?>
And here is the JS in my section which sets things up:
<style>
.ui-autocomplete-category {
font-weight: bold;
padding: .2em .4em;
margin: .8em 0 .2em;
line-height: 1.5;
}
</style>
<script>
$.widget( "custom.catcomplete", $.ui.autocomplete, {
_create: function() {
this._super();
this.widget().menu( "option", "items", "> :not(.ui-autocomplete-category)" );
},
_renderMenu: function( ul, items ) {
var that = this,
currentCategory = "";
$.each( items, function( index, item) {
var li;
if ( item.category != currentCategory ) {
ul.append( "<li class='ui-autocomplete-category'>" + item.category + "</li>" );
currentCategory = item.category;
}
li = that._renderItemData( ul, item );
if ( item.category ) {
li.attr( "aria-label", item.category + " : " + item.label );
}
});
}
});
</script>
<script>
$(function() {
$( "#searchInput" ).catcomplete({
minLength: 2,
source:'search_suggestions.php'
});
});
</script>
Finally this is the actual input field on the page:
<input class="u-full-width" placeholder="Search" id="searchInput" />
Sorry if this is too much code!
I think I have a simple bug somewhere but I can't see it!
In my view, I have the following javascript to create a form:
$.ajax({
url:"<?php echo site_url('mycontroller/methodX/'.$ip.'/'.$hardwaremodel);?>",
type:'POST',
dataType:'json',
success: function(returnDataFromController) {
var htmlstring;
var submitFormHTML;
htmlstring = "<br><br><B>To reassign the port to a new vlan, click on a VlanId below and then click on the OK button</B><br><table class='table table-bordered table-striped'>";
htmlstring = htmlstring + "<th>VlanId</th><th>Name</th>";
for(i = 0; i < returnDataFromController.length; i++) {
}
submitFormHTML = "<form method='post' accept-charset='utf-8' action='/myapp/index.php/controllerABC/methodABC/"+ $('#ip').val() +"/" + $('#hardwaremodel').val() +"/" + $('#port').val() + "'><input type='text' id='newVlanID' style='width:5em;height:1.5em'/> <button type='submit' class='btn' id='saveVlan' style='width:10em;height:2em'>Reassign Vlan</button></form>";
//alert(submitFormHTML);
$('#clientajaxcontainer').html(htmlstring);
$('#newvlanform').html(submitFormHTML);
It's the "submitFormHTML" string that builds the form.
And in my controller I have the following logic to check for the input:
public function methodABC()
{
if($_POST){
echo 'I am here';
$form = $this->input->post();
var_dump($form);
exit();
}
else {
echo "false";
}
It always print the "false". I've also tried using:
print_r($this->input->post());
and
echo $this->input->post('newID');
But I can't seem to get the data from my view into the controller.
Can you see where I'm going wrong? Thanks for the help.
Edit:
The page when rendered, creates the following HTML for the form:
<form method="post" action="/myapp/index.php/switches/changeportvlan/11.11.11.11 /">
<input type='text' id='newVlanID' style='width:5em;height:1.5em'/>
<button type="submit" class='btn' id='saveVlan' style='width:10em;height:2em'>Reassign Vlan</button>
</form>"
The problem was that the textbox is missing a "name" attribute. "id" is not enough!
You need
if ($this->input->post(Null, False)) {
echo "I am here";
$form = $this->input->post(Null, True); ## True for XSS-cleaning, which you probably want.
exit();
}
else {
echo "False";
}
You have to give $this->input->post() arguments. Moreover, never use $_POST in CodeIgniter.
Good luck
I have the following default decorators in a Zend_Config_Ini to set up my form:
elementDecorators.viewHelper.decorator = "ViewHelper"
elementDecorators.label.decorator = "Label"
elementDecorators.errors.decorator = "Errors"
elementDecorators.htmlTag.decorator = "HtmlTag"
elementDecorators.htmlTag.options.tag = "li"
I have the following element definition also in the Zend_Config_Ini:
elements.username.type = "text"
elements.username.options.label = "Username:"
elements.username.options.required = true
and the following output is produced:
<li>
<label for="username" class="required">Username:</label>
<input type="text" name="username" id="username" value="" />
</li>
Now what I need to know is, how do I (through the ini config file preferably), set the id or class of the LI tag? I would like the following output:
<li id="form-username-element"> ... </li>
or
<li class="form-2col"> ... </li>
Update:
I was able to get it by overriding all the decorators in the element config itself like this:
elements.username.options.decorators.viewHelper.decorator = "ViewHelper"
elements.username.options.decorators.label.decorator = "Label"
elements.username.options.decorators.errors.decorator = "Errors"
elements.username.options.decorators.htmlTag.decorator = "HtmlTag"
elements.username.options.decorators.htmlTag.options.tag = "li"
elements.username.options.decorators.htmlTag.options.class = "username-row-element"
So that will work, however creates a lot of duplication as that would have to go onto every element (with the single change of the last line which would be the class setting itself). So what I am NOW wondering, is, from the ini file, is there a way to just override the class name using the default decorators (rather than having to duplicate all of the decorators for each element)?
Easiest thing to do is create your own Decorator. For instance, I've created an ElementWrap decorator, which wraps each element with a div and adds the necessary class and id. It could look something like this:
class Form_Decorator_ElementWrap extends Zend_Form_Decorator_Abstract
{
public function render($content)
{
$element = $this->getElement();
if($this->getOption('openOnly')) {
return '<div class="'.$this->getClass().'" id="'.$this->getId().'">' . $content;
} else if($this->getOption('closeOnly')) {
return $content . PHP_EOL . '</div>' . PHP_EOL;
} else {
return '<div class="'.$this->getClass().'" id="'.$this->getId().'">' . $content . '</div>';
}
}
public function getClass()
{
$element = $this->getElement();
$classes = array(
'field_wrap',
'field_' . strtolower(substr(strrchr($element->getType(), '_'), 1)),
$this->getOption('class'),
);
if($element->hasErrors()) {
$classes[] = 'field_error';
}
if($elementClass = $element->getAttrib('class')) {
$classes[] = $elementClass;
}
return implode(' ', array_filter($classes));
}
public function getId()
{
return 'fieldwrap-' . $element->getId();
}
}
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.