Identity Woman - Fri, 11/21/2008 - 22:33

This story does not have a happy ending
From Times Online:

A 19-year-old man in Florida committed suicide live on the internet as hundreds of web surfers watched - taunting him and offering encouragement.

Abraham K. Biggs, from Broward County, Florida, announced his intention on an online forum, posted a suicide note on another and then took an overdose of pills in front of his webcam, broadcasting his final moments on Justin.tv.

Mr Biggs lay on his bed motionless for several hours before members of the website became alarmed. With the video still streaming, viewers eventually called the local police, who broke down the door, found the body and switched off the camera. Up to 1,500 people were viewing, according to one report.

A video clip posted on the net shows a police officer entering the room, his handgun drawn, as he checks for any sign of life. Mr Biggs was a member of bodybuilding.com under the name CandyJunkie and was also known under the alias of Feels Like Ecstasy on Justin. tv. He had apparently threatened to commit suicide before.

The last post was about cybermobs emerging in the political fallout of proposition 8. This one at a personal level.

It makes me wonder how we can love and value life through the anonymity that the web gives us.

One of the major things that kids needed to be protected from articulated at the Kids Online conference last week was “themselves” this is a good example of this need.

Categories: Web 2.0

CMSWire - Fri, 11/21/2008 - 17:43
And here's a cheers to our current sponsors. It's you who have kept the CMS gears in our heads turning and the Nespresso machines merrily gurgling. We are most thankful. Are you promoting an event, webinar or product? Our sponsorship packages are flexible and effective. Check out our media kit and email or phone us to discuss. Current Sponsors * Ademero -- Affordable document management solutions for small and mid-sized businesses. * CMS Watch -- The analyst firm covering and uncovering the details of the content management industry, including an in-depth SharePoint report. * Ektron -- Makers of one of the leading .NET web content management solutions. * Ephox -- Rich web content editing which blends ease of use with enterprise features. * eTouch SamePage -- The enterprise-strength wiki solution that combines the best of wikis and blogs to effectively support and streamline collaborative team efforts. * The Gilbane Group -- Conferences, reports, webinars, consulting and more. Gilbane keeps the industry informed. * Ingeniux -- Makers of Enterprise 2.0 web content management solutions. * Kentico -- The developer friendly, flexible Web CMS that's geared for ASP.NET developers. * Open Text -- Blending enterprise content management and email life cycle management Open Text manages enterprise content. * Quantum Art -- QP7 is a .NET web content management and content application platform that enables rapid development of content-centric functionality. * Sitecore -- Enterprise grade web content management with a strong eye towards .NET friendly tools and APIs. * Telerik Sitefinity -- A light-weight, modular and accessible ASP.NET web content management system that pleases both the developers and the marketers. * ...and of course dear old uncle Google Learn more about advertising with us.

PHP Developer - Fri, 11/21/2008 - 17:29

On the DZone site there's a new tutorial showing how to set up a new PHP project inside of one of the latest versions of the NetBeans IDE using a subversion repository as the base.

This article describes my experience in creating a PHP project in NetBeans IDE 6.5 from the repository version of Mediawiki. The project included 3 kinds of data that a developer would probably want to handle differently. Fortunately, the PHP Project from Existing Sources wizard made it easy to keep these 3 kinds of data separate from each other, as you will see in the following procedure.

The tutorial works through a seven-step process showing you how to point the software at your repository and have it pull in the information and automatically set up all the things you'll need (screenshots are included).

PHP Developer - Fri, 11/21/2008 - 16:38

On the Debuggable blog Tim Koschutzki has a new post showing how to get CakePHP to play nicely with a HABTM query and pagination.

The problem is that a user inputs some search criteria into a form, the resultset exceeds 30 rows for example and the user must be able to browse through the resultset via different pages. [...] This problem itself is in fact not much of a problem. We just need to store the form conditions somewhere and then hack it together. So what we are going to do is that we raise the difficulty bar a lot more by trying to get the pagination work over a HABTM relation.

Code is included for the model and controller to get the job done.

PHP Coding Practices - Fri, 11/21/2008 - 10:38

Hey folks,

