Friday, September 20, 2013

College Fun - bootstrap framework basics

Okay guys so I'm at college now and busier than ever before.  Currently I'm working on a plugin for an image theme for a few friends on WJ.  I'm also learning to work with bootstrap as I'm getting a job developing for someone.  I can't describe any details about the job and I won't be able to post any of my work but I will be able to post everything learned about bootstrap: http://getbootstrap.com/2.3.2/getting-started.html  And I'm not going to post anything about the plugin yet, but I will as soon as it's done.  For now here's my notes/progress with the bootstrap framework:
  • Bootstrap needs HTML5 as well as jQuery
  • Bootstrap sets a basic css template to work off of that controls the global display, typography and link styles.  In specific it:
    • Found in scaffolding.less:
      • removes the body margin
      • makes the body bg color white
      • uses @baseFontFamily, @baseFontSize and @baseLineGeight attributes as our typographic base.
      • set link color with @linkColor and applies underline affect on hover
    • Found in reset.less:
  • without responsive css added, the bootstrap grid system uses a 12 col layout with a 940px wide container.
  • with responsive css, grid adapts to be 724px and 1170px depending on the viewing screen res.
    • with this the columns become fluid and stack under each other
  • Because there are 12 columns you need to make the spans add up to = 12.  For example:
<div class="row">
     <div class="span5">...</div>
     <div class="span5">...</div>
     <div calss="span2">...</div>
</div>
  • This creates a filled row.  In the old bootstrap (2.x) you used to have to enter .row-fluid but in the new version of bootstrap you just use .row* and it's fluid automatically because there's no more "fixed grid".
  • You use .offset* for shifting columns.
  • For embedding two spans it would look like this:
<div class="row">
   <div class="span10">
     <div class="row">
        <div class="span6">...</div>
        <div class="span4">...</div>
     </div>
   </div>
</div>

  • Use .container for different sections of the website.
Okay so this pretty much covers all the basics that I need to know about the bootstrap framework.

Saturday, August 17, 2013

Me again - custom image post type release

So I've successfully created the image variation custom post type which can be viewed live here: http://wpprojects.net63.net/?image_post=testing-the-image-post-type

The code for it can be seen here: https://gist.github.com/C-onnor/6258300

I like the way it came out.  I'm sure I'll think of some new changes and other people will as well if they look through the code.  Another thing of done today is messed with the content.php file and made it so only images will be displayed on the homepage and a no-image picture will be shown if there was no featured image set: http://pastebin.com/atzAXQZ5

What's next?  Idk, people keep promising me work and shit but so far no ones actually come through for me even when I'm doing everything for free.  I'm gunna go back to making that b4b theme now and I'll save that for next post.

Wednesday, August 7, 2013

Adding a custom meta box to a custom post type day 2

Continuing off of yesterday, now that I have the CPT (custom post type) publishing problem solved I'm concentrating on the meta box again.  I need to figure out a way to add inputs for inputting data.  How?  I'm not sure yet so I've decided to take a look at this plugin, http://wordpress.org/plugins/ml-slider/, that uses something similar with the add slide button.

I looked at the code from this for a couple of hours and got nowhere.  So I foraged through a bunch of google search results and found code that does exactly what I wanted to do: https://gist.github.com/da1nonly/2057532
I mean it doesn't have the exact columns (inputs) I need but that's for me to change.  First I need to understand the results and it's a bit late for that right now so I'm going to bed.  Goodnight people.

Adding a custom meta box to a custom post type day 1

Building off of yesterday's progress (http://persteezy.blogspot.com/2013/08/custom-post-types-in-wordpress.html) there was an argument called register_meta_box_cb that was for a callback function that could be used to add a custom meta box using the add_meta_box func: http://codex.wordpress.org/Function_Reference/add_meta_box
add_meta_box(id, title, callback, post type, context, priority, callback args);

  • id - ID of the meta box section
  • title - visible title of the meta box
  • callback - function for generating the meta box html and can only accept two args from the callback args parameter.
  • post type - the post type you want the meta box in (Can I add this to the default post?)
  • context - choose where you want the meta box (normal, advanced or side)
  • priority - choose how important (placementwise) the meta box is
  • callback args - arguments passed on to the callback func
So with just a few additions/mods to the code this is what it looks like now: http://pastebin.com/89rrkuww
Which makes the image post type look like this:

