Wednesday, June 13, 2012

Configuring an SPDataSource to access data from External Lists tied to External Content Types

The SPDataSource, used in conjunction with External Lists and External Content Types, is a powerful way to access traditional list data in SharePoint.  The SPDataSource is very useful for populating dropdowns, checkbox lists, and other data driven page layout elements.  Using the SPDataSource tied to an External List is very similar to one tied to a traditional SharePoint list, but there are a few gotchas and things you can do to make your life easier.

So, let's walk through a scenario of how we might take data from a database, in our case SQL Server 2008, create an External Content Type (ECT), create an External List (EL) from the External Content Type, and expose the data in that list to and end user in a dropdown that is part of a page layout.

Time for nerd stuff - spinner hats ON!!!


(Disclaimer:  this is not me, but is an epic picture nonetheless.)
First, go to your database, and add a table named "CITIES".  Add a nvarchar(25) field to it called "CITY" that is the primary key.  Then, create a view on that table - something like vwCities, etc.  This view is going to form the foundation for our ECT, and thus our External List (EL).

I advocate tying the ECT to a sql server view for all read operations rather than to the table directly. This is primarily because it is easy to change a view, and even flatten a highly normalized table structure, thus making your external list's implementation much easier to support, tweak, and use in development of page layouts and search. You can change a table out from underneath a view, even rewrite or optimize the view, without having to rebuild your entire BCS model, External Content Types, and External Lists.

Second you need to create your External Content Type (ECT).  We're going to stick with SharePoint Designer for this demo.  Open up your SharePoint site collection's root site, click External Content Types in the left hand panel, then click the new External Content Type button in the ribbon at the top right of the screen.  Configure your external system, make sure you type a name like "City" as the Name of the ECT, then create your operations.  In our scenario, just create a Read List and Read Item method - leave the others out.
I realize I'm glossing over the finer details here, but I am assuming some level of comfort with creating ECTs in this demo.  Naturally using SPD is not a requirement here, and a Visual Studio is often an easier way to create robust BCS models.  We've used SPD here the sake of simplicity and brevity in deployment and configuration.


Once you've created your External Content Type, create the External List. This is easily done in SharePoint Designer 2010 by clicking the "Create List and Forms" button in the ribbon. Unless InfoPath (IP) is a part of your solutions' architecture, don't bother with checking the checkbox to create the IP form. For purposes of data or list structure the IP form is not needed.

Next, you're going to create the SPDataSource object in your page layout. First, you probably put your External List at the top site in the site collection. This is a good practice. You don't want to have to build SPDataSources smart enough to figure out a dynamic path to your list if you can avoid it. You're going to want to add the WebUrl and ListName parameters to your list. Don't query by ListID. If you get the error "List does not exist" after editing a DFWP or SPDataSource in SharePoint Designer, check to see that it did not add a ListID for you in the SPDataSource tag. Delete that and go by name.

Here's the name parameter:
<asp:parameter defaultvalue="Cities" name="ListName">
</asp:parameter>


Here's the WebUrl parameter.
<asp:Parameter Name="WebUrl" DefaultValue="{sitecollectionroot}"/>

** Note:  You can also use the older "/" instead of "{sitecollectionroot}", but I like the sitecollectionroot param as it is more accurate when read and the newest syntax.

The above parameters tell the SPDataSource to query the Cities list in the site collection root.


In all, here's the syntax for an SPDataSource accessing an External List named "Cities":
<sharepointwebcontrols:spdatasource datasourcemode="List" id="CitiesDataSource" runat="server" selectcommand="&lt;View&gt;&lt;ViewFields&gt;&lt;FieldRef Name='CITY'/&gt;&lt;/ViewFields&gt;&lt;/View&gt;" useinternalname="true" useserverdataformat="true"><selectparameters><br /><asp:parameter defaultvalue="Location Cities" name="ListName"><br /><asp:parameter defaultvalue="{sitecollectionroot}" name="WebUrl"><br /></asp:parameter></asp:parameter></selectparameters></sharepointwebcontrols:spdatasource>



 A few peculiarities as you craft your CAML query of an External List:


  • SPDataSources tied to External Lists really likes ViewFields specified in the CAML query.  You may get some weird execution errors until you add a few fields.  I've had CAML queries work beautifully without the ViewFields attribute of the CAML query set, only to come in the next day to a weird Correlation ID error.  When I looked up the error it said something along the lines of the query exceeding the size allowed, etc.  I think this may be when you have very wide tables, or attributes of the ECT and thus the list column tied to really long fields.  In my case, I had several nvarchar(4000) fields.
  • The RowLimit attribute of the CAML query for external lists does not seem to limit the result set coming back. I've had to resort to filtering the number of rows returned in the XSLT at times.
  • HTML Encode your CAML.  Yes, you might get away with a typed in CAML query, but it won't be as bulletproof at run time and is required for many syntax circumstances.