this post is going to deal with the pretty common problem of paginating a search with the CakePHP framework.

The Problem

The problem is that a user inputs some search criteria into a form, the resultset exceeds 30 rows for example and the user must be able to browse through the resultset via different pages. The search criteria has to be the same everytime, the form prepopulated with the used search keywords/data and the resultset still has to match the input conditions everytime a new page is clicked.

This problem itself is in fact not much of a problem. We just need to store the form conditions somewhere and then hack it together. So what we are going to do is that we raise the difficulty bar a lot more by trying to get the pagination work over a HABTM relation.

Battlefield Briefing

We agreed we need to store the search criteria somewhere, so we can access it later. No we won't use the DB for that as it is overkill. We will also not use files, since many users may use the search at the same time screwing our hd. :P Yes, we will use the session for that as it is made exactly for these things.

For the example code we are going to use the "Advanced Search" of Flashfun247, a flashgame site which is one of my freetime projects. If you want to see some more of its code, feel free to ask.

We want to search for games based on some input conditions. The Game model is related to the GameCategory model over a HABTM relation, so the same game can be in many categories and a category contains many games. CakePHP's paginator cannot handle pagination over a HABTM so well in its current version. The incident here is that we want every game listed only once in the resultset - and not n times, where n is the number of categories it belongs to.

So we must at some point include a group by statement. However, the paginator will use that group by statement for its internal find('count') call as well, which it does to determine the size of the resultset. This will in fact corrupt the page count screwing us all over. We will see that we can trick the paginator, though. ; )

The View

To get us started, let's have a look at the view in /views/searches/advanced.ctp, which is very simple:

php
  1. <h1><?php echo $this->pageTitle = 'Advanced Game Search'; ?></h1>
  2. <?php
  3. $html->addCrumb($this->pageTitle);
  4. echo $form->create('Search', array('action' => 'advanced'));
  5.  
  6. if (isset($formData) && !empty($formData)) {
  7.   $form->data = $formData;
  8. }
  9.  
  10. echo $form->input('game_category_id', array('label' => 'Category:', 'options' => $searchCategories, 'empty' => 'All Categories'));
  11. echo $form->input('keywords', array('label' => 'Text from game name, description or instructions:'));
  12. echo $form->input('tags', array('label' => 'Is tagged with (separate tags by comma):'));
  13. $orderOptions = array(
  14.   'Game.name' => 'Name',
  15.   'GameCategory.name' => 'Game Category',
  16.   'Game.avg_rating' => 'Game Rating',
  17.   'Game.clicks' => 'Number of Plays',
  18. );
  19. echo $form->input('order_by', array('label' => 'Order Results By:', 'options' => $orderOptions));
  20. echo $form->input('order_dir', array('label' => 'Direction:', 'options' => array('asc' => 'Ascending', 'desc' => 'Descending')));
  21. ?>
  22. <div class="clear"></div>
  23. <?php echo $form->end('Search', array('action' => 'search'))?>
  24.  
  25. <?php if (isset($games)) : ?>
  26.   <div class="clear"></div>
  27.  
  28.   <?php if (!empty($games)) : ?>
  29.     <?php echo $this->element('../games/list', array('games' => $games, 'hilite' => $query))?>
  30.     <div class="clear"></div>
  31.     <?php echo $this->element('paging', array('model' => 'GameCategoriesGame'))?>
  32.   <?php else : ?>
  33.     <p class="error-message">Sorry, your search returned no results</p>
  34.   <?php endif; ?>
  35. <?php endif; ?>

It should be pretty straightforward. The only weird thing here is that $formData array. It is basically the placeholder for our search criteria that the user originally typed into the search form field. The view only needs to know where the form data is and not where it comes from. We simply assign the data to the form helper so it can prepopulate the fields for us (line 7).

The user can input here a substring of the name/description/instructions of a game and he can pick a category where the game must be in. Notice the different order options as well as the string "All Categories" for the empty option of the select tag. One other remarkable thing is that we have both isset($games) and !empty($games) calls there. This is to differentiate if the user has submitted the form already ( isset($games) ) and, if he did, the resultset is not empty which allows us to display that "Nothing found" message.