Now reading through tutorials for creating inputs (http://wp.tutsplus.com/series/reusable-custom-meta-boxes/) they seem to follow outdated techniques I saw when first trying to create my options panel.  Skimming through other tutorials (that are a bit newer), I'm seeing the same thing.  What gives?  So the add_settings_section, add_settings_field and register_setting can't be used here?  Well, I'm going to try using them anyways and I'll see how that works out for me (hopefully well).

After trying out the settings api they do in fact work but only with the save changes button which wouldn't work.  I've also coded it the wrong way: http://pastebin.com/h0TZ1b3Z

So starting over again I need to rethink how I'm going to code this.  Before that comes though I've found that the post type isn't even working.  I keep getting the error "You are not allowed to edit this post" so I went to stackexchange for help: http://wordpress.stackexchange.com/questions/109243/cant-publish-custom-post-type-you-are-not-allowed-to-edit-this-post/
And with the community's help I found a fix but I'm unsure why it's working.

I meant to post this last night but forgot so I'm posting it today lol

Monday, August 5, 2013

Custom post types in wordpress

Today I've upgraded majority of my localhost wp blogs to wp 3.6: http://codex.wordpress.org/Version_3.6#Scripts.2C_External_Libraries
I've also been given a new task from someone on skype.  The task is to create a custom post type that works as the default post type but also has a custom meta box (named image) with input fields for color, size, download link.  This is a simple sketch as to what I want it to look like this:
Okay so I've messed with custom post types before but I forget how to get started with them and can't find a post on here about it so I'm just gunna take some notes on this: http://codex.wordpress.org/Post_Types

First off, custom post types get registered using the register_post_type func: http://codex.wordpress.org/Function_Reference/register_post_type
register_post_type(Name, Args);

This function must be hooked before the admin_menu and after_setup_theme hooks.  It's recommended that the init hook is used.  At the end of today using what I've read so far this is the code I've made for the custom post type: http://pastebin.com/nxvqPFu5

Now that I've learned to add the custom post type I can focus on adding a custom meta box tomorrow.

Saturday, August 3, 2013

Cool guy has chill day

Not much went on today.  I talked to a few people on WJ.  I know I said I stopped with forums but I feel I need to go back to build up a portfolio.  So while talking to people an idea popped into my head where I create a group of people looking to do free conversion services in order to buildup their portfolio.  I've created a thread to recruit people here: http://www.wjunction.com/92-development-area/177734-looking-build-your-portfolio.html
Unfortunately there have been no takers to the idea which could be foreshadowing the future.

Anyways while waiting for people to PM me I saw this thread in the dev section: http://www.wjunction.com/92-development-area/177510-why-php-domdocument-getelementsbytagname-not-finding-all-elements.html#post1868952
I could not solve his problem but in attempting to do so I learned a couple new things.   The first thing I learned was that since majority of web pages don't have properly formatted html PHP DOM will throw an amazing amount of annoying error messages that look like this:
To avoid this I followed one of the answers to this post: http://stackoverflow.com/questions/7082401/avoid-domdocument-xml-warnings-in-php

Anyways there's 13 links on the page that Filenuke (the user on wj seeking help) is trying to scrape.  His code scraped 8 links and my code scraped 9 links (not much better).  Here's my end result: http://pastebin.com/QEje2be0

Other than this, nothing else happened today.  Maybe I'll shift back into the crypter or wordpress tomorrow.  Pce!

Back from a malware attack!

Well recently I was the victim of a Java Drive-by (JDB).  I don't think the malware came from opening anything related to the crypter.  Anyways thanks to Paradoxum's help on HF the malware is gone and my system is much more secure than before.  To see everything that happened, check this thread: http://hackforums.net/showthread.php?tid=3661673

Now that this is over I'm back to posting normally again.

Tuesday, July 30, 2013

Switchin it up - Learning how a crypter works

Today I switched things up and decided to see how a vb.net crypter works.  I searched through HF for a simple crypter source and found just what I needed: http://www.hackforums.net/showthread.php?tid=3556669&highlight=Castle+Crypter+V0.1+Source

I've begun the process of going through literally every single line of code to fully understand everything.  This is what the solution explorer looks like for the crypter:
So far I've only fully summarized the Form1.vb: http://pastebin.com/xSTSmt1V
In doing so I've gotten a pretty good idea of what each file is good for:

  • Form1.vb - holds the encrypt and random string functions, filepaths, encryption keys, replacements that are made to the stub code and compilation of the crypted file as well as the addition of a resource that holds the encrypted code.
  • Stub.txt - holds the stub source for a runPE type crypt.
  • Stub 2.txt - holds the stub source for a drop type crypt.
  • clsCodeDom.vb - holds the Compile function where the codedom import is used.  I think this is done to avoid detections but I'm not sure.
  • IconChanger.vb - holds the InjectIcon function where the selected icon (if there is one) is implemented to the crypted file.
  • Controls folder - contains .vb files used for creating custom controls (not important).
  • Stub 1 & 2 Edit.vb - same as Stub.txt and Stub 2.txt juts in .vb files so you can see and edit things a little bit easier.
In the end, I hope to comment out the stub files and codedom and iconchanger classes as well.  This topic interests me quite a bit and it feel nice to take a break from wordpress and web development.

Monday, July 29, 2013

Continuing yesterdays efforts - day 11

Continuing off of yesterday I figured out how to get the twitter dialog working correctly thanks to this dude: http://gpiot.com/elegant-twitter-share-button-and-dialog-with-jquery/
Here's the working code:
$content .= '<li><a href="#" onclick="window.open(\'https://twitter.com/share?url=' . esc_url('http:\\' . $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"]) . '&text=Check this out!: ' . esc_url($_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"]) . '&\', \'facebook-share-dialog\', \'width=626,height=436\'); return false;">tw</a></li>';
To get it to work I just had to had the &text attribute.