The next thing to do is tie a dropdown or some other data driven component to your SPDataSource, just as you would any other SPDataSource.

In this scenario, I want a dropdown tied to my CitiesDataSource SPDataSource that has a default value.  I'd also like a custom javascript method to fire when I change it.

<asp:dropdownlist appenddatabounditems="true" cssclass="ddl_city" datasourceid="CitiesDataSource" datatextfield="CITY" datavaluefield="CITY" id="ddlCity" onchange="javascript:ChangeCity(this);" runat="server"></asp:dropdownlist>
   
<asp:listitem selected="True" text="City" value="City"></asp:listitem>

So, there you have it - a dropdown tied to an external list, which is tied to an external content type that is tied to a view in a database!

Sunday, February 12, 2012

SharePoint 2010 BCS and Search over anonymous access



Recently a colleague and I labored through an entire day working with the Business Data Connectivity Service (BCS) and getting it to search properly. Our mission? Take a line of business (LOB) data source in SQL Server 2008, encapsulate it as an External Content Type (ECT) in SharePoint 2010, and create a list from that ECT that is searchable via anonymous access over the internet - a combination of scenarios rarely encountered. That list would then have a custom profile page built to view the data. The list (and ECT) should be searchable from the typical search components of SharePoint 2010 such that, when an appropriate result was found, they could click and get our custom view page - over anonymous and authenticated acces.

Sounds easy, right? Been done a thousand times with classic content types in SharePoint, right? Easy to configure the search meta data you say, right?

Brrrrrrrrnnnnggggt.

The BDSC creates an interesting search paradigm. You aren't working with a normal content type. It's simple enough to take a traditional content type and map it's site columns to managed properties in SharePoint search. However, with an ECT you don't get the benefit of a Site Column.

Furthermore, you have to index the BDCS, not a SharePoint list by url filter. So, the content source becomes an issue.

At first, we thought applying a content source for all BCS entities would work. Seemed logical. Just have one and then search by property value from there. However we soon found that this was not practically possible. We found that any time we modified the ECT, we needed to completely delete and recreate the ECT, not just update it and propagate those changes to the list via SharePoint Designer (SPD).

When we needed to add a field, we needed to delete the ECT and completely recreate the External List fielding the ECT. Otherwise the search wouldn't work.

Furthermore, we found that a Content Source in SharePoint search only worked with one ECT assigned to it. The first ECT added worked. Any subsequent ones did not. So, we ended up with a one to one ratio of ECTs to Content Sources in SharePoint search.

In short, to make LOB data searchable via BDCS, we had to do the following:
  1. Create data structure (table or view worked fine) using Sql Server management tools
  2. Create External Content Type using SharePoint Designer 2010 and save it.

    Make sure your data access is set appropriately if you need to access it anonymously. The BCS data source has to be configured as Revert To Self to be available anonymously, which is different than the way you must first set it up to initially configure the ECT.
    $apps = Get-SPServiceApplication$bcs = #Do something appropriate here to get the app that is#BCS. If you’re doing this by hand, just type $apps and look#for the Business Data one, then index into it like $apps[i].#If you’re doing it for automation, filter by
    #$_.GetType.FullName
    (not $_.TypeName, which is localized).$bcs.RevertToSelfAllowed = $true
    Then, alter your data source to select "BCS Identity" - this will cause SharePoint to revert to the application pool's identity for accessing the BCS data source.



    Make sure the app pool account has access to read your BCS entity in the service manager for the BCS. This is configured in Central Administration, the BCS service application. Make sure your app pool account has access to the Sql Server.
  3. Click "Create Lists & Forms" button in SPD to propagate ECT to a SharePoint list.
  4. Make sure the new External List is showing data. Do not proceed until you've validated it has access anonymously and authenticated.
  5. Log into Central Administration and go to Search Administration. Under Content Sources, create a new Content Source. St it to "Line of Business Data", but DO NOT select the "All BCS" entities option. Rather, select ONLY the ECT you just created.
  6. Save the Content Source, and run a full crawl of the Content Source. The number of successes should be close to the number of records in your data source (table or view).
  7. Search for an item in your data source, and you should be presented with a result that links you to a profile page.