Here is the /views/games/list.ctp view just so you have the complete code:

php
  1. <?php
  2. $short = isset($short) ? $short : false;
  3. $class = $short ? ' short' : '';
  4. ?>
  5. <div class="games-list">
  6.   <?php foreach ($games as $game) : ?>
  7.     <div class="game<?php echo $class ?>">
  8.       <div class="game-image">
  9.         <?php echo $this->element('game_image', array('game' => $game, 'thumb' => true))?>
  10.       </div>
  11.       <div class="game-descr">
  12.         <?php
  13.         $name = $game['Game']['name'];
  14.         if (isset($hilite)) {
  15.           $name = $text->highlight($game['Game']['name'], $hilite);
  16.         }
  17.         echo $html->link($name, Game::url($game), null, false, false);
  18.         ?>
  19.         <?php if (!$short) : ?>
  20.          
  21. <?php echo $game['Game']['short_desc'] ?>
  22.  
  23.           <div class="plays"><span>Plays:</span> <?php echo $game['Game']['game_playing_count']?></div>
  24.         <?php endif; ?>
  25.       </div>
  26.     </div>
  27.   <?php endforeach; ?>
  28. </div>
  29. ?>

Straightforward... Let's move on to the paging element:

php
  1. <?php
  2. if (!isset($model) || $paginator->params['paging'][$model]['pageCount'] > 1) : ?>
  3. <div class="paging">
  4.   <?php echo $paginator->prev('&laquo; Previous', array('escape' => false, 'class' => 'prev'), null, array('class'=>'disabled'));?>
  5.   <?php echo $paginator->numbers();?>
  6.   <?php echo $paginator->next('Next &raquo;', array('escape' => false, 'class' => 'next'), null, array('class'=>'disabled'));?>
  7. </div>
  8. <?php endif; ?>

Notice the different checks at the start in order to figure out if we need to display a div at all.. This is called in the advanced.ctp view and the model GameCategoriesGame is supplied, which is a convenience HABTM model which belongsTo both Game and GameCategory.

The controller action

The controller action might appear a little big at first glance. However, every line has its purpose. This is in a SearchesController. You could have your own search() method though in about any controller.

php
  1. function advanced() {
  2.     $searchCategories = $this->Game->GameCategory->find('list', compact('conditions'));
  3.     $this->set(compact('searchCategories'));
  4.  
  5.     $page = 1;
  6.     if (isset($this->params['named']['page'])) {
  7.       $page = $this->params['named']['page'];
  8.     }
  9.  
  10.     $formData = array();
  11.     $sessionKey = 'advanced_search_query';
  12.     if (isset($this->data['Search']['keywords'])) {
  13.       $formData = $this->data;
  14.       $this->Session->write($sessionKey, $formData);
  15.     } elseif ($this->Session->check($sessionKey)) {
  16.       $formData = $this->Session->read($sessionKey);
  17.     } else {
  18.       Assert::true(false, '404');
  19.     }
  20.     $this->set(compact('formData'));
  21.  
  22.  
  23.     if (!empty($formData)) {
  24.       $query = $formData['Search']['keywords'];
  25.       $useQuery = trim(low($query));
  26.  
  27.       $conditions = array();
  28.       if (!empty($formData['Search']['game_category_id'])) {
  29.         $conditions['GameCategoriesGame.game_category_id'] = $formData['Search']['game_category_id'];
  30.       }
  31.       $conditions = am($conditions, array(
  32.         'Game.published' => '1',
  33.         'or' => array(
  34.           'LOWER(Game.name) LIKE' => "%{$useQuery}%",
  35.           'LOWER(Game.short_desc) LIKE' => "%{$useQuery}%",
  36.           'LOWER(Game.long_desc) LIKE' => "%{$useQuery}%",
  37.           'LOWER(Game.instructions) LIKE' => "%{$useQuery}%"
  38.         )
  39.       ));
  40.  
  41.       $this->GameCategoriesGame->forcePaginateCount = $this->GameCategoriesGame->paginatorCount(
  42.         'game_categories_games', $conditions, array('Game')
  43.       );
  44.       $contain = array('GameCategory', 'Game.Tag');
  45.       $order = array('Game.name' => 'asc');
  46.  
  47.       if (!empty($formData['Search']['order_by'])) {
  48.         $order = array($formData['Search']['order_by'] => $formData['Search']['order_dir']);
  49.       }
  50.  
  51.       $this->paginate['GameCategoriesGame'] = array(
  52.         'conditions' => $this->GameCategoriesGame->paginatorConditions('game_categories_games', $conditions),
  53.         'contain' => $contain,
  54.         'order' => $order,
  55.         'limit' => 12
  56.       );
  57.       $games = $this->paginate('GameCategoriesGame');
  58.       $this->set(compact('games', 'query'));
  59.     }
  60.   }