Now for the google plus button.  I ran into the same issue as the twitter button leaving me to believe that I need to find out why I can't use $_SERVER commands or get_permalink for the url.  I revised the entire function so it looks like this now:
function b4b_sharing_enabled($content){

$b4b_options = get_option('b4b_theme_display_options');

$b4b_share_post_enable = $b4b_options['share_post_enable'];


if ($b4b_share_post_enable && is_single() || is_page()){
$url = get_permalink();
$content .= '<nav class="sharethis"><ul>';
$content .= '<li><a href="https://www.facebook.com/sharer/sharer.php?u=' . esc_url($url) . '" onclick="window.open(this.href, \'facebook-share-dialog\', \'resizable=yes,width=626,height=436\'); return false;">facebook</a></li>';
$content .= '<li><a href="https://twitter.com/share?url=' . esc_url($url) . '" onclick="window.open(this.href, \'twitter-share-dialog\', \'resizable=yes,width=626,height=436\'); return false;">twitter</a></li>';
$content .= '<li><a href="https://plus.google.com/share?url=' . esc_url($url) . '" onclick="window.open(this.href, \'googleplus-share-dialog\', \'resizable=yes,width=626,height=436\'); return false;">googleplus</a></li>';
$content .= '</ul></nav>';
return $content;
} else {
return $content;
}
}
add_filter('the_content', 'b4b_sharing_enabled');
I couldn't figure this out on my own so I've asked a question on it here: http://wordpress.stackexchange.com/questions/108241/sharing-buttons-url-doesnt-show-up-in-dialog-box
While waiting for people to answer I'm going to work on the footer settings because I'm going to include the implication of the author bio in the same b4b_sharing_enabled function (except I'll rename it).

This is what I wrote for applying all of the footer options:
function b4b_footer_options(){
$b4b_options = get_option('b4b_theme_display_options');
$b4b_social_icons_enable = $b4b_options['social_icons_enable'];
$b4b_facebook_url = $b4b_options['facebook_url'];
$b4b_twitter_url = $b4b_options['twitter_url'];
$b4b_footer_text = $b4b_options['footer_text'];

if($b4b_social_icons_enable){
?>
<nav class="socialicons">
<ul>
<?php
if($b4b_facebook_url != ''){
echo '<li><a href="' . $b4b_facebook_url . '">facebook</a></li>';
}
if($b4b_twitter_url != ''){
echo '<li><a href="' . $b4b_twitter_url . '">twitter</a></li>';
}
?>
</ul>
</nav>
<?php
}

if($b4b_footer_text != ''){
echo '<p>' . $b4b_footer_text . '</p>';
}
}
add_action('wp_footer', 'b4b_footer_options');

This is what the footer.php looks like now after a few modifications to it: http://pastebin.com/Vb7sFU9f
One issue I've noticed though is that you can enter in non-urls into the facebook and twitter url inputs and the text in footer input is too small.  This means I need to make some adjustments to the validation function and input callback.
I've split up the textarea callback into an input and textarea callback.  Here's what I'm left with after making these changes:
function b4b_input_callback($args){
$options = get_option('b4b_theme_display_options');
if($args[0]=="number_of_posts"){
$html = '<input type="number"';
$html .= ' pattern="\d*"';
} elseif ($args[0]=="facebook_url" || $args[0]=="twitter_url"){
$html = '<input type="url"';
} else {
$html = '<input type="text"';
}
$html .= ' id="' . $args[0] . '" name="b4b_theme_display_options[' . $args[0] . ']" value="' . $options[$args[0]] . '" />';

echo $html;
}

function b4b_textarea_callback($args){
$options = get_option('b4b_theme_display_options');
$html = '<textarea id="' . $args[0] . '" name="b4b_theme_display_options[' . $args[0] . ']" rows="' . $args[1] . '" cols="' . $args[2] . '">' . $options[$args[0]] . '</textarea>';

echo $html;
}

The footer_text field is the only option utilizing the textarea callback.  Upon completing this I've also come to realize that I left all the applied options in the header.php and never took them out to put in the theme-options.php; so I'll make these changes now.  First I changed the header to this:
Then I added the following hook function: http://pastebin.com/cqsmRnrT
function b4b_header_options(){
$b4b_options = get_option('b4b_theme_display_options');
$b4b_header_type = $b4b_options['header_type'];
$b4b_header_image = $b4b_options['header_image'];
$b4b_header_title = $b4b_options['header_title'];
$b4b_header_slogan = $b4b_options['header_slogan'];

if ($b4b_header_type == 'image'){ ?>

<a href="<?php echo esc_url( home_url( '/' ) ); ?>" title="<?php echo esc_attr( get_bloginfo( 'name', 'display' ) ); ?>" rel="home">
<img src="<?php echo $b4b_header_image; ?>" alt="logo" />
</a>

<?php } elseif($b4b_header_type && $b4b_header_title == '' && $b4b_header_slogan == '') { ?>

<h1 class="site-title"><a href="<?php echo esc_url( home_url( '/' ) ); ?>" title="<?php echo esc_attr( get_bloginfo( 'name', 'display' ) ); ?>" rel="home"><?php bloginfo( 'name' ); ?></a></h1>
<h2 class="site-description"><?php bloginfo( 'description' ); ?></h2>

<?php } elseif($b4b_header_type && $b4b_header_title != '' && $b4b_header_slogan != '') { ?>

<h1 class="site-title"><a href="<?php echo esc_url( home_url( '/' ) ); ?>" title="<?php echo esc_attr( $b4b_header_title ); ?>" rel="home"><?php echo esc_attr( $b4b_header_title ); ?></a></h1>
<h2 class="site-description"><?php echo $b4b_header_slogan ?></h2>

<?php }
}
add_action('site-branding', 'b4b_header_options');

Please note: The site-branding hook is the custom hook that I added into the header.php.

After all the changes I've wrote about so far this is what the theme-options.php currently looks like: http://pastebin.com/LvXcsGPr

I still haven't received any help on the sharing buttons problem so I have the rare opportunity to work on something different.  I'm going to browse through the tutorials on wp.tutsplus.com cause I can always find something new on there.  This tutorial series about coding standards seems useful and interesting so I'm going to summarize whatever I get through: http://wp.tutsplus.com/series/the-wordpress-coding-standards/

Well, I got distracted and went out instead.  I'm going to sleep now, so if there isn't any type of assistance tomorrow I'll come back to it.

Sunday, July 28, 2013

New plans for coding the options panel - day 10

I've decided that it would be a could idea to keep all (or as much as possible) of the settings usage in the theme-options.php.  Why?  I just like the idea of making it a lot more portable so I can bring it to other themes I work on.  This being said, with the help of the query_posts wp documentation I removed the usage of query_posts from the index.php and used the pre_get_posts hook in the theme-options.php instead:
function b4b_number_of_posts($query){
$b4b_options = get_option('b4b_theme_display_options');
$b4b_number_of_posts = $b4b_options['number_of_posts'];
if($b4b_number_of_posts != '' && $query->is_home() && $query->is_main_query()){
$query->set('posts_per_page', $b4b_number_of_posts);
}
}
add_action('pre_get_posts', 'b4b_number_of_posts');


Now I can go back to the share this buttons.  First I need to find the hook that I can use for the usage function which I'm looking for in here: http://codex.wordpress.org/Plugin_API/Action_Reference
I thought pre_get_commments would be what I was looking for but upon running the following code it only puts "TESTING" before the recent comments widget:
function b4b_sharing_enabled(){
echo '<h1><b>TESTING</b></h1';
}
add_action('pre_get_comments', 'b4b_sharing_enabled');


After reading through this article, http://wp.tutsplus.com/tutorials/the-beginners-guide-to-wordpress-actions-and-filters/, I've realized I need to look for a filter instead in here: http://codex.wordpress.org/Plugin_API/Filter_Reference

So to add something to the end of your content I've found you only have to do this:
function b4b_sharing_enabled($content){
$content .= '<h1><b>TESTING</b></h1>';
return $content;
}
add_filter('the_content', 'b4b_sharing_enabled');


Leaving you with:

I've been working on the social buttons for a couple hours now only to get stuck on the damn twitter button.  Here's the current code:
function b4b_sharing_enabled($content){
$content .= '<nav class="sharethis"><ul>';
$content .= '<li><a href="#" onclick="window.open(\'https://www.facebook.com/sharer/sharer.php?u=' . esc_url('http:\/\/'.$_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"]) . '\', \'facebook-share-dialog\', \'width=626,height=436\'); return false;">fb</a></li>';
$content .= '<li><a href="#" onclick="window.open(\'https://twitter.com/share?url=' . esc_url('http:\\' . $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"]) . '\', \'facebook-share-dialog\', \'width=626,height=436\'); return false;">tw</a></li>';
$content .= '</ul></nav>';
return $content;
}
add_filter('the_content', 'b4b_sharing_enabled');


The popup for the twitter button works but the problem is the url doesn't show up in the tweet like it should.  If I replace $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"] with a simple url like google.com it works.  Why is this the issue?  I guess I'll just have to take a look at it tomorrow.  I'm done today.

Saturday, July 27, 2013

Options Panel - day 9

So continuing from yesterday I'm working on the number of posts per page option.  The first thing I was working on was choosing whether to remove numbers using jquery on keyup or using php and just changing the input type.  The jQuery version looks like this:
//only allow numbers to be entered
$('#number_of_posts').keyup(function(e){
if(/\D/g.test(this.value)){
this.value = this.value.replace(/\D/g, '');
}
});

I got this solution from here: http://stackoverflow.com/questions/995183/how-to-allow-only-numeric-0-9-in-html-inputbox-using-jquery

This is the php function which involved me changing the textarea callback:
function b4b_textarea_callback($args){
$options = get_option('b4b_theme_display_options');
if($args[0]=="number_of_posts"){
$html = '<input type="number"';
$html .= ' pattern="\d*"';
} else {
$html = '<input type="text"';
}
$html .= ' id="' . $args[0] . '" name="b4b_theme_display_options[' . $args[0] . ']" value="' . $options[$args[0]] . '" />';

echo $html;
}

I got help to find this solution from here: http://stackoverflow.com/questions/8808590/html5-number-input-type-that-takes-only-integers
Rather than replacing anything besides numbers with letters right away this allows for the letters to be entered and doesn't allow them to be saved.  I've decided to use the php solution instead of the jQuery one because letters can still be saved if the user clicks the save button right away.

Lastly this is the php code I made for querying the amount of posts:
<?php
$options = get_option( 'b4b_theme_display_options' );
$number_of_posts = $options['number_of_posts'];

if($number_of_posts != ''){
$args = 'posts_per_page=' . $number_of_posts;
query_posts($args);
}
?>


Next is the enabling sharing in posts option.  Planning this more in detail, this option will have a sharing button for Facebook, Twitter, Email and Google Plus.  These developer pages will help me create the code I need for the share buttons:

As for the email share button, that's something I want to try writing from scratch as a learning experience.  As of now I have a headache so I'm leaving this option for tomorrow.

Friday, July 26, 2013

Yet another day on the options panel - day 8

I'm jumping right into the last tutorial today: http://wp.tutsplus.com/tutorials/the-complete-guide-to-the-wordpress-settings-api-part-8-validation-sanitisation-and-input-ii/

First, the author goes to add a checkbox field into the example section he created yesterday.  I've already created my own checkbox callback but the author goes more into detail explaining it.  Here is my code:
function b4b_checkbox_callback($args){
$options = get_option('b4b_theme_display_options');
$html = '<input type="checkbox" id="' . $args[0] . '" name="b4b_theme_display_options[' . $args[0] . ']" value="1" ' . checked(1, $options[$args[0]], false) . '/>';
$html .= '<label for="' . $args[0] . '"> ' . $args[1] . '</label>';

echo $html;
}

This makes use of the checked func: http://codex.wordpress.org/Function_Reference/checked
To use this I would simply use an if loop to check if the saved options value is 1 or not.

Then the author goes through the callback for a radio button.  It's pretty much the same as a checkbox as it uses the checked function but the $checked parameter increments for each radio button in the set.  Again, to use the label to check the radio button just set the label's "for" attribute equal to the radio button's ID.

Lastly the author shows how to make the callback for the select control, which I've already done again.   Here's the code I've used for it:
function b4b_select_callback($args){
$options = get_option('b4b_theme_display_options');
$html = '<select id="' . $args[Count($args)-2] . '" name="b4b_theme_display_options[' . $args[Count($args)-2] . ']">';
foreach($args as $arg){
if ($args[Count($args)-1] != $arg && $args[Count($args)-2] != $arg){
$html .= '<option value="' . $arg . '"' . selected($options[$args[Count($args)-2]], $arg, false) . '>' . $arg . '</option>';
}
}
$html .= '</select>';
$html .= '<label for="' . $args[Count($args)-2] . '">' . $args[Count($args)-1] . '</label>';

echo $html;
}

This makes use of the selected func: http://codex.wordpress.org/Function_Reference/selected

After reading skimming through some of the tutorials again and browsing through the codex this is what my final header looks like: http://pastebin.com/SRdwSmhe

Now that the header is done I'm going to put a bit of planning for the other options down:
  • To display the favicon I'm just going to implement (to theme-options.php) the display favicon code from this author's tutorial: http://wp.tutsplus.com/tutorials/creative-coding/integrating-the-wp-media-uploader-into-your-theme-with-jquery/?search_index=2
  • To control the number of posts on the home page I first need to edit the validation callback so it will only accept numbers.  Then before the loop (in index.php) I'd want to use query_posts(http://codex.wordpress.org/Function_Reference/query_posts) in combination with retrieving the option (sanitized).  It's important to keep in mind that this option is useless since there are already options for this in Settings->Reading.
  • Code for the enable sharing posts and author bio options will go in the page.php between the get_template_part func and code for the comment loop.
  • The enable social icons (in the footer) option will go in the footer.php and be an if loop to decide whether it will display or not.
  • Text in footer controls the text in the footer that is shown at the very bottom and centered in a very light blue.
  • Facebook & Twitter url inputs first need to be changed so only a valid url can be saved.  Then it will be made (in footer.php) so that if they are blank their button won't appear. 
Okay so here's the favicon options code:
function b4b_add_favicon(){
$b4b_options = get_option('b4b_theme_display_options');
$b4b_favicon = $b4b_options['favicon_image'];
?>
<link rel="icon" type="image/png" href="<?php echo esc_url($b4b_favicon); ?>">
<?php
}
add_action('wp_head', 'b4b_add_favicon');

That's it for today.  More will come tomorrow.

Thursday, July 25, 2013

Today's wp work - day 7

Before I implement any more options in the theme I'm going back to the settings api tutorials and finishing summarizing them.

In the sixth tutorial, http://wp.tutsplus.com/tutorials/the-complete-guide-to-the-wordpress-settings-api-part-6-menu-pages/, the author is teaching how to introduce a top-level menu, add two submenus that will link to different tabs.   This will be making use of the add_menu_page and add_submenu_page functions I explained in better detail here: http://persteezy.blogspot.com/2013/07/options-panel-day-5-wordpress-menu-types.html

Now this goal is all fine and dandy but I couldn't get the tabs from the 5th tutorial (http://wp.tutsplus.com/tutorials/the-complete-guide-to-the-wordpress-settings-api-part-5-tabbed-navigation-for-your-settings-page/) to work and since this tutorial builds upon that working I can only summarize what he's saying now.  The 5th tutorial not only didn't work for me but it didn't work for another person as well.

Simply reading through the tut now, the author used add_theme_page and add_menu_page in a function that's hooked to the admin_menu hook.  Then a submenu (goes under top-level) item for one of the tabs is added using the add_submenu_page leaving you with two submenu items.  Two?  Yes, that's because the add_menu_page also leaves the user with a submenu page with the same name and callback function.  After this, a third submenu page is added for the second option.

Author then adds a tab parameter (default value of null) to the *_theme_display func grabs the value of tab and assigns it to a var, creates an if loop that checks what the var equals and reassigns the var depending on what it equals.  Then to utilize this change the author changes the callback of the submenu to something like this:
create_function( null, 'sandbox_theme_display( "social_options" );' ) 
create_function explained: http://php.net/manual/en/function.create-function.php

Now this would be great to implement if the tabs worked but they don't and I don't plan on looking for a solution until another time.  Honestly I think jQuery is probably the better solution here because (A) I'm not very good with ajax and (B) it cuts back on load time majorly.  Now I'm onto tut #7: http://wp.tutsplus.com/tutorials/the-complete-guide-to-the-wordpress-settings-api-part-7-validation-sanitisation-and-input-i/

Validation - the process by which data entered into the options page by the user is examined and it is determined whether it's acceptable to save.

Sanitization - the process by which data coming out of the database is assured to be clean and properly formatted for rendering.

So validation should be done before data gets written to the db and sanitization should be done between loading the data from the db and displaying it in the browser.  The author then goes to add a new input_examples function, create a submenu for it, and add it to the tabs like the other functions.  He then adds an input field to the tab that will be used to test validation.

The third parameter for the register_setting function is what gets used for the validation function callback.  The function should accept the $input parameter which will obviously hold the data to be validated.  This function will normally follow these three steps:
  • Create an array for storing validated options
  • Validate the options
  • Return the created array
In the author's validation function he does this then uses a foreach to loop through the inputs.  If the loop is not null (isset: http://php.net/manual/en/function.isset.php) then the author makes use of two php functions to validate the input and add it too $ouput at the same time:
Not sure why the user doesn't try making use of the esc_html and esc_url wp functions but I guess I'll just have to continue reading and find out.  Here's the validation function in my code:
function b4b_theme_display_options_validation($input){
$output = array();
foreach($input as $key => $value){
if(isset($input[$key])){
$output[$key] = strip_tags(stripslashes($input[$key]));
}
}
return apply_filters('b4b_theme_display_options_validation', $output, $input);
}
apply_filters(http://codex.wordpress.org/Function_Reference/apply_filters) is used because it is just known as a best practice (idk).

The author then uses sanitize_text_field(http://codex.wordpress.org/Function_Reference/sanitize_text_field) for echoing the options.

This concludes the tutorial and my wp work for today.  The author included me with one link that I'm now using as a reference: http://codex.wordpress.org/Data_Validation
One more tut in the series to go and I plan on finishing it tomorrow.

Wednesday, July 24, 2013

Unfocused.

Honestly these I've been having a very bad motivational issue with doing anything computer programming related and it's starting to piss me off.  I once used to love programming for the fun of it and now I'm only worried about one thing and that's money.  I've applied to countless jobs (near and far) but absolutely no one wanted to hire me because I have absolutely no work experience in retail or computer hardware, I'd only be working for a short amount of time (because I'm off to college soon), and there's no open web developer positions that will hire someone with just a high school education and not even a portfolio website.

I find myself constantly looking (and wasting my time) to make "easy money" online rather than to focus on improving my programming skill and building a much stronger portfolio.  For example, just the other day I bought a shit ebook on HF that's supposed to teach me how to get free one month xbox live codes and spent hours trying to make it work and plotting ways I can change the method to make it work.  The method will never work and was just a waste of a $25 Amazon GC.

From this point on (like with MapleStory), I've decided that I'm done with forums.  Yes, that means I'm officially off WJ, HF, TBN, & HC until I improve my skill to the point where I can create amazing things and make money doing something I love.  I've been told this before by my lawyer and he said:
Don't focus on making money at such a young age (I was 17 at the time).  Just focus on improving and getting better at your talent and the money will come.
When I first heard this it went in one ear and out the other because I was so convinced that making money at that age was the most important thing I could possibly too because I wanted to be able to get whatever I wanted without struggle.  Now, I'm realizing how true this statement is.  If I continue trying to make money in semi-illegitimate ways and not utilizing my talent I won't turn into anything but a fraudster and a criminal.  I need to focus on building my skills and create my own path to the riches in a completely legal way.

That's all I have for today.  Sorry for posting all this bullshit and none of the usual coding stuff but this was just another thought I needed to get straight.  However I did implement the header options into the b4b theme through the header.php file by inserting the following:
<?php $display_options = get_option( 'b4b_theme_display_options' ); ?>
<div class="site-branding">
<?php if ($display_options['header_type'] == 'image'){ ?>
<img src="<?php echo $display_options['header_image']; ?>" alt="logo" />
<?php } elseif($display_options['header_type'] == 'text' && $display_options['header_title'] == '' && $display_options['header_slogan'] == '') { ?>
<h1 class="site-title"><a href="<?php echo esc_url( home_url( '/' ) ); ?>" title="<?php echo esc_attr( get_bloginfo( 'name', 'display' ) ); ?>" rel="home"><?php bloginfo( 'name' ); ?></a></h1>
<h2 class="site-description"><?php bloginfo( 'description' ); ?></h2>
<?php } elseif($display_options['header_type'] == 'text' && $display_options['header_title'] != '' && $display_options['header_slogan'] != '') { ?>
<h1 class="site-title"><a href="<?php echo esc_url( home_url( '/' ) ); ?>" title="<?php echo esc_attr( $display_options['header_title'] ); ?>" rel="home"><?php echo esc_attr( $display_options['header_title'] ); ?></a></h1>
<h2 class="site-description"><?php echo esc_attr( $display_options['header_slogan'] ); ?></h2>
<?php } ?>

</div>

Going to bed now. There'll probably be more activity on here from now on.

Monday, July 22, 2013

Back from vacation! - my options panel

Sorry I forgot to tell you guys that I was going on vacation for a bit.  I didn't have a reliable internet connection where I was so I couldn't make any posts.  Anyways I pretty much finished the basic aesthetics and options for the options panel in the new theme I'm making.


Here's the files used for this and their source code:

I'm aware that I can just combine the two js files but I'm keeping them separate to stay a little more organized (I'll put them together and compress it when I finalize everything).  I'm sure some things can be coded better but I'm moving on to the rest of the theme now and will come back for improvements after everything is done.  That's all for today, pce!

Thursday, July 11, 2013

Back from college - wp options panel day 6

I had college orientation and a bunch of other stuff to take care of which is why I was gone for so long.  I my free time though I have been designing a new WordPress theme called Boundaries for Breaking.  So far I've only designed it in Photoshop and it looks pretty good.  When I code it it'll be named b4b and I need to re-size it because the design is a bit small.  Since I haven't been learning about the settings api like I should have I'm going back to learning about it for most of today.

Before I even get started with taking notes, I had to fix my localhost (wampserver) first.  What was wrong with it?  This was the error:

I fixed it by following the advice from the first responders on these two threads:

Okay back to note taking...  So in this tutorial http://wp.tutsplus.com/tutorials/the-complete-guide-to-the-wordpress-settings-api-part-4-on-theme-options/ the author goes over categorizing all the fields in each section to a single option.  Once you define multiple option sections and display them using settings_fields(), do_settings_sections() and submit_button() wrapped in a form only the newest defined option will actually save.

Now for part 5, http://wp.tutsplus.com/tutorials/the-complete-guide-to-the-wordpress-settings-api-part-5-tabbed-navigation-for-your-settings-page/, he says you can keep these option groups and still save with using tabs instead of new pages.  I only got to the very beginning of this tutorial before I ran into troubles and couldn't get anything working.  The non-working code is here: http://pastebin.com/xVmuKjcc

I'm back to this code now though cause it is still working: http://pastebin.com/3HLKhuQG

I'm going to read through part 5 again and try to add tabs to my code even with only one set of options.  Didn't add tabs still yet but added the image uploader by following and making modifications/additions to the code from these two tutorials:

Here's the code at the end of today: http://pastebin.com/c9U3gD0Z
Here's the additional js file: http://pastebin.com/ErZy47vc

Pce niggs.

Friday, July 5, 2013

Options panel day 5 - wordpress menu types

On part 3 of the settings api tutorials and this part goes over menu types (not the settings api but very closely related).

Top-level menus: are the menus in the left column that hold sub-menu pages.  You use the add_menu_page function to add your own: http://codex.wordpress.org/Function_Reference/add_menu_page
add_menu_page(Page Title, Menu Title, Capability, Menu Slug, Callback, Icon URL, Position);
  • Page Title - Title displayed in the browser window tab.
  • Menu Title - Title displayed in the menu.  Keep it short so it doesn't wrap and look stupid.
  • Capability - String value that specifies which users can access the menu.  Roles: http://codex.wordpress.org/Function_Reference/add_menu_page
  • Menu Slug - identifier for the menu page.  Is a hook that submenu pages use to register themselves.
  • Callback - function that defines content for the page.  This can be html or refer to and external file.
  • Icon URL - path of the icon that gets displayed next to menu title.  (optional)
  • Position - place in the menu where the page gets placed.  It gets placed at the bottom by default but custom positioning allows you to put it above or below and existing item.
Use this function in a custom function you create that is hooked to the admin_menu.  A lot of people think that the position argument is a bad practice cause it changes the traditional wordpress experience and the position can be overwritten if defined somewhere else.

Submenus: pretty much the same as a menu except they belong to top-level menus (they always have a parent).  add_submenu_page is the function that is used for submenus: http://codex.wordpress.org/Function_Reference/add_submenu_page
add_submenu_page(Parent Slug, Page Title, Menu Title, Capability, Menu Slug, Callback);
  • Parent Slug - ID of the menu item it will belong to.
  • Page Title - same as top-level.
  • Menu Title - same as top-level.
  • Capability - refers to what types of users can access the specific submenu page
  • Menu Slug - ID for this specific item.
  • Callback - same as top-level.
Plugin Pages: the add_plugins_page function was made to make it easier for plugin developers: http://codex.wordpress.org/Function_Reference/add_plugins_page
add_plugins_page(Page Title, Menu Title, Capability, Menu Slug, Callback);
All of its parameters work the same as add_menu_page.  This should be called from within your plugin's php file and not your functions.php.

Theme Pages: uses add_theme_page to add a submenu to the appearance menu: http://codex.wordpress.org/Function_Reference/add_theme_page
add_theme_page(Page Title, Menu Title, Capability, Menu Slug, Callback);
All of its parameters work the same as add_submenu_page.

Now what is each menu type good for exactly?:
  • Top-Level Menus - for when you have a group of important settings that don't fit in other existing menus.
  • Submenus - either custom or already existing, should be put under a parent menu that works.
  • Plugin Menus - used for plugins and should used tabbed navigation if there's multiple option pages.
  • Theme Menus - used for theme options and follows the same deal with tabbed menus as plugin menus.  However, top-level menus are sometimes used for theme options instead.
So that's everything I took down for part 3.  Here's the code I'm left with at the end of that: http://pastebin.com/aYk6kjzX

Part 4 is supposed to go more into detail about theme options so I'm starting that now but that's all for this post.

Tuesday, July 2, 2013

Options panel struggles continue - day 4

Things aren't going so well creating an options panel.  Today I learned that the method I've been using to create an options panel is outdated and that there's a settings api that I could be using instead: http://codex.wordpress.org/Settings_API

When going through the tutorial (in my last post) I started picking up on this bit by bit.  So for the rest of this post I'm taking down some notes on this settings api as I work my way through this tutorial series: http://wp.tutsplus.com/series/the-complete-guide-to-the-wordpress-settings-api/
btw I'm starting the options panel from scratch now (but keeping theme-options.php) in a new file (better-options.php).

So yea, this api is supposed to facilitate the processes of:

  • introducing menus
  • option pages
  • saving (I'm looking forward to this lol)
  • validating
  • retrieving user input
You should use the api because it's secure and properly manages (my mistake).

There are three main components of the api:
  1. Fields - single inputs (options) that you'll see on menu pages like textboxes, radio buttons, selects, etc.  They hold the value that gets put in the db.
  2. Sections - are used for grouping (usually related) fields.  Normally used so each section is its own menu page.
  3. Settings get registered after you've defined your fields and sections.
Creating a section uses the add_settings_section function I learned about before: http://codex.wordpress.org/Function_Reference/add_settings_section
add_settings_section(ID, Title, Callback, Page);
  • ID - identifier for the section.  The value is used in registering the field within each section and can be named anything (keep it meaningful).
  • Title - a value displayed at the top of the page as an (h1 or h3 or something).
  • Callback - the name of the function where the code for displaying certain elements for the section will go.
  • Page - this value tellswp which page your options are displayed on.
This is a reference for some page keys:
  • General, “general”
  • Writing, “writing”
  • Reading, “reading”
  • Discussion, “discussion”
  • Media, “media”
  • Privacy, “privacy”
  • Permalinks, “permalink”
The add_settings_field function gets used to ad fields: http://codex.wordpress.org/Function_Reference/add_settings_field
add_settings_field(ID, Title, Callback, Page, Section, Arguments);
  • ID - ID of the field and used in saving and retrieving the value (keep it meaningful).
  • Title - value that turns into the title of the field option on the page.
  • Callback - Same as in section.
  • Page - identifies which page the option should be on and can be added to an existing page rather than a section that's already been defined.
  • Section - the ID of the section you created earlier when registering sections.  (optional param)
  • Arguments - array of arguments that get brought to the callback func.  (optional param)
Now after you add some sections and fields they still will not save.  Why?  Because they weren't registered with the register_setting function yet: http://codex.wordpress.org/Function_Reference/register_setting
register_setting(Option Group, Option Name, Callback);
  • Option Group - Name of the group of options.  This will be and existing group of options in wp or an ID that we made when we created our section.  (required)
  • Option Name - The ID of the field we're registering.  If registering multiple fields, you'd have to call this function multiple times.  (required)
  • Callback - Same as section and field.  (optional)
Now to use these options you created, the get_option function comes into play: http://codex.wordpress.org/Function_Reference/get_option
get_option(Option ID, Default Option);
  • Option ID - the ID of the field that you want the value of. (required)
  • Default Option - the value if the option returns nothing (like if it didn't exist in the db).  (optional)
Well that's all I'm going through for today.  By applying all this knowledge (and the little programming skill I have), I've come up with this as my functions file: http://pastebin.com/ZkGkiMVP

I've also applied these options to my themes header file: http://pastebin.com/FzBUbxF9

So this is what this code looks like:

At the end of the day, I'm happy to finally be getting somewhere with the options panel without having to copy and paste massive amounts of code.  With this settings api, I actually understand what's going on now so tonight I can go to sleep a little less pissed off than usual ;)

Sunday, June 30, 2013

Creating an options panel - day 3

Still no responses on the other thread so I'm creating a new one: http://wordpress.stackexchange.com/questions/104632/options-php-loop-wont-show

Already got some help and are narrowing everything down.  Well I feel very stupid.  I forgot to actually  call the them_options function forth.  To do so, all I had to do was add_action('init', 'theme_options'); which I knew already, I just kept missing it.

Another problem occurred with the save button not working so I've posted a new question on it here: http://wordpress.stackexchange.com/questions/104734/theme-options-save-button-is-not-working

I don't mean to rely on them for help but I've been struggling with it for a few hours now and are stuck.

In the meantime, I'm taking written notes on the source code from this tutorial: http://wp.tutsplus.com/tutorials/creative-coding/how-to-integrate-the-wordpress-media-uploader-in-theme-and-plugin-options/

These are some of the functions I've learned about:

That's it for today.

Thursday, June 27, 2013

Working with the options panel - day 2

/vent

Today I'm just fucking stressed and annoyed.  I can't even get the damn reset/save buttons to work fucking properly.  Here's the current options.php: http://pastebin.com/2P31BgcW

Every time I hit the reset or save button I get "You do not have sufficient permissions to access this page".  Now why wouldn't I?  I'm the admin of the blog but I don't have permissions to save/reset the options apparently.  This means something is up with my fuckinround_add_admin function.

The thing in this function that I think is causing the error should be this guy: http://codex.wordpress.org/Function_Reference/check_admin_referer

But why?  I can't find anything wrong with that.. So I'm going to continue looking aaaaaannnnnndddddd found it!  It's the fucking header method causing the problem.  I can't do options/options.php most likely because I can't view directories like that.  If I just change it too options.php it appears to work fine.

Although it appears to be working, it might not work at all when I actually write the loops and try to save the properties.  So now I'm onto writing them...

Well I've tried writing loop 1: http://pastebin.com/cK7APede
But nothing wants to show up on the page.  Why?  idk yet.  If I do echo <h1>test</h1>; just outside of the foreach loop it works perfectly.  However when I put this inside of the foreach loop it's a nogo. This means that (a) The options aren't declared properly (b) The options aren't declared before they are used (c) Something completely different than what I'm thinking is going wrong.

Asked a question here regarding it: http://thematictheme.com/forums/topic/options-panel-loop-isnt-showing/
Now I'm just awaiting a reply...

Well, it's 12:20AM and there's still no replies and I'm tired as fuck so I guess this is where I end today.

Tuesday, June 25, 2013

Creating an advanced options panel - day 1

I just graduated recently and I've been too busy spending time with the fam and homies to actually post anything here.  What I have done over this time was almost completely dissemble (till I took the motherboard out), get the dust out of, and assemble my Acer Aspire One 532h-2588.  I used this guide to do so: http://erkinson.altervista.org/acer-aspire-one-532h-aggiornare-ramhdwifi-smontare-lcd/
And no, I don't speak Italian, I translated the article (obviously).  Everything was very easy to put back together except for the damn keyboard.  The main reason was that the ribbon cable used to connect it was very folded and almost impossible to secure (but I got it).

Today I've started creating an advanced options panel today.  These are some of the guides I'm using so far:

My idea is to have too loops in the creation of the panel.  The first will be used to create a side navigation that is used for navigating through each container that has options in it (so it will only use the items in the array with the sidebar type.  The second loop will be used to create the needed containers to go along with the side menu and fill them with options.

Once this is done, I'll need to write some simple js to fade in and out of containers depending on the one clicked in the side menu.  As for the save changes input functions, I think I can just copy/paste it from either the first article above or just rewrite it from one of the books I own.  This is all I'm posting about now but I'm going to continue working throughout tonight.

My goal is to make it look almost exactly like this:

Wednesday, June 19, 2013

Integrating WP Plugins/Widgets into your theme

Tonight I'm trying to figure out how to integrate widgets I write into my theme.  This way, when the user install the theme, the widgets will be there for them to use.

To do so you just need to:

  • import all the widget files into your theme directory
  • Make sure any hardcoded paths or plugin_urls are changed to get_template_directory_uri() and the correct path.
  • Add a require_once to your functions.php with the path of your widget's php file inside.
Notes:
  • When integrating make sure to delete it from the plugins directory or else you'll get an error that says you can't redefine that class.
Now that I have shortcodes and integrating plugins/widgets into the theme I can now start working on making an advanced admin panel.  This admin panel would include the following options:
  • Change logo/if you want a logo at all.
  • Change background image/color.
  • Change link color.
  • Change header text color.
  • Custom css.
  • Insert google analytic code.
  • Enable/disable image slider.
  • Enable/disable jQuery.
All of these need to be placed in a tab for their category of option in the options panel too.  That's all for tomorrow night though cause tonight's energy drink is wearing off already.

Monday, June 17, 2013

Conversion

It's been a while since I posted because of four reasons:
  • laziness
  • social life
  • new conversion
  • finals :(
Anyways, I did a new psd to html conversion called **** Host.  It's a three page web hosting layout that I used as much css3 as possible on:

EDIT: The design I coded was apparently ripped from another designer.  I feel bad about doing this so I've removed all the pictures of the coded design etc.  It's amazing how many fag rippers are on the internet these days.

Tuesday, June 11, 2013

vbulletin skins?

I spent majority of my time on the computer today derping around.  Other than that I decided to take a break from wp and check out how vbulletin skins work.  These two sites help with understanding how  a skin works:
I can only read and not actually try this stuff out today because I don't have a nulled vbulletin to run on my localhost and TPB is down for whatever reason.  I don't trust the torrents from other sites either like torrentz.eu and kickass torrents.  The thing that makes me nervous about downloading so many things is opening a virus and having all my account data stolen.  Sometimes when I'm really paranoid, I convince myself that I already have a virus and go crazy with scans/checking folders/processes where it could possibly be.  It'd probably be a good idea to ask the experienced members on HF if my comp is infected because I feel my paranoia coming in again. 

Monday, June 10, 2013

My progress with shortcodes

Tonight I messed around with shortcodes more so they look like this:


Some things I should probably do is make it so when the inline toggles are next to each other, the ones on the end will get the .last class and float:left;clear:right;.  I want the same to happen for the alerts.  I should also make it so when the width is fixed that they should clear:both;.  A style attribute for all the elements wouldn't hurt either.  When all this is complete it'd be a good idea to look into packaging this. Nothing else happened today besides a shit ton of calculus so pce.

Sunday, June 9, 2013

Fucked myself over

I was on a nice little vacation after prom and I've come home to the realization of how badly I fucked myself over.  Because my dumb ass accidentally (I'm not explaining any further) got involved in some type of fraudulent activity involving PayPal, I've found myself banned from using the processor FOR LIFE.  Now, lifetime bans aren't fun if you get them for any site, but one from PP tends to sting a bit more than usual.  Why?

  • PP is the #1 most used payment processor in the world and most accepted by online businesses/potential customers for my web designing services.
  • I can never sell things on ebay with my own account.
  • I can't pay for things that only accept PP (which are a lot).
Now what about using Payza instead?  They won't allow new accounts to be created in the US currently.  Which means the only payment methods I can accept are:
The first option is always a backup and Western Union seems like the way to go now.  I've used moneybookers before and I just don't know them well enough to trust them with my bank info/money.

What should you deduct from reading this?
  • Always write passwords/security answers down.
  • Never do fraudulent activity with any payment processor as a kid because it can fuck you over when you're an adult.
  • Even if you're banned from someplace there are still plenty of other options (that probably aren't as good) out there.

Wednesday, June 5, 2013

Revisiting the Wordpress Shortcode API

I'm creating a new wordpress in my localhost just for practice.  Just for remembering purposes, the url is localhost/fucking round.  I know, it's very mature of me to use a curse word in the directory name.

With everything set up I'm choosing to practice making shortcodes because I'm not familiar with them at all.  First though, I'm going to take some notes on this: http://codex.wordpress.org/Shortcode_API

Basically a shortcode is a placeholder that you put in posts that gets replaced with the code when displayed.  It's kinda like when you use :ninja: in the chatbox at wj to get a ninja smiley.  Shortcodes can also have attributes (color, size, id, etc.).

Then to write a shortcode, in your functions.php, you just have to write a function that returns the html/text you need and use add_shortcode() for that function: http://codex.wordpress.org/Function_Reference/add_shortcode

There are three parameters included in the shortcode callback:
  • $atts, is an optional array of attributes.
  • $content, is the content of the shortcode (obviously)
  • $tag, is a tag for the shortcode, used for shared callback functions.
The shortcode api will replace any shortcodes [thatlooklikethis] and parse all the attributes and content.  Content will only be placed in the post body if it's returned and not echoed.  A shortcode handler would get put into the body instead of the shortcode already programmed.

So say you have something like: [scode dont="touch" me="there"]

The $atts would be: array( 'dont' => 'touch', 'me' => 'there' )
$atts[0] holds a string that was used to match the shortcode regex if (and only if) it's different from the callback name.

shortcode_atts (resembles wp_parse_args) is used to set a default for missing values and get rid of any attributes that the shortcode doesn't understand: http://codex.wordpress.org/Function_Reference/shortcode_atts
This would get placed inside of an add_shortcode handler function like this:
function my_shortcode_handler( $atts, $content = null ) {
   extract( shortcode_atts( array(
      'attr_1' => 'attribute 1 default',
      'attr_2' => 'attribute 2 default',
      // ...etc
      ), $atts ) );
}

Here, extract (http://www.php.net/extract) pulls the needed values from the array and will handle any collisions after shortcode_atts() strips out all the non-included keys.

This tip is important regarding naming attributes:
$atts values are lower-cased during shortcode_atts( array( 'attr_1' => 'attr_1 default', // ...etc ), $atts ) processing, so you might want to just use lower-case.
 Shortcodes get parsed after wpautop and wptexturize formatting is applied, meaning it won't have the proper html (p and br) tags added or curly quotes applied.  To format the shortcode, just call wpautop() and wptexturize when you return the output from your handler.  If there's a lot of html in the shortcode you can use ob_start() to capture the output and convert it to a string:
ob_start();
?> <HTML> <here> ... <?PHP
$output_string = ob_get_contents();
ob_end_clean();

Besides using self-closing shortcode, you can enclose shortcodes by using this format in posts: [shortcode]content[shortcode].  Doing so will not send the second (content) parameter to the handler so you'd have to set the handler's default value:
function my_shortcode_handler( $atts, $content = null )

Don't know what kind of closing a shortcode has?  You can use is_null($content) to figure that out.  Other html can be embed in $content since it's not encoded or escaped but you can add another shortcode unless you output it using do_shortcode(): http://codex.wordpress.org/Function_Reference/do_shortcode

You can mix forms of enclosing or non-enclosing shortcodes:
[sc title="steez" /] this aint [sc] working [/sc]
This would output: this aint [sc] working

Enclosing shortcodes work the same way as self-enclosing.  An example:
function caption_shortcode( $atts, $content = null ) {
   extract( shortcode_atts( array(
      'class' => 'caption',
      ), $atts ) );

   return '<span class="' . esc_attr($class) . '">' . $content . '</span>';
}


Input: [caption class="headline"]My Caption[/caption]
Output: <span class="headline">My Caption</span>

You cannot use square brackets in attributes.  So [sc attribute="[this will not work]"].

There's a few other things to note about shortcodes but I think I've summarized the important stuff.