The BCS is much improved over SharePoint 2007's version. There are still some things to work around in difficult scenarios but it can be done.

Monday, September 26, 2011

Disabling the SharePoint 2010 ribbon

Oftentimes, web designers need the entire screen to really pull out all the stops on a web design for a customer. This is especially true of public, consumer-facing web portals.

SharePoint 2010 presents a wonderful tool at the top for managing content called the ribbon. However, it is in the way, and public, anonymous users don't generally need the ribbon. That space is more valuable presenting a message to a customer than in providing technical functions to someone that doesn't need them.

So, how do you get rid of it? There's no way to simply disable it out of the box. To do so requires the typical UI customization approach to making SharePoint 2010 sing. However, you can't get rid of it FOREVER or your customer won't be able to manage content. So, it's a little trickier than meets the eye.

So, let's get down to it.

First, you need a way to manage content, so plan accordingly. In the situation below, I'm going to assume that only the public, anonymous URL is going to need to have the ribbon disabled. I'm going to use the default zone of the SharePoint application to manage content. You could also deploy a third zone, an extranet, wherein your content managers could log in via Forms Based authentication and manage content.

So here we go:
  1. Set up your application.
  2. Deploy it to a public, anonymous zone - the Internet zone. You'll now have one application deployed to two zones - the default and the Internet zones.
  3. Find the master page that drives the screens on which you need to hide the ribbon. If you have more than one master page in your site collection or solution you'll need to implement this solution for each one.
  4. Add the following style to a stylesheet that is always included in the master page. (I avoid inline styles like the plague, and don't update the style sheets native to sharepoint or you'll get your fingers broken by the Best Practices Enforcement Bureau.)

    /* Ribbon row - hide by default - this is turned on in the master page jquery file for content editor access */
    #s4-ribbonrow{display:none;}

    *This setting turns OFF the ribbon row. It will ALWAYS be off unless you do #5.
  5. Add the following code to some javascript that gets executed by your master page.

    var ribbonRow = document.getElementById("s4-ribbonrow");
    if(window.location.href.indexOf('www.yourawesomewebsite.com') == -1)
    ribbonRow.style.display = "inherit";
    This code will turn the ribbon ON if it does not contain the base url of your public site.
That's it! No "code". No custom assemblies. No screwing with base SharePoint components.

Now, at this point, you can see the fundamentals of how you might go about programatically turning it on and off. It's simple. You can add a UI element such as a button or link - even make it audience-aware, that toggles ribbonRow.style.display between "inherit" (show) and "none" (hide). Very slick. So, if you have a scenario say - on your intranet - where you have a large audience consuming the information only and others that need to update it via the same URL, you have a really slick option.

That's enough nerdy stuff for now. Back to my hole.

Sunday, July 3, 2011

Building Snake Traps with Savannah


This afternoon Amber, Keegan, and Kennedy went out in the back yard to play in the kiddie pool and sprinkler. When Amber reached down to grab the hose, lo and behold, she nearly grabbed a snake!

I was inside when I heard the screech. Amber came in and expressed her concerns. I went to the bush where the snake had slithered to and flushed him out. "Good" I thought. "He's gone."

Not quite. I watched as he slithered into a small hole underneath the power supply for the air conditioner ON OUR HOUSE. After further inspection it was determined he was not in the box, but in the walls of our home.

This needed remedied. Fast.

I decided to build a snake trap.

So, Savannah and I headed to the basement to build a snake trap.

The design is simple: You build a tube long and wide enough to hold the snake, then build a one way trap door at the end. You butt the trap up against the hole and wait. Hopefully when he comes out he'll go down your trapped tube and get stuck. Mwwwaaaaahahahahaahhahahahah!!!!

Materials:
  • 1 cardboard wrapping paper tube
  • tape (packing, duct, etc - something that can withstand the elements a wee bit)
  • 1 toothpick
  • 1 piece of plastic (from something in the trash!)
  • 1 sharpie
  • 1 rubber band
  • scissors
  • Rocks, logs, etc to hold the snake trap in place.

Step 1 - Cut the end cap and trap door
Stick the end of your tube on the plastic and draw a circle. Add a tab about a quarter inch wide to the edge of one circle.

Cut the circles, leaving the notched tab on one of course.
Play around with the trap door in the tube. Make sure it is not too tight that it can't open and close but not so loose there is a big gap between the sides.