So we are first loading all our game categories to populate the select tag. Then we check if there is a named parameter "page" given. If so, the user clicked on the Previous/Next/Numbered links. If it is not present, we might as well start at page 1. ; ]

Now comes the tricky part. We check if the form was submitted via empty($this->data). If it is submitted, we store all the form data in the session. If the form is not submitted we try to recover the form data from the session. If both the form is not submitted and there is no data in the session, but it still a Get request, something bad happened and we fire the user by asserting the yummyness of his cake.

The rest should be familiar - some processing of the $formData array to extract the proper conditions and order stuff. The most interesting stuff now is that call to $this->GameCategoriesGame->paginatorCount('game_categories_games', $conditions, array('Game'));. This enables us to paginate over the HABTM relation (Game HABTM GameCategory). Here is the code from the GameCategoriesGame model:

php
  1. <?php
  2. class GameCategoriesGame extends AppModel {
  3.   var $name = 'GameCategoriesGame';
  4.   var $belongsTo = array('GameCategory', 'Game');
  5.  
  6. /**
  7.  * Return count for given pagination
  8.  *
  9.  * @param string $paginator Pagination name
  10.  * @param array $conditions Conditions to use
  11.  * @return mixed Count, or false
  12.  * @access public
  13.  */
  14.   function paginatorCount($paginator, $conditions = array(), $contain = array()) {
  15.     $Db = ConnectionManager::getDataSource($this->useDbConfig);
  16.     if (!empty($contain)) {
  17.       $related = ClassRegistry::init($contain[0]);
  18.     }
  19.  
  20.     $sql = 'SELECT
  21.       COUNT(DISTINCT ' . $this->alias . '.' . $this->belongsTo['Game']['foreignKey'] . ') count
  22.     FROM ' . $Db->fullTableName($this->table) . ' ' . $Db->name($this->alias) . ' ';
  23.     if (!empty($contain)) {
  24.       $sql .= ' INNER JOIN ' . $Db->fullTableName($related->table) . ' ' . $Db->name($related->alias) . ' ';
  25.     }
  26.     $sql .= $Db->conditions($this->paginatorConditions($paginator, $conditions, 'count'));
  27.  
  28.     $count = $this->query($sql);
  29.  
  30.     if (!empty($count)) {
  31.       $count = $count[0][0]['count'];
  32.     }
  33.     return $count;
  34.   }
  35. /**
  36.  * Build conditions for given pagination
  37.  *
  38.  * @param string $paginator Pagination name
  39.  * @param array $extraConditions Extra conditions to use
  40.  * @param string $method 'count', or 'find'
  41.  * @return array Conditions
  42.  * @access public
  43.  */
  44.   function paginatorConditions($paginator, $extraConditions = array(), $method = null) {
  45.     $Db = ConnectionManager::getDataSource($this->useDbConfig);
  46.     $conditions = null;
  47.     if (empty($extraConditions)) {
  48.       $extraConditions = array('1=1');
  49.     }
  50.     switch (strtolower($paginator)) {
  51.       case 'game_categories_games':
  52.         if ($method != 'count') {
  53.           $conditions = array_merge($extraConditions, array('1=1 GROUP BY ' . $this->alias . '.' . $this->belongsTo['Game']['foreignKey']));
  54.         } else {
  55.           $conditions = $extraConditions;
  56.         }
  57.         break;
  58.     }
  59.     return $conditions;
  60.   }
  61. /**
  62.  * Executed by the paginator to get the count. Overriden to allow
  63.  * forcing a count (through var $forcePaginateCount)
  64.  *
  65.  * @param array $conditions Conditions to use
  66.  * @param int $recursive Recursivity level
  67.  * @return int Count
  68.  * @access public
  69.  */
  70.   function paginateCount($conditions, $recursive) {
  71.     if (isset($this->forcePaginateCount)) {
  72.       $count = $this->forcePaginateCount;
  73.       unset($this->forcePaginateCount);
  74.     } else {
  75.       $count = $this->find('count', compact('conditions', 'recursive'));
  76.     }
  77.     return $count;
  78.   }
  79. }
  80. ?>

