Monday, 19 August 2013

Changing your YouTube video preview thumbnail

To change preview thumbnail of your youtube video

Option 1

You can choose a thumbnail from the three options that youtube automatically generates 
  • Go to Video Manager by clicking on your username in the upper right corner.
  • On the My Videos/Upload Page, click Edit for the corresponding video you'd like to change.
  • Once you are on Edit Video Page you can choose from the three options provided by YouTube as highlighted in the screen grab below.

Option 2

If don't find any image suitable for your video in the options provided by YouTube then you can also add a "Custom Thumbnail" for your video. Please note you will be able to see this option only if your YouTube account is a verified account.

If you are already viewing the Custom Thumbnail option you can simply upload a image of your choice and set it as your video preview thumbnail.

P.S. I would recommend to keep 16:9 ratio as it's the most used in YouTube Players and previews

Once you have selected the preview image of your choice, save your changes by clicking on the "Save Changes" button present on the top left of the page.

Please let me know if you have any questions. Thanks for your time!

Friday, 17 May 2013

Making PDF files SEO friendly

Are you trying to figure out a way to get search engines to drill down your online PDF files and improve its ranking? If that is the case then you have a reason to cheer up :), this post will guide you to follow few very basic steps to improve your PDFs online visibility.

Best Practices in SEO for PDF files

  • Smartly name your PDFsTypically, the PDF filename will become part of the URL, so give your document a good key-word rich filename. 
  • Set the PDF title - Yes, most of us just don't set PDF title properties, but the matter of fact is that the title tag is a huge ranking factor. To set title of a PDF file, open it in Adobe Acrobat or any other PDF creator and go to, File --> Properties
  • Set the other document properties too - don't just ignore the other properties provide a good Subject (Description) and Keywords as you do it for your HTMLs
  • Prefer text-based PDFs over image-dominated PDFs
  • Set "alt" text for all the images - this will also increase the accessibility 
  • TouchUp Reading Order - allows to quickly add and edit PDF tags and view the reading order of the elements on the page.
Please let me know if missed something or if you want to have any query, I would be more than happy to answer your queries.

Wednesday, 20 February 2013

Custom PagingNavigator for SEO friendly URL

Apache Wickets biggest strength is its focus on components - Among a very large set of components is PagingNavigator component. It is a Wicket Panel component to draw and maintain a complete page navigation. I found this component very useful but the only problem that compelled me to write my own CustomPagingNavigator is the wicket URLs that are being created by clicking the page links. 

The Java Part...
public class CustomPaginationLinksPanel<T> extends Panel{
  private static final long serialVersionUID = 10002L;
  /**Pageable List View to be displayed */
  private PageableListView<T> mainView;
  /** Max count of links  default  value = 5 */
  private int linksPerPage = 5;
  /** Page Number currently visible */
  private int  currPgNum;
    /** first page number */
  private int firstNum;
  /** last page number */
  private int lastNum;
  //Calculated on the basic of List size
  private int maxPages;
//Parameter name that will be displayed as a part of URL
  private String PAGINATOR_PARAM_NAME = "pg";
   
    private WebPage navigateToPage;
    private PageParameters parameters;
    
    public CustomPaginationLinksPanel(String id, String paginatorParamName, int linksPerPage, PageableListView<T> main, WebPage page) {
super(id);

this.linksPerPage = linksPerPage;
        this.navigateToPage = page;
        this.mainView = main;
        
        if(paginatorParamName != null && !paginatorParamName.isEmpty())
        PAGINATOR_PARAM_NAME = paginatorParamName;
        init();        
        gotoPage();
        initComponents();
  }