The other circle is for the end cap and needs to be a little bigger than the end of the tube.


Check your baby.











Step 2 - Assemble the trap door

Cut a slit about a quarter inch long extending from the edge of each tab on the trap door parallel with the edge. This will hold the rubber band which will snap it shut after the snake has passed over the door.

Cut a slit long enough for the tab to fit through from the inside of the snake tube. I used the point of my scissors.

Slip the rubber band through the two slits.

Slide the trap door into the tube and insert the tab into the slit you just cut. Make sure the trap door swings down the long portion of the tube. Pull the rubber band out the open end.

Step 3 - Make a rubber band anchor point.

Find a point where you can anchor the rubber band that will pull the trap door closed but not be so tight it can't be easily pushed open. Poke two holes fairly close together at this point. Break off 3/4 of the toothpick and slide the larger piece through the two holes. (This keeps the toothpick out of the snake's way.)

Pull the rubber band through the open end and hook it on the toothpick at the anchor point.

Test your trap door. Does it open easily? Does it close easily?

Once your are satisfied with the trap door's operation, tape down the tab of the trap door you inserted through the slit.

Take the 1/4 remainder of the toothpick. Insert it on the opposite side of the tube from the tab far enough that it engages the trap door when it closes. This will prevent the snake from getting out once the trap door closes. Secure it with some tape on the outside of the tube.

Step 4 - Install the end cap

Put the end cap on the end of the tube opposite the trap door. Tape it on the end securely so it can't be pushed out by a snake.







Step 5 - Set the trap

Go to your snake hole and butt up the end of the tube with the trap door on the hole. The side of the tube with the tab sticking out should be towards the top. (This way the door opens easiest for a snake traveling on the bottom of your tube.) Make sure to involve your 5 year old son for a real kick.

Prevent it from rolling or moving vertically by placing logs on either side and over the top. 5 year old boys are very good at collecting logs for you.

Step 6 - Wait

Wait for the snake. They come out and night often so check in the morning. You may be able to bait the snake with some insects as well.

All in all making and setting this trap took about 30 minutes.

Tuesday, June 28, 2011

Jonah's Revenge

I finally decided on a name for the kayak:

"Jonah's Revenge"

Jonah's Revenge takes its name from the nature of the boat and the water on which it will be used. It will be used for fishing while navigating some tempestuous waters on longer trips. In my case, I'll be fishing between whitewater stretches on the New River in West Virginia.

Kinda like maybe what Jonah was doing while trying to avoid his mission from God.


For those not in the know, Jonah was a prophet in the Bible that was sent to give a message from God to an enemy city. He decided to bail on his mission from God - no, not like the Blues Brothers.



Jonah had a bit of an anger management problem, akin to the angry whitewater of the New River. Jonah stormed onto a ship to return home, but God sent a huge storm, and the guys on the boat ended up throwing him overboard to save themselves. A big fish then swallowed up him up and vomited him onto land.

Jonah got the point and returned to deliver God's message to the city. If the city didn't change in 40 days, God would destroy it. He then went outside the city to await its final destruction.

To Jonah's somewhat dismay, the city repented and God spared it from destruction. We don't know much of what happened with Jonah after that. Perhaps he lived happily ever after.

Or, perhaps, given his angry disposition, he returned to sea to exact vengeance on fish while navigating tempestuous waters.

Thus, the nature of the kayak.

Wednesday, June 15, 2011

Pimp My Kayak

This summer I'm taking a 3 night kayak adventure with 3 of my best friends. So, I bought a kayak.

I decided to get the most inexpensive kayak I could find that was capable of making a journey through class I, II, and III rapids, could serve as a fishing kayak for the small lake we live next to and navigate Indiana rivers, small lakes, and creeks for fishing.

I purchased the Potomac 100 ES at Dick's Sporting Goods. I got it on sale and used two $10 off coupons. Then, I got an inexpensive, mid-length paddle.

Not one to have a run-of-the-mill boat, I decided to "Pimp My Kayak" for the purpose of fishing and additional gear for a mid-length trip of 3-4 days.