To make a long story short: You see we build up the count query on our on and then force Cake to use our calculated count via our own forcePaginateCount property of the model. The Group BY is already in there, we can supply extra conditions and have different queries for different types (see the switch statement in paginatorConditions).
Alas, we have to build the sql on our own for the JOINs, which can become a headache for more complex problems. Anyway, this code gives us enough flexibility to build the right pagination for every problem. :) If you can think of a problem this code cannot be used for, please let me know and we discuss.

The paginateCount() method could go into your AppModel, I just put it here to have the code in one place to keep it simpler.

Conclusion

The method presented has some advantages and disadvantages, as always. The advantages would definitely include that we don't have to extend the controller's paginate() method in our app controller. This is what many people do and what I did in the past as well. However, as always, it's not good manners to hack the core.
Another advantage is the flexibility of the code - with just one line, we can calculate pagination counts for almost every occasion, and even if we paginate over two or three HABTM relations (I can show you later).

Disadvantages include some bloat in your models and the need to write sql again (*sigh*), which can become very complex if you have to supply all the JOINS yourself for more complex problems. Apart from that the code does not yet have full integration of the containable behavior. However, that I can add later.

I hope you liked the article and can put it to some use. Credits go to mariano for the original idea for this. If you guys are interested in seeing how I coupled the "Save search" feature from here with all of this, feel free to ask and we can have some nice discussion.

Categories: PHP, Web Programming

PHP Developer - Fri, 11/21/2008 - 10:31

The NETTUTS.com blog has a new screencast posted showing how to create a simple thumbnailing script you can use in any application (like an image gallery).

In this week's screencast, I'll show you how to upload files and then have PHP dynamically create a thumbnail. Whether you're building an ecommerce site, or just a simple gallery, these techniques will absolutely prove to be useful. If you're ready for your "spoonfed" screencast of the week, let's get going!

The post also includes all of the code and HTML that you'll need to get it up and running (very cut and paste-able).

CMSWire - Fri, 11/21/2008 - 10:06
When it comes to search, Google typically has the solution. Site-specific search isn't that different. But Lijit, a company focused on providing site search services for blogs and Web sites, claims that Google is not nearly as invincible as the company is portrayed. Lijit is supposedly not too far behind, and this innovative start up could perhaps overtake Google in the near future.

CMSWire - Fri, 11/21/2008 - 09:53
Social Media moves so fast, its hard to keep up. Here’s the week’s top stories, in scan-friendly format. This week: * Yahoo Glue Comes to the US * Using Tarpipe to Unclog the Social Media Pipe * Google's Getting a SearchWiki * Get Yer Free Blog on TypePad

CMSWire - Fri, 11/21/2008 - 09:34
Six Apart knows there's nothing worse than an out of work journalist. That's why the company who makes the major commercial blogging platforms TypePad and Movable Type is offering pro-level blog memberships for free to out-of-work media types.

PHP Developer - Fri, 11/21/2008 - 08:07

PHPBuilder.com has posted a list of resources that they offer to help both beginning and experienced PHP developers to further their knowledge:

PHP is one of the most popular scripting languages used to develop applications on the web today. As a result, internet.com has a multitude of PHP resources throughout our network of websites. Here are some of our best PHP resources, along with some featured tutorials and out-of-network resources that you may not know about.

The grouping of links also include external resources like the main PHP site and Zend's website.