    private void init() {

    this.parameters = navigateToPage.getPageParameters();
    this.currPgNo parameters.getAsInteger(PAGINATOR_PARAM_NAME, 1);
    this.maxPages = mainView.getPageCount();
   
    int padding = linksPerPage / 2;
firstNumcurrPgNum - padding > 0  ? currPgNum - padding : 1;
lastNumcurrPgNum + padding <= maxPages ? currPgNum + padding : maxPages;

int temp_currLppCnt = (lastNum + 1) - firstNum
//Following code handles the boundary Condition
if(temp_currLppCnt< linksPerPage){
if(firstNum == 1 && lastNum < maxPages){
lastNum = lastNum + (linksPerPage - temp_currLppCnt  <= maxPages ? lastNum + (linksPerPage - temp_currLppCnt) : maxPages
}
else{
firstNum = firstNum - (linksPerPage - temp_currLppCnt) >= 1 ? firstNum - (linksPerPage - temp_currLppCnt) : 1; 
}
}
if(temp_currLppCnt linksPerPage)
lastNum = lastNum - 1;
   }

    private void initComponents() {

        // previous control static
        WebMarkupContainer prevStatic = new WebMarkupContainer("prev");
        prevStatic.setVisible(currPgNo > 1);
        prevStatic.add(new BookmarkablePageLink<WebPage>("link", navigateToPage.getPageClass(), addParam(parametersPAGINATOR_PARAM_NAMEcurrPgNo - 1)));
        add(prevStatic);

        // next control static

        WebMarkupContainer nextStatic = new WebMarkupContainer("next");
        nextStatic.setVisible(currPgNo < maxPages);
        nextStatic.add(new BookmarkablePageLink<WebPage>("link", navigateToPage.getPageClass(), addParam(parametersPAGINATOR_PARAM_NAMEcurrPgNo + 1)));
        add(nextStatic);

        add(createPaginationLinks("links"));

    }

    private Component createPaginationLinks(String id) {

        return new RefreshingView<Integer>(id) {
          private static final long serialVersionUID = 10011L;
            @Override
            public boolean isVisible() {
                return maxPages > 1;
            }
            @Override
            protected Iterator<IModel<Integer>> getItemModels() {
                List<Integer> list = new ArrayList<Integer>();
                for (int i = firstNum; i <= lastNum; i++) {
                    list.add(i);
                }
                return new ModelIteratorAdapter<Integer>(list.iterator()) {
                    @Override
                    protected IModel<Integer> model(Integer object) {
                        return new Model<Integer>(object);
                    }
                };
            }

            
@Override

            protected void populateItem(final Item<Integer> item) {   
                Integer obj = item.getModelObject();
                
                BookmarkablePageLink<WebPage> notCurrent = new BookmarkablePageLink<WebPage>("notCurrent", navigateToPage.getPageClass(), addParam(parametersPAGINATOR_PARAM_NAME, obj));
                notCurrent.setVisible(!(obj.equals(currPgNo)));
                notCurrent.add(new Label("number", item.getModel()).setRenderBodyOnly(true));
                item.add(notCurrent);
                 
                item.add(new Label("current", item.getModel()).setVisible(obj.equals(currPgNo)));

                item.setRenderBodyOnly(true);

            }
        };
    }

    private void gotoPage() {

        mainView.setList( mainView.getList().subList((currPgNo - 1) * 10, (currPgNo * 10) < mainView.getList().size() ? currPgNo * 10 : mainView.getList().size()));
    }
  private PageParameters addParam(PageParameters original, String key, Object value) {
        PageParameters result = (PageParameters)original.clone();
        result.put(key, value);
        return result;
    }
}    

Here is the markup...
<html xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd" >
  <body>
  <wicket:panel>
        <div class="pagination" >
            <span wicket:id="prev">
  <a href="#" class="link previous" wicket:id="link">&laquo; Prev</a>
  </span>
            <span wicket:id="links">
<a href="#" class="link" wicket:id="notCurrent">
                    <span wicket:id="number">[page number]</span>
                </a>
<a href="#" class="link active" wicket:id="current">[page number]</a>
</span>
            <span wicket:id="next">
<a href="#" class="link next" wicket:id="link">&nbsp;&nbsp; Next &raquo;</a>
</span>
</div>
</wicket:panel>
   </body>
</html>

And finally usage of the custom component...
...
add(new PageableListView<Post>("post", post, itemsPerPage) {
  private static final long serialVersionUID = 10025L;
  @Override
protected void populateItem(ListItem<Post> item) {
final Post p = item.getModelObject();
item.add(new ContextImage("image", p.getImageUrl()));
PageParameters parameters = new PageParameters();
    parameters.put(PARAM_POST_TITLE, p.getPostUrl());
Link<Void> ttlLnk = new BookmarkablePageLink<Void>("titleLink", PostPage.class, parameters);
ttlLnk .add(new Label("title", p.getTitle()));
item.add(ttlLnk);
}
});
 
add(new CustomPaginationLinksPanel<Post>("btmNavigator", null, 5, listView, this));
...


Friday, 1 February 2013

sorting a List containing Object[] elements


Problem Statement: How can we  sort a List containing Object[] elements?

The Solution:
Ever wondered how to sort a list full of Object[]? The answer is to use a Comparator I have used an anonymous class which implements compare method to sort the List of Object[]

package example.collections;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Sorting {

       public static void main(String[] args) {
              List<Object[]> list = new ArrayList<Object[]>();
             
              list.add(new Object[]{123, "abc", 212});
              list.add(new Object[]{423, "qwert", 2131});
              list.add(new Object[]{656, "asda", 45});
              list.add(new Object[]{111, "zxcz", 43});
              list.add(new Object[]{10, "poiu", 890});

              Collections.sort(list, new Comparator<Object[]>() {
                     //Used by Collections.sort method to sort the List
                     @Override
                     public int compare(Object[] o1, Object[] o2) {
                           Integer accId1 = (Integer)o1[0];
                           Integer accId2 = (Integer)o2[0];
                           if(accId1 < accId2)
                                  return -1;
                           if(accId1 > accId2)
                                  return 1;
                           return 0;
                     }
              });
             
              for(Object[] obj : list){
                 System.out.println("id= "+obj[0]+", name= "+obj[1]+", val= "+obj[2]);
              }
       }
}