ItemCostSource
Kayak$159Dick's Sporting Goods (w/ coupons)
Angler Kit - includes anchor, 2 flush mount rod holders, 1 anchor cleat, 1 Scott rod holder$42yak-gear
Marine Goop$5Menard's - paint / adhesive section
Anchor Trolley2 caribiners - $2
1 O-ring = $1
1 pulley = $1.50
50' yellow cord - $3
Menard's - boating section
Folding Paddle Clips$8yak-gear
1 Scotty rod holder (baitcaster)$15Gander Mountain
Rigging Kit - 4 pad eyes, 4 bungee terminals, 4 j-hooks, 8' 1/4" bungee$9.99Bonanza - rats502
220 cm Paddle$35Dick's Sporting Goods
6 3/8" pad eye packet$2Bass Pro Shops
2 Bungee Clips$1Bass Pro Shops
Washers, Machine Screws, Zip Ties, Nuts I had on hand



Rear Storage Access

The Potomac 100 ES is a little light on storage space out-of-the-box, so I first cut out the bottom of the rear storage bin so I could access the internal storage behind the seat.

Tools: Ruler, Sharpie, hacksaw blade, utility knife

I marked a dotted line 1 3/4 inches above the base of the hatch with the Sharpie, then scored it with the utility knife so my hacksaw blade would have an easier time tracking. I cut all the way through on one side about two inches long with the utility knife so I could get through.

Then, I hacksawed it all the way around until it was out. The hole wasn't perfect but it is good enough.

I would have rather used a dremel or drill cutter to get through it but I didn't have those tools and I'm doing this all "on the cheap".

Rear Flush Mount, 45 Degree Angle Rod Holders

I purchased the Angler Kit from Yak Gear with 1 pound grapnel anchor and Scotty Rod Holder for $45. The Marine Goop came from Menards in the paint and adhesive section.

Tools: Sharpie, Drill, Drill Bit, Jigsaw, Marine Goop, 6 nuts, 6 bolts

I first sat in the kayak and made sure that where I intended to put the two rod holders would not interfere with my stroke when rods were in them. I also wanted to angle them to the side so that I could still navigate narrower inlets and streams, as well as see the rods out of the corner of my eye while trolling. So, I angled them to the back of the kayak some.

Then off to work!

1. I cut out the ovular pattern provided and positioned it where I wanted my rod. I marked the spot with a red Sharpie. Then, I drilled a pilot hole for my jigsaw with my drill using a 3/8 inch bit.

2. Cut hole with your jigsaw.


3. Repeated #1 and #2 for the other hole. I made sure to clean the surface and remove all the burrs from the holes. This is important for a watertight seal.

4. I played around with the rod holder in the hole- you'll have quite a bit of movement available here so don't worry about cutting the ovular hole perfectly in line with the direction you ultimately decide them to point.

I got my marine goop ready!

Once aligned I used a sharpie to mark where the screws would mount the rod holder to the kayak and drilled them out with a 5/16" bit. I'll be mounting mine with machine screw, nut, and washer on the back side.




5. I slathered marine goop all over the rod holder and put some IN the mounting holes I just drilled. No water leakage is the goal!




6. Insert the rod holder into your hole and align it with the holes, then insert the screw into the top and screw it into the kayak with enough thread exposed to thread the nut and washer on the back end.

Your hands will get goopy. It's ok.

Using a screwdriver and wrench, hand tighten each bolt. Don't overtighten. Snug but not stressed.

Wipe up the excess goop with a wet paper towel or rag.



Flip-Down Paddle Clips

I bought the flip down clips because I wanted the clips to interfere with my paddle stroke as little as possible. I figure they are less likely to tangle fishing lines as well if they are out of the way.

First thing I did was decide which side I wanted to store the paddle on. I picked the right side because I'm righthanded and need to make sure the paddle is accessible as easily as possible if I need to grab it. I intend to put the most often-used Scotty rod holder to my front left for holding a pole for up-front trolling and wanted a pole in the way as few times as possible when storing the paddle as well.

First thing was to make sure the clips would be out of the paddle stroke area. I sat in the kayak and made sure my stroke would not go over the clip. I endured good-natured cajoling from my wife in the process as I sat in the garage pretending to be kayaking.

I marked the general spot up front and in back. I made doubly sure there would be no stroke interference. I'll be on some whitewater after all and need maneuverability.

I tested the location with clips on my paddle and held into place while I pretended to do stuff in the kayak. Thick skin for the cajoling was again needed.

1. I lined the holes up with a straight edge. (the flexible edge of my tape measure worked well)

2. I marked the holes with a sharpie.

Front: Back:


3. Drilled out the marked holes, then dabbed some Marine Goop on them.

4. Put some goop on the bottom of the base, put the clip into the base, then screwed the entire assembly into the kayak using screwdriver and wrench. I made it hand tight - snug but not stressed.

Scotty Rod Holders