CMSWire - Fri, 11/21/2008 - 08:00
They've only been publicly available for four months, but the Web 2.0 community solution cubeless is already picking up awards right and left, including becoming a finalist in the Forrester Groundswell Awards.

CMSWire - Fri, 11/21/2008 - 07:10
PaperThin, the producer of ColdFusion-based Web CMS CommonSpot, announced that its 2008 Q2 and Q3 revenues shattered all company records, having grown an average of more than 50% year over year. Furthermore, the company’s average deal size increased by more than 30%. Now, it’s time to update the product, perhaps. And PaperThin plans on doing so in 2009. The last major product release from PaperThin was in October, 2007, when CommonSpot 5.0 came out.

CMSWire - Fri, 11/21/2008 - 07:00
Take your enterprise community to new venues with Socialcast. They have released some new accessibility features to their social networking and micro-blogging platform, including access via Gmail and your iPhone.

CMSWire - Fri, 11/21/2008 - 06:00
From East to West... Ektron is now ready to jump into those cowboy boots and embrace the oh-so-desired Bay Area. The Web CMS vendor (quite predictably so) announced the opening of two new offices -- in San Francisco, California, and in Austin, Texas. The addition of the new offices will extend Ektron’s market reach and provide additional support and services critical to the company’s expanding customer base and partner channel. Ektron reports increasing demand for its products and services over the past 5 years. It also shows the revenue growth rate of over 400%. During the past two years, due to the consistent increase in sales and ongoing development of the company’s partner channel, Ektron grew staff levels to approximately 200 employees and opened offices in Toronto, Canada, Sydney, Australia and the U.K. The new San Francisco office will serve as a services and training facility. The Austin office will provide additional sales and services resources. Coming on the heels of the September announcement of Ektron CMS400.NET v7.6 and Ektron’s new deployment options, Ektron is expanding big time. No wonder -- it’s cheap, flexible, gets accolades every now and then and demos well.

Identity Woman - Thu, 11/20/2008 - 15:10

I am Canadian so you can probably guess how I would have voted if I could have on Proposition 8 (the California constitutional amendment to define marriage as only between a man and a woman).
My views are not the point of this post. I am very concerned about what is playing out - online and in real life between the two sides of this issues following the passage of the amendment.

First of all we live in a democracy - the people of California voted for it - albeit by a small percentage but that was the will of the people.

When I look at this I think well the way the NO side wins is by doing all the work the YES side did last time - only better. They go and put an amendment to the constitution on the ballot and then build support for it.

The NO campaign assumed it couldn’t loose, was badly organized, didn’t have a comprehensive strategy for building support for its side across diverse communities throughout California. (The YES campaign was on the ground engaging with the black church community for example - they never saw anyone from the NO side come to their communities to engage them on the issue).

As the vote approach the NO side in a final very flawed move started attacking in television adds those who funded the YES side of the proposition and in particular the Mormon Church.

It was this turn of events that has lead into quite disturbing actions and behaviors by the NO campaign post election.

The blacklisting and subsequent public harassment and targeting of specific people and specific religious groups for their beliefs and support of YES on prop 8 is wrong.

I take this personally, I have and do work with people who are Mormon - (When I played water polo in university and in the Identity field). I respect the LDS church and the people in it - they have good values. Their religion is a very American one too (like Christian Science its origins are on this continent). Watch the Frontline/American Experience 4 hour documentary on the history of the church and their experience as a people/religious group.

A close personal family member I know also voted YES and for all I know could have donated.

When mobs start appearing at places of residence of YES contributors and their businesses. It makes me worried.

I thought about this issue earlier in the campaign when I wrote this post There are a lot of donkey’s in my neighborhood (and I know who they are)

From The Hive:

because she did about 60 gay ‘activists’ went to her restaurant and strong armed her in a scene reminiscent to Nazi Germany. They went down a list of people who gave as little as 100 dollars to boycott, harrass and attack them. They went there to ‘confront’ her for giving a measley hundred bucks based on her personal faith that she has had since childhood. They argued with her and it was reported by local news reporters was a “heated” confrontation.

