I have a templating engine in PHP wich allows you to set style attributes to objects prior to rendering.
During development time, I want these attributes to be inline so I can find them and change them easily. However, for production, I want to extract them and cache them in a css file. I also want to extract inline styles from any html element in the template.
The extracting, as well as ordering in arrays part is done. So I have a bunch or arrays that are structured as follow
array(
'tag' =>'div',
'id' =>'myDiv',
'class'=>array('container','wrapper'),
'style'=>array('background'=>'#CCCCCC',/*rules...*/)
);
Note that 'id' and 'class' keys are not necessarily set on all elements, but at least one of both is always set.
The part that renders this array as a css file is also done.
What I need to do is re-shuffle around the 'style' part of the array so common elements are grouped together. Optimization is not an issue since this process will be called only once then cached.
But I tried to design some pseudo-code and I'm just stuck. I am guessing that some part of the process at least will have to make "as-smart-as-possible guesses", but even that I don't see clearly.
Last recourse would be to just create the full string, then run the string itself through a css-minifier, but as far as what I could read, none does this "reducing to the lowest common denominator" thing.
Any suggestion?
[edit]
In answer to comments, here is more clarification:
if my array is presented like so:
array(
array(
'tag' =>'div',
'id' =>'myDiv',
'style'=>array('background'=>'#CCCCCC','font-size'=>'24px','color'=>'#FF0000')
),
array(
'tag' =>'div',
'class'=>array('container','hasBorder'),
'style'=>array('background'=>'#CCCCCC','border'=>'1px solid black')
),
array(
'tag' =>'div',
'class'=>array('wrapper','hasBorder'),
'style'=>array('color'=>'#FF0000','border'=>'1px solid black')
)
);
My CSS should be rendered as such:
#myDiv{font-size:24px;}
#myDiv, .container{background:#CCCCCC;}
#myDiv, .wrapper{color:#FF0000;}
.hasBorder{border:1px solid black}
The output could be different; I don't care what the exact logic for defining how rules are set is; But what I want to avoid is what I currently have:
#myDiv{background:#CCCCCC;font-size:24px;color:#FF0000;}
.container{background:#CCCCCC;border:1px solid black;}
.wrapper{color:#FF0000';border:1px solid black;}
This is a simple example, but I have lots of repeated rules all over that make no sense; the generated CSS is not only bloated, it is not humanely maintainable. What I want is to generate a base CSS that designers can use to work with.
css lint http://csslint.net/
watch out, she'll hurt your feelings
Related
Although this question relates to a particular Wordpress plugin called the All in One Event Calender by Time.ly it can also be a general PHP related question.
I am trying to modify a theme to use event colours selected in the ai1ec back end and would like to produce a simple HTML colour code - ie "#f2f2f2"
The plugin itself has loads of functions and php shortcodes to pull a wealth of information off each event such as the one listed below.
<?php echo $event->get_category_text_color(); ?> which will print style="color: #f2a011;"
Can also change to print style="background-color: #f2a011;" with the use of $event->get_category_bg_color();
Now the real meat of the question
All I want to do is get that HTML colour so I can also code it into buttons and other visual elements. I have scoured through blogs and code to try and find something that does it to no avail.
What I was wondering is if you could write a filter of some sort to just take the information within the "#f2f2f2" quotation marks. I know it's not called a filter as searches for php filter return information about something completely different - I'm a self taught PHP programmer and so searching for a lot of terms I don't know can be pretty tough!
As pointed above, substr would be a great solution but it wouldn't solve the case where the color code is expressed in this format:
#FFF;
instead of:
#FFFFFF;
Therefore, this regex should do the job quite well:
'/?=#(.*(?=;)))/'
Example:
$matches = array();
preg_match('/?=#(.*(?=;)))/', $event->get_category_text_color(), $matches);
$colorCode = "#{$matches[0]};";
You could use the substr() function like so:
echo substr($event->get_category_text_color(),14,-2);
Which in the example, would return #f2f2f2.
I’m writing a custom parser/data extractor for some pretty shitty HTML.
Changing the HTML is out of the question.
I will spare you the details of the hoops I’ve had to jump through but I’ve now come pretty close to my original goal. I’m using a combination of DOMDocument getElementByName, regular expression replace (I know, I know...), and XPath queries.
I need to get all the text out of the body of the document. I would like for the navigation to remain a separate entity, at least in the abstract. Here’s what I’m doing now:
$contentnodes = $xpath->query("//body//*[not(self::a)]/text()|//body//ul/li/a");
foreach ($contentnodes as $contentnode) {
$type = $contentnode->nodeName;
$content = $contentnode->nodeValue;
$output[] = array( $type, $content);
}
This works, except that of course it treats all of the links on the page differently, and I only want it to do that to the navigation.
What XPath syntax can I use so that, in the first part of that query, before the |, I tell it to get all the text nodes of body’s children except ul > li > a.
Please note that I cannot rely on the presence of p tags or h1 tags or anything sensible like that to make educated guesses about content.
Thanks
Update: #hr_117’s answer below works. I’ve also found that you can use multiple not statements like so:
//body//text()[not(parent::a/parent::li/parent::ul)][not(parent::h1)]
You may try something like this:
//body//text()[not(parent::a/parent::li/parent::ul)]|//body//ul/li/a
//body//*[not(self::a/parent::li/parent::ul)]/text()[normalize-space()]|//body//ul/li/a
(test)
Some clarification:
I want to have 6 placeholder divs for strikes, so to speak, in a game.
So like [ ] [ ] [ ] [ ] [ ] [ ].
Which will be white squares with a black border.
After they make a bad guess, I want the first div to be overwritten with a red box holding the guess. Basically the above, but fully red and a number in the middle. ex: [9]
How would I go about doing this with PHP/CSS/HTML? I'm totally used to echo statements, so I was thinking about echoing each one out. But if I had divs there to begin with, it would just go after them, not overwrite.
I was thinking something along the lines of background images, at least in concept (not actual images) where the new guesses just go overtop the old ones. Would that be the best way?
PHP completes all data at DOM complete. To update the DOM in real time, you can either use Ajax or your own JS block, node.js, etc.
While you have tagged for CSS and PHP, you would be better off using jQuery.
CSS stacks would simply get confusing and messy fast, and PHP renders on load, unless you use AJAX so again can get messy fast.
For the example of above you could use:
function badguess() {
$('#box2').css("color","red");
}
If you wanted to add text to the box you could also use:
function badguess(){
$('#box2').css("color","red");
$('#box2').append('<p>WRONG</p>');
}
Links:
.Append() - http://api.jquery.com/append/
.CSS() - http://api.jquery.com/css/
This is the most optimal way of dealing with a multilingual website I can think of, right now (not sure) which doesn't involve gettext, zend_translate or any php plugin or framework.
I think its pretty straight forward: I have 3 languages and I write their "content" in different files (in form of arrays), and later, I call that content to my index.php like you can appreciate in the following picture:
alt text http://img31.imageshack.us/img31/1471/codew.png
I just started with php and I would like to know if I'm breaking php good practices, if the code is vulnerable to XSS attack or if I'm writing more code than necessary.
EDIT: I posted a picture so that you can see the files tree (I'm not being lazy)
EDIT2: I'm using Vim with the theme ir_black and NERDTree.
Looks all right to me, although I personally prefer creating and using a dictionary helper function:
<?php echo dictionary("showcase_li2"); ?>
that would enable you to easily switch methods later, and gives you generally more control over your dictionary. Also with an array, you will have the problem of scope - you will have to import it into every function using global $language; very annoying.
You will probably also reach the point when you have to insert values into an internationalized string:
You have %1 votes left in the next %2 hours.
Sie haben %1 stimmen übrig für die nächsten %2 stunden.
Sinulla on %1 ääntä jäljellä seuraavan %2 tunnin ajassa.
that is something a helper function can be very useful for:
<?php echo dictionary("xyz", $value1, $value2 ); ?>
$value1 and $value2 would be inserted into %1 and %2 in the dictionary string.
Such a helper function can easily be built with an unlimited number of parameters using func_get_args().
It's OK generally. For instance, punBB's localization works this way. It is very fast. Faster than calling a function or an object's method or property. But I see a problem with this approach, since it doesn't support language fallbacks easily. I mean, if you don't have a string for Chinese, let it be displayed in English.
This problem is topical when you upgrade your system and you don't have time to translate everything in every language.
I'd better use something like
lang.en.php
$langs['en'] = array(
...
);
lang.cn.php
$langs['cn'] = array(
...
);
[prepend].php (some common lib)
define('DEFAULT_LANG', 'en');
include_once('lang.' . DEFAULT_LANG '.php');
include_once('lang.' . $user->lang . '.php');
$lang = array_merge($langs[DEFAULT_LANG], $langs[$user->lang]);
Looks all right to me also, but:
Seems that you have localization for multiple modules/sites, so why not break it down to multidimensional array?
$localization = array(
'module' => (object)array(
'heading' => 'oh, no!',
'perex' => 'oh, yes!'
)
);
I personally like to creat stdClass out of arrays with
$localization = (object)$localization;
so you can use
$localization->module->heading;
:) my 2 cents
The only way that this could be xss is if you have register_globals=On and you don't set $lang['showcase_lil'] or other $lang's. But I don't think you have to worry about this. So I think your in the clear.
as an xss test:
http://127.0.0.1/whatever.php?lang[showcase_lil]=alert(/xss/)
Wouldn't it have been better to post code and briefly explain this issue to us?
Anyway, putting each language in its own file and loading it through some sort of language component seems okay. I'd prefer using some sort of gettext, but this is okay too, I guess.
You should make a function for calling the language keys rather than relying on an array, something like
<?php echo lang('yourKey'); ?>
One thing to watch for is interpolation; that's really the only place XSS could sneak in if your server settings are sensible. If you at any point need to do something along the lines of translating "$project->name has $project->member_count members", you'll have to make sure you escape all HTML that goes in there.
But other than that, you should be fine.
I am using wmd markdown editor on a project and had a question:
When I post the form containing the markdown text area, it (as expected) posts html to the server. However, say upon server-side validation something fails and I need to send the user back to edit their entry, is there anyway to refill the textarea with just the markdown and not the html? Since as I have it set up, the server only has access to the post data (which is in the form of html) so I can't seem to think of a way to do this. Any ideas? Preferably a non-javascript based solution.
Update: I found an html to markdown converter called markdownify. I guess this might be the best solution for displaying the markdown back to the user...any better alternatives are welcome!
Update 2: I found this post on SO and I guess there is an option to send the data to the server as markdown instead of html. Are there any downsides to simply storing the data as markdown in the database? What about displaying it back to the user (outside of an editor)? Maybe it would be best to post both versions (html AND markdown) to the server...
SOLVED: I can simply use php markdown to convert the markdown to html serverside.
I would suggest that you simply send and store the text as Markdown. This seems to be what you have settled on already. IMO, storing the text as Markdown will be better because you can safely strip all HTML tags out without worrying about loss of formatting - this makes your code safer, because it will be harder to use a XSS attack (although it may still be possible though - I am only saying that this part will be safer).
One thing to consider is that WMD appears to have certain different edge cases from certain server-side Markdown implementations. I've definitely seen some quirks in the previews here that have shown up differently after submission (I believe one such case was attempting to escape a backtick surrounded by backticks). By sending the converted preview over the wire, you can ensure that the preview is accurate.
I'm not saying that should make your decision, but it's something to consider.
Try out Pandoc. It's a little more comprehensive and reliable than Markdownify.
The HTML you are seeing is just a preview, so it's not a good idea to store that in the database as you will run into issues when you try to edit. It's also not a good idea to store both versions (markdown and HTML) as the HTML is just an interpretation and you will have the same problems of editing and keeping both versions in synch.
So the best idea is to store the markdown in the db and then convert it server side before displaying.
You can use PHP Markdown for this purpose. However this is not 100% perfect conversion of what you are seeing on the javascript side and may need some tweaking.
The version that the Stack Exchange network is using is a C# implementation and there should be a python implementation you downloaded with the version of wmd you have.
The one thing I tweaked was the way new lines were rendered so I changed this in markdown.php to convert some new lines into <br> starting from line 626 in the version I have:
var $span_gamut = array(
#
# These are all the transformations that occur *within* block-level
# tags like paragraphs, headers, and list items.
#
# Process character escapes, code spans, and inline HTML
# in one shot.
"parseSpan" => -30,
# Process anchor and image tags. Images must come first,
# because ![foo][f] looks like an anchor.
"doImages" => 10,
"doAnchors" => 20,
# Make links out of things like `<http://example.com/>`
# Must come after doAnchors, because you can use < and >
# delimiters in inline links like [this](<url>).
"doAutoLinks" => 30,
"encodeAmpsAndAngles" => 40,
"doItalicsAndBold" => 50,
"doHardBreaks" => 60,
"doNewLines" => 70,
);
function runSpanGamut($text) {
#
# Run span gamut tranformations.
#
foreach ($this->span_gamut as $method => $priority) {
$text = $this->$method($text);
}
return $text;
}
function doNewLines($text) {
return nl2br($text);
}