The Scotty Rod holder placement is important. I wanted easy access to their poles, no paddle stroke interference, the best deck access I could get up front, and a secure mount. Securely mounting these, given their large surface area, required me to angle them up the contour of the kayak. A slight loss of deck access but better to have a secure mount. Repositioning the mounts causes quite a bit of stress on the kayak structure so I didn't want anything bent or compromised over time.

1. I removed the rod holder and positioned the base where I wanted it. Then, I drilled through with the drill. My sharpies weren't long enough to mark a spot for a cleaner drill through and pattern.

My holes left some plastic on the inside so I cut the excess off with my utility knife. This worked very well for nice, clean holes.



2. I mounted the rod holder base to the kayak. I put a little goop in each hole, the edges of the rod holder base, and then attached them with the machine screw, nut, and washer. Make sure your washers will be flush once fully screwed down. I had to find some smaller washers to fit the space, but generally bigger is better with the washers.



3. I let the assembly cure for a while before reattaching the rod holders.



All done! Clean up the excess goop :)

Stern Deck Rigging
The stern area did not have any rigging so I elected to add some. I'd like to be able to put a deck bag, dry bag, crate, or other gear behind me.

First you need to have your design determined including where the rigging will go, what type of connectors you'll use, and the diameter of your bungee.

I went with 1/4" bungee, four pad eyes on the ends, and two j hooks in the middle. I determined to attach the rigging to either end with bungee clips for easier reconfiguration for larger, heavier loads. (It's best to put larger, heavier loads on the back if you cannot get it in the middle of the kayak.)

What's the process for installing rigging connectors?
For attaching hardware, I use machine screws, washers, and nuts where possible as opposed to
rivets. It's stronger and easier to fix if it gets loose. Rivets require drilling out and can more easily bend or deform. I also use marine goop.

First, lay out all the connectors according to your design.

Mark each hole you need to drill with a sharpie. Deburr each hole.


Put goop in the holes and on surface contacts, then attach with the
hardware. Give each connector some time to cure before putting a load on it so the goop can cure.

Finally, run the cord through the loops and attach. I used a simple square not to attach two cords.


Here's my completed stern rigging.



Bow Deck Rigging


I chose to reconfigure the bow rigging by extending it all the way to the end. I cut the bungee cords already attached to the kayak where they were connected in the middle of the bow and reused the holes. I couldn't reach underneath to use washers, bolts, and nuts, so I used rivets for them. I reused the existing j-hooks that are by the cockpit.

I had a piece of bungee left over from the stern rigging that I spliced into the original bow bungee using two square knots. Now I have more storage and bungee on the bow deck.

Anchor Kit
Now it's time to install the anchor kit!

First thing I did was find a place for the anchor cleat. It needed to be close to the cockpit, somewhere sturdy and flat, yet out of the way of my paddle stroke. Also, it needed to be on the side with less casting action which in my case is on my left side - also away from the paddle clips. Port will be the side the trolley needs to go on anyways since the paddle would interfere with its operation.

The anchor cleat was easy to install. Drill a couple holes, slather on the goop, then attach with hardware.



Anchor Trolley
I bought a bunch of inexpensive hardware to build the anchor trolley. The anchor needs to be port side so it can operate freely and be next to the cleat.

The trolley is completely removable and is attached between the bow's handle and the eyelet I installed behind my flush mount rod holder.

First, I created a double-looped bungee tied to itself with a square knot at each connection point. This helps cushion the kayak when anchored so you're not getting jerked around.

Clip a carabiner to each bungee loop.

Attach a 1/4" pulley to the bow's carabiner. (I'm using 1/4" rope.)

Run your rope. I'm using inexpensive, yellow, 1/4" neoprene rope.

Run your line through the stern's carabiner, through the 2" O Ring, then through the pulley at the bow. Bring it back to the O Ring and make sure you've got an extra foot or so.

Now's the fun part: Playing with fire and zip ties.

Loop the rope through the O Ring and double it up. Measure out your rope - a little slack is ok then cut it.

Put two zip ties on each side of the O Ring, partially zipped down - not all the way tight - loose enough to move over the doubled rope.

Melt a portion of the doubled up rope close to the O Ring using a lighter. Then, quickly move your zip tie over the spot and cinch it down tightly. Use your lighter to heat up the area where the zip tie is cinched down. This will fuse it all together and make for a very strong connection.

Do this four times of course - two times on each side.

We now have our trolley line hooked up! It can easily be detached when we don't want to use it.

Finally we have pimped our kayak!!!