So is this the America we want? Where if a private citizen wants to participate in the governmental process that they be harrassed and acosted. Their freedom of speech chilled by thugs.

From the NY Times:

The artistic director, Scott Eckern, came under fire recently after it became known that he contributed $1,000 to support Proposition 8…
In a statement issued on Wednesday morning, Mr. Eckern said that his donation stemmed from his religious beliefs — he is a Mormon — and that he was “deeply saddened that my personal beliefs and convictions have offended others.”

From the SF Chronicle:

Phillip Fletcher, a Palo Alto dentist who donated $1,000 to the campaign, is featured prominently on a Web site listing donors targeted for boycott. He said two of his patients already have left over the donation.

This is the site of the Anti Gay Blacklist Then there is a blog called Stop the Mormons.

The night Obama won and there was a party in the main street 6 blocks from my house - I had a moment of insight into the future. This was a happy celebratory Mob - it was basically safe. People were texting their friends and telling them where it was inviting them to join. I Tweeted about it so 900 people knew about it and where it was. I also knew that this new technology of texting and presence based real time information creates an increased capacity for mob formation. It made me wonder about the cultural skills and capacities we need to develop to interrupt mob behavior turning bad.

I think what is going on with the blacklists - that are directly targeting people in their private life is wrong. I think targeting specific religious institutions for protest is wrong.

These people and these religious institutions are not propagating HATE they are just not agreeing that marriage can be between a man and a man or a woman and a woman. This is a cultural difference of opinion.

I “get” where many of the gay activists are coming from - but it is not a place that will get them what they want. Many “fled” to the Bay Area to find a community and place where they could be who they were (gay, lesbian, queer, transgender etc). They were raised in conservative churches in other parts of the country that may have been explicitly anti-gay. They likely have strong feelings against these institutions and similar ones. It does not make it OK to the hate these people and act out against them. (If they want to proactively work on cultural change within these communities - Soul Force is doing a good job using nonviolence to work on change.)

We in the identity community need to understand what has unfolded here. The No on Prop 8 groups are using publicly available information. However this used to be information you could get if you went and asked for the paper versions from the court house. So it was public but with high friction to get the information. The web lowers the cost of getting this information (close) to zero - Daniel Solove writes about the change in publicly available information in the Digital Person.

I wonder about how we can balance the need to know who has contributed to political campaigns and propositions while at the same time prevent harassment and the emergence of negative physical and cyber mobs.

Categories: Web 2.0

CMSWire - Thu, 11/20/2008 - 14:50
Nearing the end of its Content World 2008 Conference, Open Text announced new plans for its eDOCS product line that will give customers the flexibility to leverage the latest ECM technology. The plan includes new enhancements for eDOCS, more integrations with the Open Text ECM suite and more play time with Microsoft.

CMSWire - Thu, 11/20/2008 - 14:05
Social media is one of the fastest growing marketing areas on the Internet today. It allows marketers and business owners to advertise and market in ways that were unheard of 5-10 years ago. Every major corporation (and many small businesses and start-ups) out there is currently using social media. The problem inherent with social media is the fact that a proper social media campaign can be extremely time-consuming, very costly and may require a large team of people. Let’s face it -- most of us already know that there is an insane amount of sites, software, services and methods out there. A social media campaign can be exhausting. Enter Shoutlet, a tool that makes managing all your social marketing campaigns a snap.

CMSWire - Thu, 11/20/2008 - 11:30
Chances are if you're easily frustrated and regularly discouraged by the failure of computers, cell phones and the Internet, you're old. That's not criticism, though. It's the results of a recent study released by the Pew Research Center's Internet & American Life Project. The study, based on a survey of over 2000 U.S. adults, took an in-depth look at how people felt and reacted to problems with technology, whether it is a loss of Internet connection or a broken iPod.

CMSWire - Thu, 11/20/2008 - 11:22
Drupal is one of the most mentioned open source Web content management system out there today. But not everyone knows about it and how it fits into the content management world. So if you are one of those people, or just want a refresher, O'Reilly is hosting a webinar entitled: Everything you Wanted to Know About Drupal but were Afraid to Ask.